diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2009-09-20 14:26:40 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2009-09-20 14:26:40 +0000 |
| commit | 5b5f8803d3d95d65699dad5b1e02015683e39c08 (patch) | |
| tree | ec60e6b2038acee028b71a2a0b423cea936364d2 | |
| parent | b6ba1017f793b83e099c863fa7c42745361ffef9 (diff) | |
| download | qmmp-5b5f8803d3d95d65699dad5b1e02015683e39c08.tar.gz qmmp-5b5f8803d3d95d65699dad5b1e02015683e39c08.tar.bz2 qmmp-5b5f8803d3d95d65699dad5b1e02015683e39c08.zip | |
removed noise between cue tracks
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@1237 90c681e8-e032-0410-971d-27865f9a5e38
| -rw-r--r-- | src/plugins/Input/cue/cueparser.cpp | 5 | ||||
| -rw-r--r-- | src/plugins/Input/cue/cueparser.h | 4 | ||||
| -rw-r--r-- | src/plugins/Input/cue/decoder_cue.cpp | 97 | ||||
| -rw-r--r-- | src/plugins/Input/cue/decoder_cue.h | 11 | ||||
| -rw-r--r-- | src/qmmp/decoder.cpp | 8 | ||||
| -rw-r--r-- | src/qmmp/decoder.h | 3 | ||||
| -rw-r--r-- | src/qmmp/qmmpaudioengine.cpp | 29 | ||||
| -rw-r--r-- | src/qmmp/qmmpaudioengine.h | 1 | ||||
| -rw-r--r-- | src/qmmp/soundcore.cpp | 3 |
9 files changed, 138 insertions, 23 deletions
diff --git a/src/plugins/Input/cue/cueparser.cpp b/src/plugins/Input/cue/cueparser.cpp index f093d955c..1b4af9ef8 100644 --- a/src/plugins/Input/cue/cueparser.cpp +++ b/src/plugins/Input/cue/cueparser.cpp @@ -182,6 +182,11 @@ FileInfo *CUEParser::info(int track) return &m_infoList[track - 1]; } +const QString CUEParser::trackURL(int track) +{ + return m_infoList[track - 1].path(); +} + QStringList CUEParser::splitLine(const QString &line) { //qDebug("row string = %s",qPrintable(line)); diff --git a/src/plugins/Input/cue/cueparser.h b/src/plugins/Input/cue/cueparser.h index 84be19115..3dc4f60e9 100644 --- a/src/plugins/Input/cue/cueparser.h +++ b/src/plugins/Input/cue/cueparser.h @@ -32,7 +32,8 @@ /** @author Ilya Kotov <forkotov02@hotmail.ru> */ -class CUEParser{ +class CUEParser +{ public: CUEParser(const QString &fileName); @@ -44,6 +45,7 @@ public: qint64 length(int track); int count(); FileInfo *info(int track); + const QString trackURL(int track); private: QString m_filePath; diff --git a/src/plugins/Input/cue/decoder_cue.cpp b/src/plugins/Input/cue/decoder_cue.cpp index cf06438e9..ec2349bac 100644 --- a/src/plugins/Input/cue/decoder_cue.cpp +++ b/src/plugins/Input/cue/decoder_cue.cpp @@ -37,6 +37,9 @@ DecoderCUE::DecoderCUE(const QString &url) { m_path = url; m_decoder = 0; + m_parser = 0; + m_track = 0; + m_buf = 0; } DecoderCUE::~DecoderCUE() @@ -44,6 +47,12 @@ DecoderCUE::~DecoderCUE() if(m_decoder) delete m_decoder; m_decoder = 0; + if(m_parser) + delete m_parser; + m_parser = 0; + if(m_buf) + delete [] m_buf; + m_buf = 0; } bool DecoderCUE::initialize() @@ -51,14 +60,14 @@ bool DecoderCUE::initialize() QString p = QUrl(m_path).path(); p.replace(QString(QUrl::toPercentEncoding("#")), "#"); p.replace(QString(QUrl::toPercentEncoding("%")), "%"); - CUEParser parser(p); - if (parser.count() == 0) + m_parser = new CUEParser(p); + if (m_parser->count() == 0) { qWarning("DecoderCUE: invalid cue file"); return FALSE; } - int track = m_path.section("#", -1).toInt(); - m_path = parser.filePath(track); + m_track = m_path.section("#", -1).toInt(); + m_path = m_parser->filePath(m_track); if (!QFile::exists(m_path)) { qWarning("DecoderCUE: file \"%s\" doesn't exist", qPrintable(m_path)); @@ -70,8 +79,8 @@ bool DecoderCUE::initialize() qWarning("DecoderCUE: unsupported file format"); return FALSE; } - m_length = parser.length(track); - m_offset = parser.offset(track); + m_length = m_parser->length(m_track); + m_offset = m_parser->offset(m_track); m_decoder = df->create(m_path, new QFile(m_path)); if(!m_decoder->initialize()) @@ -84,12 +93,14 @@ bool DecoderCUE::initialize() configure(m_decoder->audioParameters().sampleRate(), m_decoder->audioParameters().channels(), m_decoder->audioParameters().bits()); - offset_in_bytes = audioParameters().sampleRate() * + length_in_bytes = audioParameters().sampleRate() * audioParameters().channels() * audioParameters().bits() * m_length/8000; m_totalBytes = 0; - StateHandler::instance()->dispatch(parser.info(track)->metaData()); + m_sz = audioParameters().bits() * audioParameters().channels()/8; + + StateHandler::instance()->dispatch(m_parser->info(m_track)->metaData()); return TRUE; } @@ -108,20 +119,72 @@ void DecoderCUE::seek(qint64 pos) qint64 DecoderCUE::read(char *data, qint64 size) { - qint64 len = m_decoder->read(data, size); - m_totalBytes += len; - if(len > offset_in_bytes - m_totalBytes) + if(length_in_bytes - m_totalBytes < m_sz) //end of cue track + return 0; + + qint64 len = 0; + + if(m_buf) //read remaining data first + { + len = qMin(m_buf_size, size); + memmove(data, m_buf, len); + if(size >= m_buf_size) + { + delete[] m_buf; + m_buf = 0; + m_buf_size = 0; + } + else + memmove(m_buf, m_buf + len, size - len); + } + else + len = m_decoder->read(data, size); + + if(len <= 0) //end of file + return 0; + + if(len + m_totalBytes <= length_in_bytes) { - len = offset_in_bytes - m_totalBytes; - int sample_size = audioParameters().bits() * audioParameters().channels()/8; - len = (len / sample_size) * sample_size; + m_totalBytes += len; + return len; } - if(len < 0) - len = 0; - return len; + + qint64 len2 = qMax(qint64(0), length_in_bytes - m_totalBytes); + len2 = (len2 / m_sz) * m_sz; //returned size must contain integer number of samples + m_totalBytes += len2; + //save data of the next track + if(m_buf) + delete[] m_buf; + m_buf_size = len - len2; + m_buf = new char[m_buf_size]; + memmove(m_buf, data + len2, m_buf_size); + return len2; } int DecoderCUE::bitrate() { return m_decoder->bitrate(); } + +const QString DecoderCUE::nextURL() +{ + if(m_track +1 <= m_parser->count()) + return m_parser->trackURL(m_track + 1); + else + return QString(); +} + +void DecoderCUE::next() +{ + if(m_track +1 <= m_parser->count()) + { + m_track++; + m_length = m_parser->length(m_track); + m_offset = m_parser->offset(m_track); + length_in_bytes = audioParameters().sampleRate() * + audioParameters().channels() * + audioParameters().bits() * m_length/8000; + StateHandler::instance()->dispatch(m_parser->info(m_track)->metaData()); + m_totalBytes = 0; + } +} diff --git a/src/plugins/Input/cue/decoder_cue.h b/src/plugins/Input/cue/decoder_cue.h index ce3bcb4b5..6ff6e85a1 100644 --- a/src/plugins/Input/cue/decoder_cue.h +++ b/src/plugins/Input/cue/decoder_cue.h @@ -26,6 +26,7 @@ class Output; class QIDevice; +class CUEParser; class DecoderCUE : public Decoder { @@ -39,14 +40,22 @@ public: void seek(qint64); qint64 read(char *data, qint64 size); int bitrate(); + const QString nextURL(); + void next(); private: Decoder *m_decoder; qint64 m_length; qint64 m_offset; - qint64 offset_in_bytes; + qint64 length_in_bytes; qint64 m_totalBytes; QString m_path; + QString m_nextURL; + CUEParser *m_parser; + int m_track; + char *m_buf; //buffer for remainig data + qint64 m_buf_size; + qint64 m_sz; //sample size }; #endif // DECODER_CUE_H diff --git a/src/qmmp/decoder.cpp b/src/qmmp/decoder.cpp index 90013eeb5..40c35ee6d 100644 --- a/src/qmmp/decoder.cpp +++ b/src/qmmp/decoder.cpp @@ -37,6 +37,14 @@ void Decoder::configure(quint32 srate, int chan, int bps) m_parameters = AudioParameters(srate, chan, bps); } +void Decoder::next() +{} + +const QString Decoder::nextURL() +{ + return QString(); +} + const AudioParameters Decoder::audioParameters() { return m_parameters; diff --git a/src/qmmp/decoder.h b/src/qmmp/decoder.h index 91d7507a0..4d16faa6a 100644 --- a/src/qmmp/decoder.h +++ b/src/qmmp/decoder.h @@ -60,9 +60,12 @@ public: * Subclass should reimplement this function. */ virtual int bitrate() = 0; + virtual void next(); + virtual const QString nextURL(); const AudioParameters audioParameters(); QIODevice *input(); + /*! * Returns \b true if \b file is supported by input plugins, otherwise returns \b false */ diff --git a/src/qmmp/qmmpaudioengine.cpp b/src/qmmp/qmmpaudioengine.cpp index 893ad1239..7630d480f 100644 --- a/src/qmmp/qmmpaudioengine.cpp +++ b/src/qmmp/qmmpaudioengine.cpp @@ -72,10 +72,21 @@ void QmmpAudioEngine::reset() m_bitrate = 0; m_chan = 0; m_bps = 0; + m_next = FALSE; } bool QmmpAudioEngine::enqueue(InputSource *source) { + mutex()->lock(); + if(m_decoder && m_decoder->nextURL() == source->url()) + { + delete source; + m_next = TRUE; + mutex()->unlock(); + return TRUE; + } + mutex()->unlock(); + DecoderFactory *factory = Decoder::findByURL(source->url()); if(!factory && !source->url().contains("://")) @@ -103,6 +114,7 @@ bool QmmpAudioEngine::enqueue(InputSource *source) } m_decoders.enqueue(decoder); m_inputs.insert(decoder, source); + source->setParent(this); return TRUE; } @@ -294,6 +306,7 @@ void QmmpAudioEngine::run() Q_ASSERT(m_chan == 0); Q_ASSERT(!m_output_buf); mutex()->lock (); + m_next = FALSE; qint64 len = 0; if(m_decoders.isEmpty()) { @@ -333,7 +346,20 @@ void QmmpAudioEngine::run() } else if (len == 0) { - if(!m_decoders.isEmpty()) + if(m_next) //decoder can play next track without initialization + { + m_next = FALSE; + qDebug("QmmpAudioEngine: switching to the next track"); + emit playbackFinished(); + StateHandler::instance()->dispatch(Qmmp::Stopped); //fake stop/start cycle + StateHandler::instance()->dispatch(Qmmp::Buffering); + StateHandler::instance()->dispatch(Qmmp::Playing); + m_decoder->next(); + m_output->seek(0); //reset counter + mutex()->unlock(); + continue; + } + else if(!m_decoders.isEmpty()) { delete m_inputs.take(m_decoder); delete m_decoder; @@ -402,6 +428,7 @@ void QmmpAudioEngine::run() } mutex()->lock (); + m_next = FALSE; if (m_finish) finish(); mutex()->unlock(); diff --git a/src/qmmp/qmmpaudioengine.h b/src/qmmp/qmmpaudioengine.h index e16ecef72..2b5f33bfc 100644 --- a/src/qmmp/qmmpaudioengine.h +++ b/src/qmmp/qmmpaudioengine.h @@ -81,6 +81,7 @@ private: QQueue <Decoder*> m_decoders; QHash <Decoder*, InputSource*> m_inputs; AudioParameters m_ap; + bool m_next; }; diff --git a/src/qmmp/soundcore.cpp b/src/qmmp/soundcore.cpp index 2a8d3c7a1..2165202b2 100644 --- a/src/qmmp/soundcore.cpp +++ b/src/qmmp/soundcore.cpp @@ -33,7 +33,6 @@ #include "soundcore.h" - SoundCore *SoundCore::m_instance = 0; SoundCore::SoundCore(QObject *parent) @@ -228,11 +227,9 @@ bool SoundCore::enqueue(InputSource *s) setEQ(m_bands, m_preamp); setEQEnabled(m_useEQ); - if(m_engine->enqueue(s)) { m_source = s->url(); - s->setParent(m_engine); m_engine->start(); } else |
