aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/Input/CMakeLists.txt2
-rw-r--r--src/plugins/Input/Input.pro2
-rw-r--r--src/plugins/Input/cue/decoder_cue.cpp278
-rw-r--r--src/plugins/Input/cue/decoder_cue.h46
-rw-r--r--src/plugins/Input/cue/decodercuefactory.cpp15
-rw-r--r--src/plugins/Input/cue/decodercuefactory.h7
-rw-r--r--src/plugins/Input/mad/decoder_mad.cpp7
-rw-r--r--src/qmmp/qmmpaudioengine.cpp7
-rw-r--r--src/qmmp/soundcore.cpp1
9 files changed, 75 insertions, 290 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;
diff --git a/src/qmmp/qmmpaudioengine.cpp b/src/qmmp/qmmpaudioengine.cpp
index f3f35b80c..ae2efff89 100644
--- a/src/qmmp/qmmpaudioengine.cpp
+++ b/src/qmmp/qmmpaudioengine.cpp
@@ -79,9 +79,12 @@ bool QmmpAudioEngine::initialize(const QString &source, QIODevice *input)
if(m_decoder && isRunning() && m_output && m_output->isRunning())
{
m_factory = Decoder::findByPath(source);
+ if(!m_factory)
+ m_factory = Decoder::findByURL(QUrl(source));
m_decoder2 = m_factory->create(input, source);
if(!m_decoder2->initialize())
return FALSE;
+
if(m_decoder2->audioParameters() == m_decoder->audioParameters())
{
qDebug("accepted!!");
@@ -113,6 +116,8 @@ bool QmmpAudioEngine::initialize(const QString &source, QIODevice *input)
}
m_factory = Decoder::findByPath(source);
+ if(!m_factory)
+ m_factory = Decoder::findByURL(QUrl(source));
m_decoder = m_factory->create(input, source);
if (!m_decoder)
{
@@ -267,6 +272,7 @@ void QmmpAudioEngine::stop()
if(m_decoder)
{
+ qDebug("delete m_decoder");
delete m_decoder;
m_decoder = 0;
}
@@ -376,7 +382,6 @@ void QmmpAudioEngine::run()
}
else if (len == 0)
{
- qDebug("0");
if(m_decoder2)
{
qDebug("next decoder");
diff --git a/src/qmmp/soundcore.cpp b/src/qmmp/soundcore.cpp
index 6d5135c1c..83d268a88 100644
--- a/src/qmmp/soundcore.cpp
+++ b/src/qmmp/soundcore.cpp
@@ -96,6 +96,7 @@ bool SoundCore::play(const QString &source, bool queue)
}
m_factory = Decoder::findByURL(url);
+ m_input = 0;
if (m_factory)
return decode();