diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2009-09-14 10:38:21 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2009-09-14 10:38:21 +0000 |
| commit | 095abc2e238556b3b89f55a6c7885450e3e3385b (patch) | |
| tree | 6c2afff150a179e640d6579828a98108850a981a /src/plugins | |
| parent | a21018491ad5f53521b63dba062e2d7e87efc1c5 (diff) | |
| download | qmmp-095abc2e238556b3b89f55a6c7885450e3e3385b.tar.gz qmmp-095abc2e238556b3b89f55a6c7885450e3e3385b.tar.bz2 qmmp-095abc2e238556b3b89f55a6c7885450e3e3385b.zip | |
enabled cue support
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@1221 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/plugins')
| -rw-r--r-- | src/plugins/Input/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/plugins/Input/Input.pro | 2 | ||||
| -rw-r--r-- | src/plugins/Input/cue/decoder_cue.cpp | 278 | ||||
| -rw-r--r-- | src/plugins/Input/cue/decoder_cue.h | 46 | ||||
| -rw-r--r-- | src/plugins/Input/cue/decodercuefactory.cpp | 15 | ||||
| -rw-r--r-- | src/plugins/Input/cue/decodercuefactory.h | 7 | ||||
| -rw-r--r-- | src/plugins/Input/mad/decoder_mad.cpp | 7 |
7 files changed, 68 insertions, 289 deletions
diff --git a/src/plugins/Input/CMakeLists.txt b/src/plugins/Input/CMakeLists.txt index 3a98630c6..6ac96c92a 100644 --- a/src/plugins/Input/CMakeLists.txt +++ b/src/plugins/Input/CMakeLists.txt @@ -10,7 +10,7 @@ SET(USE_MAD TRUE CACHE BOOL "enable/disable mad plugin") #SET(USE_WAVPACK TRUE CACHE BOOL "enable/disable wavpack plugin") #SET(USE_MODPLUG TRUE CACHE BOOL "enable/disable modplug plugin") #SET(USE_AAC TRUE CACHE BOOL "enable/disable aac plugin") -#SET(USE_CUE TRUE CACHE BOOL "enable/disable cue plugin") +SET(USE_CUE TRUE CACHE BOOL "enable/disable cue plugin") #SET(USE_MPLAYER TRUE CACHE BOOL "enable/disable mplayer support") #SET(USE_CDA TRUE CACHE BOOL "enable/disable cd audio support") diff --git a/src/plugins/Input/Input.pro b/src/plugins/Input/Input.pro index 63f5dc4b3..22ae0f653 100644 --- a/src/plugins/Input/Input.pro +++ b/src/plugins/Input/Input.pro @@ -1,6 +1,6 @@ include(../../../qmmp.pri) -SUBDIRS += mad #cue +SUBDIRS += mad cue TEMPLATE = subdirs unix{ diff --git a/src/plugins/Input/cue/decoder_cue.cpp b/src/plugins/Input/cue/decoder_cue.cpp index a3942f100..8ee786105 100644 --- a/src/plugins/Input/cue/decoder_cue.cpp +++ b/src/plugins/Input/cue/decoder_cue.cpp @@ -32,27 +32,23 @@ #include "decoder_cue.h" -DecoderCUE::DecoderCUE(QObject *parent, DecoderFactory *d, const QString &url) - : Decoder(parent, d) +DecoderCUE::DecoderCUE(const QString &url, QIODevice *input) + : Decoder(input) { - path = url; + m_path = url; m_decoder = 0; - m_output2 = 0; - m_input2 = 0; - for (int i = 1; i < 10; ++i) - m_bands2[i] = 0; - m_preamp2 = 0; - m_useEQ2 = FALSE; } DecoderCUE::~DecoderCUE() -{} +{ + if(m_decoder) + delete m_decoder; + m_decoder = 0; +} bool DecoderCUE::initialize() { - m_input2 = 0; - - QString p = QUrl(path).path(); + QString p = QUrl(m_path).path(); p.replace(QString(QUrl::toPercentEncoding("#")), "#"); p.replace(QString(QUrl::toPercentEncoding("%")), "%"); CUEParser parser(p); @@ -61,71 +57,37 @@ bool DecoderCUE::initialize() qWarning("DecoderCUE: invalid cue file"); return FALSE; } - int track = path.section("#", -1).toInt(); - path = parser.filePath(track); - // find next track - if(track <= parser.count() - 1) - m_nextUrl = parser.info(track + 1)->path(); - //is it track of another file? - if(QUrl(m_nextUrl).path() != p) - m_nextUrl.clear(); - - if (!QFile::exists(path)) + int track = m_path.section("#", -1).toInt(); + m_path = parser.filePath(track); + if (!QFile::exists(m_path)) { - qWarning("DecoderCUE: file \"%s\" doesn't exist", qPrintable(path)); + qWarning("DecoderCUE: file \"%s\" doesn't exist", qPrintable(m_path)); return FALSE; } - DecoderFactory *df = Decoder::findByPath(path); + DecoderFactory *df = Decoder::findByPath(m_path); if (!df) { qWarning("DecoderCUE: unsupported file format"); return FALSE; } - if (!df->properties().noInput) - { - m_input2 = new QFile(path); - if (!m_input2->open(QIODevice::ReadOnly)) - { - qDebug("DecoderCUE: cannot open input"); - stop(); - return FALSE; - } - } - if (df->properties().noOutput) - { - qWarning("DecoderCUE: unsupported file format"); - return FALSE; - } - m_output2 = Output::create(this); - if (!m_output2) - { - qWarning("DecoderCUE: unable to create output"); - return FALSE; - } - if (!m_output2->initialize()) + m_length = parser.length(track); + m_offset = parser.offset(track); + + m_decoder = df->create(new QFile(m_path), m_path); + if(!m_decoder->initialize()) { - qWarning("SoundCore: unable to initialize output"); - delete m_output2; - m_output2 = 0; + qWarning("DecoderCUE: invalid audio file"); return FALSE; } + m_decoder->seek(m_offset); - m_length = parser.length(track); - m_offset = parser.offset(track); - m_decoder = df->create(this, m_input2, m_output2, path); - m_decoder->setEQ(m_bands2, m_preamp2); - m_decoder->setEQEnabled(m_useEQ2); - connect(m_decoder, SIGNAL(playbackFinished()), SLOT(finish())); - //replace default state handler to ignore metadata - m_decoder->setStateHandler(new CUEStateHandler(m_decoder)); - m_output2->setStateHandler(m_decoder->stateHandler()); - connect(stateHandler(), SIGNAL(aboutToFinish()), SLOT(proccessFinish())); - //prepare decoder and ouput objects - m_decoder->initialize(); - m_decoder->setFragment(m_offset, m_length); - //send metadata - QMap<Qmmp::MetaData, QString> metaData = parser.info(track)->metaData(); - stateHandler()->dispatch(metaData); + configure(m_decoder->audioParameters().sampleRate(), + m_decoder->audioParameters().channels(), + m_decoder->audioParameters().bits()); + offset_in_bytes = audioParameters().sampleRate() * + audioParameters().channels() * + audioParameters().bits() * m_length/8000; + m_totalBytes = 0; return TRUE; } @@ -136,180 +98,28 @@ qint64 DecoderCUE::totalTime() void DecoderCUE::seek(qint64 pos) { - if (m_output2 && m_output2->isRunning()) - { - m_output2->mutex()->lock (); - m_output2->seek(pos); - m_output2->mutex()->unlock(); - if (m_decoder && m_decoder->isRunning()) - { - m_decoder->mutex()->lock (); - m_decoder->seek(pos); - m_decoder->mutex()->unlock(); - } - } -} - -void DecoderCUE::stop() -{ - if (m_decoder /*&& m_decoder->isRunning()*/) - { - m_decoder->mutex()->lock (); - m_decoder->stop(); - m_decoder->mutex()->unlock(); - //m_decoder->stateHandler()->dispatch(Qmmp::Stopped); - } - if (m_output2) - { - m_output2->mutex()->lock (); - m_output2->stop(); - m_output2->mutex()->unlock(); - } - - // wake up threads - if (m_decoder) - { - m_decoder->mutex()->lock (); - m_decoder->cond()->wakeAll(); - m_decoder->mutex()->unlock(); - } - if (m_output2) - { - m_output2->recycler()->mutex()->lock (); - m_output2->recycler()->cond()->wakeAll(); - m_output2->recycler()->mutex()->unlock(); - } - if (m_decoder) - m_decoder->wait(); - if (m_output2) - m_output2->wait(); - - if (m_input2) - { - m_input2->deleteLater(); - m_input2 = 0; - } + m_decoder->seek(m_offset + pos); + m_totalBytes = audioParameters().sampleRate() * + audioParameters().channels() * + audioParameters().bits() * pos/8000; } -void DecoderCUE::pause() +qint64 DecoderCUE::read(char *data, qint64 size) { - if (m_output2) + qint64 len = m_decoder->read(data, size); + m_totalBytes += len; + if(len > offset_in_bytes - m_totalBytes) { - m_output2->mutex()->lock (); - m_output2->pause(); - m_output2->mutex()->unlock(); + len = offset_in_bytes - m_totalBytes; + int sample_size = audioParameters().bits() * audioParameters().channels()/8; + len = (len / sample_size) * sample_size; } - else if (m_decoder) - { - m_decoder->mutex()->lock (); - m_decoder->pause(); - m_decoder->mutex()->unlock(); - } - - // wake up threads - if (m_decoder) - { - m_decoder->mutex()->lock (); - m_decoder->cond()->wakeAll(); - m_decoder->mutex()->unlock(); - } - - if (m_output2) - { - m_output2->recycler()->mutex()->lock (); - m_output2->recycler()->cond()->wakeAll(); - m_output2->recycler()->mutex()->unlock(); - } -} - -void DecoderCUE::setEQ(double bands[10], double preamp) -{ - for (int i = 0; i < 10; ++i) - m_bands2[i] = bands[i]; - m_preamp2 = preamp; - if (m_decoder) - { - m_decoder->mutex()->lock (); - m_decoder->setEQ(m_bands2, m_preamp2); - m_decoder->setEQEnabled(m_useEQ2); - m_decoder->mutex()->unlock(); - } -} - -void DecoderCUE::setEQEnabled(bool on) -{ - m_useEQ2 = on; - if (m_decoder) - { - m_decoder->mutex()->lock (); - m_decoder->setEQ(m_bands2, m_preamp2); - m_decoder->setEQEnabled(on); - m_decoder->mutex()->unlock(); - } -} - -void DecoderCUE::run() -{ - m_decoder->start(); - if (m_output2) - m_output2->start(); -} - -void DecoderCUE::proccessFinish() -{ - if(nextUrlRequest(m_nextUrl)) - { - qDebug("DecoderCUE: going to next track"); - int track = m_nextUrl.section("#", -1).toInt(); - QString p = QUrl(m_nextUrl).path(); - p.replace(QString(QUrl::toPercentEncoding("#")), "#"); - p.replace(QString(QUrl::toPercentEncoding("%")), "%"); - //update current fragment - CUEParser parser(p); - m_length = parser.length(track); - m_offset = parser.offset(track); - m_decoder->mutex()->lock(); - m_decoder->setFragment(m_offset, m_length); - m_output2->seek(0); //reset time counter - m_decoder->mutex()->unlock(); - // find next track - if(track <= parser.count() - 1) - m_nextUrl = parser.info(track + 1)->path(); - else - m_nextUrl.clear(); - //is it track of another file? - if(QUrl(m_nextUrl).path() != p) - m_nextUrl.clear(); - //change track - finish(); - //send metadata - QMap<Qmmp::MetaData, QString> metaData = parser.info(track)->metaData(); - stateHandler()->dispatch(metaData); - } -} - -CUEStateHandler::CUEStateHandler(QObject *parent): StateHandler(parent){} - -CUEStateHandler::~CUEStateHandler(){} - -void CUEStateHandler::dispatch(qint64 elapsed, - int bitrate, - quint32 frequency, - int precision, - int channels) -{ - StateHandler::instance()->dispatch(elapsed, bitrate, - frequency, precision, channels); - -} - -void CUEStateHandler::dispatch(const QMap<Qmmp::MetaData, QString> &metaData) -{ - //ignore media file metadata - Q_UNUSED(metaData) + if(len < 0) + len = 0; + return len; } -void CUEStateHandler::dispatch(const Qmmp::State &state) +int DecoderCUE::bitrate() { - StateHandler::instance()->dispatch(state); + return m_decoder->bitrate(); } diff --git a/src/plugins/Input/cue/decoder_cue.h b/src/plugins/Input/cue/decoder_cue.h index a02f82506..1f641574f 100644 --- a/src/plugins/Input/cue/decoder_cue.h +++ b/src/plugins/Input/cue/decoder_cue.h @@ -26,59 +26,27 @@ class Output; class QIDevice; -//class CUEStateHandler; class DecoderCUE : public Decoder { - Q_OBJECT public: - DecoderCUE(QObject *, DecoderFactory *, const QString &url); + DecoderCUE(const QString &url, QIODevice *input); virtual ~DecoderCUE(); // Standard Decoder API bool initialize(); qint64 totalTime(); void seek(qint64); - void stop(); - void pause(); + qint64 read(char *data, qint64 size); + int bitrate(); - // Equalizer - void setEQ(double bands[10], double preamp); - void setEQEnabled(bool on); - -private slots: - void proccessFinish(); - -private: - // thread run function - void run(); - QString path, m_nextUrl; +private: Decoder *m_decoder; - Output *m_output2; - QIODevice *m_input2; qint64 m_length; qint64 m_offset; - double m_preamp2; - double m_bands2[10]; - bool m_useEQ2; -}; - -class CUEStateHandler : public StateHandler -{ - Q_OBJECT -public: - CUEStateHandler(QObject *parent); - virtual ~CUEStateHandler(); - - void dispatch(qint64 elapsed, - int bitrate, - quint32 frequency, - int precision, - int channels); - - void dispatch(const QMap<Qmmp::MetaData, QString> &metaData); - - void dispatch(const Qmmp::State &state); + qint64 offset_in_bytes; + qint64 m_totalBytes; + QString m_path; }; #endif // DECODER_CUE_H diff --git a/src/plugins/Input/cue/decodercuefactory.cpp b/src/plugins/Input/cue/decodercuefactory.cpp index ac057db9b..a25e930f7 100644 --- a/src/plugins/Input/cue/decodercuefactory.cpp +++ b/src/plugins/Input/cue/decodercuefactory.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008 by Ilya Kotov * + * Copyright (C) 2008-2009 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -53,12 +53,11 @@ const DecoderProperties DecoderCUEFactory::properties() const return properties; } -Decoder *DecoderCUEFactory::create(QObject *parent, QIODevice *input, - Output *output, const QString &url) +Decoder *DecoderCUEFactory::create(QIODevice *input, const QString &path) { - Q_UNUSED(input); - Q_UNUSED(output); - return new DecoderCUE(parent, this, url); + //Q_UNUSED(input); + //Q_UNUSED(output); + return new DecoderCUE(path, input); } QList<FileInfo *> DecoderCUEFactory::createPlayList(const QString &fileName, bool useMetaData) @@ -68,8 +67,10 @@ QList<FileInfo *> DecoderCUEFactory::createPlayList(const QString &fileName, boo return parser.createPlayList(); } -QObject* DecoderCUEFactory::showDetails(QWidget *, const QString &) +MetaDataModel* DecoderCUEFactory::createMetaDataModel(const QString &path, QObject *parent) { + Q_UNUSED(path); + Q_UNUSED(parent); return 0; } diff --git a/src/plugins/Input/cue/decodercuefactory.h b/src/plugins/Input/cue/decodercuefactory.h index a79cb0429..d24108369 100644 --- a/src/plugins/Input/cue/decodercuefactory.h +++ b/src/plugins/Input/cue/decodercuefactory.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2006-2008 by Ilya Kotov * + * Copyright (C) 2008-2009 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -29,6 +29,7 @@ #include <qmmp/output.h> #include <qmmp/decoderfactory.h> #include <qmmp/fileinfo.h> +#include <qmmp/metadatamodel.h> class DecoderCUEFactory : public QObject, DecoderFactory { @@ -39,9 +40,9 @@ public: bool supports(const QString &source) const; bool canDecode(QIODevice *input) const; const DecoderProperties properties() const; - Decoder *create(QObject *, QIODevice *, Output *, const QString &); + Decoder *create(QIODevice *, const QString &); QList<FileInfo *> createPlayList(const QString &fileName, bool useMetaData); - QObject* showDetails(QWidget *parent, const QString &path); + MetaDataModel* createMetaDataModel(const QString &path, QObject *parent = 0); void showSettings(QWidget *parent); void showAbout(QWidget *parent); QTranslator *createTranslator(QObject *parent); diff --git a/src/plugins/Input/mad/decoder_mad.cpp b/src/plugins/Input/mad/decoder_mad.cpp index 58d21bebd..3707abcbc 100644 --- a/src/plugins/Input/mad/decoder_mad.cpp +++ b/src/plugins/Input/mad/decoder_mad.cpp @@ -25,7 +25,7 @@ DecoderMAD::DecoderMAD(QIODevice *i) : Decoder(i) { m_inited = false; - m_totalTime = 0.; + m_totalTime = 0; m_channels = 0; m_bitrate = 0; m_freq = 0; @@ -40,7 +40,6 @@ DecoderMAD::DecoderMAD(QIODevice *i) DecoderMAD::~DecoderMAD() { - wait(); deinit(); if (m_input_buf) { @@ -53,7 +52,7 @@ DecoderMAD::~DecoderMAD() bool DecoderMAD::initialize() { m_inited = false; - m_totalTime = 0.; + m_totalTime = 0; m_channels = 0; m_bitrate = 0; m_freq = 0; @@ -118,7 +117,7 @@ void DecoderMAD::deinit() mad_stream_finish(&stream); m_inited = FALSE; - m_totalTime = 0.; + m_totalTime = 0; m_channels = 0; m_bitrate = 0; m_freq = 0; |
