aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2009-09-20 14:26:40 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2009-09-20 14:26:40 +0000
commit5b5f8803d3d95d65699dad5b1e02015683e39c08 (patch)
treeec60e6b2038acee028b71a2a0b423cea936364d2 /src
parentb6ba1017f793b83e099c863fa7c42745361ffef9 (diff)
downloadqmmp-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
Diffstat (limited to 'src')
-rw-r--r--src/plugins/Input/cue/cueparser.cpp5
-rw-r--r--src/plugins/Input/cue/cueparser.h4
-rw-r--r--src/plugins/Input/cue/decoder_cue.cpp97
-rw-r--r--src/plugins/Input/cue/decoder_cue.h11
-rw-r--r--src/qmmp/decoder.cpp8
-rw-r--r--src/qmmp/decoder.h3
-rw-r--r--src/qmmp/qmmpaudioengine.cpp29
-rw-r--r--src/qmmp/qmmpaudioengine.h1
-rw-r--r--src/qmmp/soundcore.cpp3
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