aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/Input/CMakeLists.txt2
-rw-r--r--src/plugins/Input/Input.pro2
-rw-r--r--src/plugins/Input/cue/cueparser.cpp2
-rw-r--r--src/plugins/Input/cue/decoder_cue.cpp75
-rw-r--r--src/plugins/Input/cue/decoder_cue.h9
-rw-r--r--src/qmmp/decoder.cpp69
-rw-r--r--src/qmmp/decoder.h22
7 files changed, 101 insertions, 80 deletions
diff --git a/src/plugins/Input/CMakeLists.txt b/src/plugins/Input/CMakeLists.txt
index 06b8ff774..dbc902087 100644
--- a/src/plugins/Input/CMakeLists.txt
+++ b/src/plugins/Input/CMakeLists.txt
@@ -53,7 +53,7 @@ IF(USE_AAC)
ENDIF(USE_AAC)
IF(USE_CUE)
-#add_subdirectory(cue)
+add_subdirectory(cue)
ENDIF(USE_CUE)
IF(USE_MPLAYER)
diff --git a/src/plugins/Input/Input.pro b/src/plugins/Input/Input.pro
index 037e78bc2..4678d29dd 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/cueparser.cpp b/src/plugins/Input/cue/cueparser.cpp
index 7d767cf97..3b4053867 100644
--- a/src/plugins/Input/cue/cueparser.cpp
+++ b/src/plugins/Input/cue/cueparser.cpp
@@ -84,7 +84,7 @@ CUEParser::CUEParser(const QString &fileName)
}
else if (words[0] == "INDEX")
{
- if (m_infoList.isEmpty())
+ if (m_infoList.isEmpty() || words[1] != "01")
continue;
m_infoList.last ().setLength(getLength(words[2]));
m_offsets.last() = getLength(words[2]);
diff --git a/src/plugins/Input/cue/decoder_cue.cpp b/src/plugins/Input/cue/decoder_cue.cpp
index 257d6c491..ff2761549 100644
--- a/src/plugins/Input/cue/decoder_cue.cpp
+++ b/src/plugins/Input/cue/decoder_cue.cpp
@@ -18,7 +18,6 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-#include <qmmp/constants.h>
#include <qmmp/buffer.h>
#include <qmmp/output.h>
#include <qmmp/recycler.h>
@@ -82,47 +81,43 @@ bool DecoderCUE::initialize()
{
qDebug("DecoderCUE: cannot open input");
stop();
- //m_handler->dispatch(Qmmp::NormalError);
return FALSE;
}
}
- if (!df->properties().noOutput)
+ if (df->properties().noOutput)
{
- m_output2 = Output::create(this);
- if (!m_output2)
- {
- qWarning("DecoderCUE: unable to create output");
- //m_handler->dispatch(Qmmp::FatalError);
- return FALSE;
- }
- if (!m_output2->initialize())
- {
- qWarning("SoundCore: unable to initialize output");
- delete m_output2;
- m_output2 = 0;
- //m_handler->dispatch(Qmmp::FatalError);
- return FALSE;
- }
+ 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())
+ {
+ qWarning("SoundCore: unable to initialize output");
+ delete m_output2;
+ m_output2 = 0;
+ return FALSE;
}
+
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);
- CUEStateHandler *csh = new CUEStateHandler(this, m_offset, m_length);
- m_decoder->setStateHandler(csh);
- connect(csh, SIGNAL(finished()), SLOT(finish()));
connect(m_decoder, SIGNAL(playbackFinished()), SLOT(finish()));
- if (m_output2)
- m_output2->setStateHandler(m_decoder->stateHandler());
+ //replace default state handler to ignore metadata
+ m_decoder->setStateHandler(new CUEStateHandler(m_decoder));
+ m_output2->setStateHandler(m_decoder->stateHandler());
+ //prepare decoder and ouput objects
m_decoder->initialize();
- m_decoder->seek(parser.offset(track));
- if (m_output2)
- m_output2->seek(parser.offset(track));
-
+ m_decoder->setFragment(m_offset, m_length);
//send metadata
QMap<Qmmp::MetaData, QString> metaData = parser.info(track)->metaData();
- StateHandler::instance()->dispatch(metaData);
+ stateHandler()->dispatch(metaData);
return TRUE;
}
@@ -136,21 +131,15 @@ void DecoderCUE::seek(qint64 pos)
if (m_output2 && m_output2->isRunning())
{
m_output2->mutex()->lock ();
- m_output2->seek(m_offset + pos);
+ m_output2->seek(pos);
m_output2->mutex()->unlock();
if (m_decoder && m_decoder->isRunning())
{
m_decoder->mutex()->lock ();
- m_decoder->seek(m_offset + pos);
+ m_decoder->seek(pos);
m_decoder->mutex()->unlock();
}
}
- else if (m_decoder)
- {
- m_decoder->mutex()->lock ();
- m_decoder->seek(m_offset + pos);
- m_decoder->mutex()->unlock();
- }
}
void DecoderCUE::stop()
@@ -259,13 +248,9 @@ void DecoderCUE::run()
}
-CUEStateHandler::CUEStateHandler(QObject *parent, qint64 offset, qint64 length): StateHandler(parent)
-{
- m_offset = offset;
- m_length2 = length;
-}
+CUEStateHandler::CUEStateHandler(QObject *parent): StateHandler(parent){}
-CUEStateHandler::~CUEStateHandler(){};
+CUEStateHandler::~CUEStateHandler(){}
void CUEStateHandler::dispatch(qint64 elapsed,
qint64 totalTime,
@@ -274,11 +259,9 @@ void CUEStateHandler::dispatch(qint64 elapsed,
int precision,
int channels)
{
- Q_UNUSED(totalTime);
- StateHandler::instance()->dispatch(elapsed - m_offset, m_length2, bitrate,
+ StateHandler::instance()->dispatch(elapsed, totalTime, bitrate,
frequency, precision, channels);
- if (elapsed - m_offset > m_length2)
- emit finished();
+
}
void CUEStateHandler::dispatch(const QMap<Qmmp::MetaData, QString> &metaData)
diff --git a/src/plugins/Input/cue/decoder_cue.h b/src/plugins/Input/cue/decoder_cue.h
index 39d41c208..da97735df 100644
--- a/src/plugins/Input/cue/decoder_cue.h
+++ b/src/plugins/Input/cue/decoder_cue.h
@@ -64,7 +64,7 @@ class CUEStateHandler : public StateHandler
{
Q_OBJECT
public:
- CUEStateHandler(QObject *parent, qint64 offset, qint64 length);
+ CUEStateHandler(QObject *parent);
virtual ~CUEStateHandler();
void dispatch(qint64 elapsed,
@@ -77,13 +77,6 @@ public:
void dispatch(const QMap<Qmmp::MetaData, QString> &metaData);
void dispatch(const Qmmp::State &state);
-
-signals:
- void finished();
-
-private:
- qint64 m_length2;
- qint64 m_offset;
};
#endif // DECODER_CUE_H
diff --git a/src/qmmp/decoder.cpp b/src/qmmp/decoder.cpp
index 1c4bdf087..d0542b28b 100644
--- a/src/qmmp/decoder.cpp
+++ b/src/qmmp/decoder.cpp
@@ -52,13 +52,18 @@ Decoder::~Decoder()
_m_finish = FALSE;
_m_totalTime = 0;
_m_seekTime = -1;
- _m_output_bytes = 0;
_m_output_at = 0;
_m_user_stop = FALSE;
_m_bks = Buffer::size();
_m_output_buf = 0;
_m_bitrate = 0;
_m_chan = 0;
+ _m_freq = 0;
+ _m_bps = 0;
+ _m_offset_in_bytes = 0;
+ _m_length_in_bytes = 0;
+ _m_totalBytes = 0;
+ _m_offset = 0;
if(_m_output_buf)
delete [] _m_output_buf;
_m_output_buf = 0;
@@ -78,13 +83,18 @@ void Decoder::init()
_m_finish = FALSE;
_m_totalTime = 0;
_m_seekTime = -1;
- _m_output_bytes = 0;
_m_output_at = 0;
_m_user_stop = FALSE;
_m_bks = Buffer::size();
_m_output_buf = 0;
_m_bitrate = 0;
_m_chan = 0;
+ _m_freq = 0;
+ _m_bps = 0;
+ _m_offset_in_bytes = 0;
+ _m_length_in_bytes = 0;
+ _m_offset = 0;
+ _m_totalBytes = 0;
}
DecoderFactory *Decoder::factory() const
@@ -142,6 +152,9 @@ void Decoder::setEQEnabled(bool on)
void Decoder::configure(quint32 srate, int chan, int bps)
{
Effect* effect = 0;
+ _m_freq = srate;
+ _m_chan = chan;
+ _m_bps = bps;
foreach(effect, _m_effects)
{
effect->configure(srate, chan, bps);
@@ -163,6 +176,20 @@ void Decoder::seek(qint64 time)
_m_seekTime = time;
}
+int Decoder::bitrate()
+{
+ return 0;
+}
+
+void Decoder::pause(){}
+
+void Decoder::setFragment(qint64 offset, qint64 length)
+{
+ _m_offset_in_bytes = offset * _m_freq * _m_bps * _m_chan / 8000;
+ _m_length_in_bytes = length * _m_freq * _m_bps * _m_chan / 8000;
+ _m_offset = offset;
+}
+
void Decoder::stop()
{
_m_user_stop = TRUE;
@@ -232,18 +259,22 @@ void Decoder::finish()
emit playbackFinished();
}
+qint64 Decoder::readAudio(char*, qint64)
+{
+ return 0;
+}
+
+void Decoder::seekAudio(qint64){}
+
void Decoder::run()
{
Q_ASSERT(_m_chan == 0);
+ Q_ASSERT(!_m_output_buf);
mutex()->lock ();
qint64 len = 0;
-
- /*if (!inited)
- {
- mutex()->unlock();
- return;
- }*/
+ if(_m_offset > 0)
+ seekAudio(_m_offset);
mutex()->unlock();
@@ -254,15 +285,24 @@ void Decoder::run()
if (_m_seekTime >= 0)
{
- seekAudio(_m_seekTime);
+ seekAudio(_m_seekTime + _m_offset);
+ _m_totalBytes = _m_seekTime * _m_freq * _m_bps * _m_chan / 8000;
_m_seekTime = -1;
- }
+ }
+
len = readAudio((char *)(_m_output_buf + _m_output_at), Qmmp::globalBufferSize() - _m_output_at);
+
+ if(_m_length_in_bytes && len > 0)
+ {
+ len = qMin(_m_length_in_bytes - _m_totalBytes, len);
+ len = qMax((qint64)0, len);
+ }
+
if (len > 0)
{
_m_bitrate = bitrate();
_m_output_at += len;
- _m_output_bytes += len;
+ _m_totalBytes += len;
if (output())
flush();
}
@@ -293,10 +333,8 @@ void Decoder::run()
}
mutex()->lock ();
-
if (_m_finish)
finish();
-
mutex()->unlock();
}
@@ -304,7 +342,7 @@ void Decoder::flush(bool final)
{
ulong min = final ? 0 : _m_bks;
- while ((!_m_done && !_m_finish) && _m_output_bytes > min)
+ while ((!_m_done && !_m_finish) && _m_output_at > min)
{
output()->recycler()->mutex()->lock ();
while ((!_m_done && !_m_finish) && output()->recycler()->full())
@@ -319,8 +357,7 @@ void Decoder::flush(bool final)
_m_done = TRUE;
else
{
- _m_output_bytes -= produceSound((char*)_m_output_buf, _m_output_bytes, _m_bitrate, _m_chan);
- _m_output_at = _m_output_bytes;
+ _m_output_at -= produceSound((char*)_m_output_buf, _m_output_at, _m_bitrate, _m_chan);
}
if (output()->recycler()->full())
diff --git a/src/qmmp/decoder.h b/src/qmmp/decoder.h
index a6fe04550..f1d829bf8 100644
--- a/src/qmmp/decoder.h
+++ b/src/qmmp/decoder.h
@@ -75,12 +75,18 @@ public:
* Subclass should reimplement this function.
*/
virtual void stop();
+
+ virtual int bitrate();
+
/*!
* Requests playback to pause. If it was paused already, playback should resume.
* Subclass with own output should reimplement this function.
*/
- virtual int bitrate() = 0;
- virtual void pause(){}
+ virtual void pause();
+
+
+ void setFragment(qint64 offset, qint64 length);
+
/*!
* Returns decoder's factory object.
*/
@@ -183,6 +189,9 @@ signals:
void playbackFinished();
protected:
+ virtual qint64 readAudio(char *data, qint64 maxSize);
+
+ virtual void seekAudio(qint64 time);
virtual void run();
/*!
@@ -201,9 +210,7 @@ protected:
*/
qint64 produceSound(char *data, qint64 size, quint32 brate, int chan);
- virtual qint64 readAudio(char *data, qint64 maxSize) = 0;
- virtual void seekAudio(qint64 time) = 0;
protected slots:
/*!
@@ -230,9 +237,10 @@ private:
bool _m_done, _m_finish, _m_user_stop;
ulong _m_bks;
- qint64 _m_totalTime, _m_seekTime;
- ulong _m_output_bytes, _m_output_at;
- int _m_bitrate, _m_chan;
+ qint64 _m_totalTime, _m_seekTime, _m_totalBytes;
+ qint64 _m_offset_in_bytes, _m_length_in_bytes, _m_freq, _m_offset;
+ qint64 _m_output_at;
+ int _m_bitrate, _m_chan, _m_bps;
StateHandler *_m_handler;
unsigned char *_m_output_buf;