aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/Input/mad/decoder_mad.cpp28
-rw-r--r--src/plugins/Output/alsa/outputalsa.cpp5
-rw-r--r--src/qmmp/constants.h6
-rw-r--r--src/qmmp/decoder.cpp11
-rw-r--r--src/qmmp/output.cpp10
-rw-r--r--src/qmmp/output.h5
-rw-r--r--src/qmmp/recycler.cpp9
7 files changed, 48 insertions, 26 deletions
diff --git a/src/plugins/Input/mad/decoder_mad.cpp b/src/plugins/Input/mad/decoder_mad.cpp
index 095d80371..578fc2ab0 100644
--- a/src/plugins/Input/mad/decoder_mad.cpp
+++ b/src/plugins/Input/mad/decoder_mad.cpp
@@ -18,7 +18,8 @@
#include <math.h>
#include <stdio.h>
-# define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
+#define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
+#define INPUT_BUFFER_SIZE (32*1024)
DecoderMAD::DecoderMAD(QObject *parent, DecoderFactory *d, QIODevice *i, Output *o)
@@ -95,7 +96,7 @@ bool DecoderMAD::initialize()
}
if (! input_buf)
- input_buf = new char[globalBufferSize];
+ input_buf = new char[INPUT_BUFFER_SIZE];
if (! output_buf)
output_buf = new char[globalBufferSize];
@@ -247,7 +248,7 @@ bool DecoderMAD::findHeader()
memmove (input_buf, stream.next_frame, remaining);
}
- input_bytes = input()->read(input_buf + remaining, globalBufferSize - remaining);
+ input_bytes = input()->read(input_buf + remaining, INPUT_BUFFER_SIZE - remaining);
if (input_bytes <= 0)
break;
@@ -358,12 +359,11 @@ void DecoderMAD::stop()
void DecoderMAD::flush(bool final)
{
ulong min = final ? 0 : bks;
-
- while ((! done && ! m_finish) && output_bytes > min && seekTime == -1.)
+ while (!done && (output_bytes > min) && seekTime == -1.)
{
output()->recycler()->mutex()->lock();
- while ((! done && ! m_finish) && output()->recycler()->full())
+ while (!done && output()->recycler()->full())
{
mutex()->unlock();
output()->recycler()->cond()->wait(output()->recycler()->mutex());
@@ -372,7 +372,7 @@ void DecoderMAD::flush(bool final)
done = user_stop;
}
- if (user_stop || m_finish)
+ if (user_stop)
{
inited = FALSE;
done = TRUE;
@@ -395,7 +395,7 @@ void DecoderMAD::flush(bool final)
void DecoderMAD::run()
{
- int skip_frames = 0; //skip first frame
+ int skip_frames = 0;
mutex()->lock();
if (! inited)
@@ -427,7 +427,6 @@ void DecoderMAD::run()
eof = false;
seekTime = -1;
}
-
m_finish = eof;
if (! eof)
@@ -438,10 +437,10 @@ void DecoderMAD::run()
memmove(input_buf, stream.next_frame, input_bytes);
}
- if (input_bytes < globalBufferSize)
+ if (stream.error == MAD_ERROR_BUFLEN)
{
int len = input()->read((char *) input_buf + input_bytes,
- globalBufferSize - input_bytes);
+ INPUT_BUFFER_SIZE - input_bytes);
if (len == 0)
{
@@ -482,6 +481,9 @@ void DecoderMAD::run()
if (stream.error == MAD_ERROR_BUFLEN)
break;
+ if (stream.error == MAD_ERROR_BUFLEN)
+ continue;
+
// error in decoding
if (!MAD_RECOVERABLE(stream.error))
{
@@ -513,7 +515,7 @@ void DecoderMAD::run()
mutex()->lock();
- if (! user_stop && eof)
+ if (!user_stop && eof)
{
flush(TRUE);
@@ -532,7 +534,7 @@ void DecoderMAD::run()
}
done = TRUE;
- if (! user_stop)
+ if (!user_stop)
m_finish = TRUE;
}
diff --git a/src/plugins/Output/alsa/outputalsa.cpp b/src/plugins/Output/alsa/outputalsa.cpp
index 5e9c02938..6ed462e16 100644
--- a/src/plugins/Output/alsa/outputalsa.cpp
+++ b/src/plugins/Output/alsa/outputalsa.cpp
@@ -271,6 +271,7 @@ void OutputALSA::flush()
{
snd_pcm_uframes_t l = snd_pcm_bytes_to_frames(pcm_handle, m_prebuf_fill);
long m;
+ l = snd_pcm_bytes_to_frames(pcm_handle, l);
while (l > 0)
{
if ((m = alsa_write(m_prebuf, l)) >= 0)
@@ -283,6 +284,9 @@ void OutputALSA::flush()
else
break;
}
+ snd_pcm_nonblock(pcm_handle, 0);
+ snd_pcm_drain(pcm_handle);
+ snd_pcm_nonblock(pcm_handle, 1);
}
long OutputALSA::alsa_write(unsigned char *data, long size)
@@ -340,6 +344,7 @@ long OutputALSA::alsa_write(unsigned char *data, long size)
}
return 0;
}
+ qDebug ("OutputALSA: error: %s", snd_strerror(m));
return -1;
}
diff --git a/src/qmmp/constants.h b/src/qmmp/constants.h
index fc31b4664..e9d346343 100644
--- a/src/qmmp/constants.h
+++ b/src/qmmp/constants.h
@@ -1,13 +1,7 @@
#ifndef CONSTANTS_H
#define CONSTANTS_H
-#ifndef LIB_DIR
-#define LIB_DIR "/lib"
-#endif
-
-const unsigned int historySize = 100;
const unsigned int globalBlockSize = 2 * 1024; //2*1024
const unsigned int globalBufferSize = globalBlockSize * 128;
-const unsigned int groupOpenTimeout = 750;
#endif // CONSTANTS_H
diff --git a/src/qmmp/decoder.cpp b/src/qmmp/decoder.cpp
index 65a34abbf..344154164 100644
--- a/src/qmmp/decoder.cpp
+++ b/src/qmmp/decoder.cpp
@@ -183,7 +183,16 @@ qint64 Decoder::produceSound(char *data, qint64 size, quint32 brate, int chan)
void Decoder::finish()
{
- //output()->wait();
+ if (output())
+ {
+ output()->mutex()->lock ();
+ output()->finish();
+ output()->mutex()->unlock();
+ /*output()->recycler()->mutex()->lock ();
+ output()->recycler()->cond()->wakeAll();
+ output()->recycler()->mutex()->unlock();
+ output()->wait();*/
+ }
emit playbackFinished();
}
diff --git a/src/qmmp/output.cpp b/src/qmmp/output.cpp
index bd8948b97..3ce48699b 100644
--- a/src/qmmp/output.cpp
+++ b/src/qmmp/output.cpp
@@ -29,6 +29,7 @@ Output::Output (QObject* parent) : QThread (parent), m_recycler (stackSize())
m_bytesPerMillisecond = 0;
m_userStop = FALSE;
m_pause = FALSE;
+ m_finish = FALSE;
}
void Output::configure(quint32 freq, int chan, int prec)
@@ -51,6 +52,11 @@ void Output::stop()
m_userStop = TRUE;
}
+void Output::finish()
+{
+ m_finish = TRUE;
+}
+
qint64 Output::written()
{
return m_totalWritten;
@@ -196,10 +202,10 @@ void Output::run()
b = 0;
mutex()->unlock();
}
-
mutex()->lock ();
//write remaining data
- flush();
+ if(m_finish)
+ flush();
dispatch(Qmmp::Stopped);
mutex()->unlock();
}
diff --git a/src/qmmp/output.h b/src/qmmp/output.h
index 6a81ece8f..ecbd5b740 100644
--- a/src/qmmp/output.h
+++ b/src/qmmp/output.h
@@ -68,6 +68,10 @@ public:
*/
void stop();
/*!
+ * Requests playback to finish.
+ */
+ void finish();
+ /*!
* Returns the number of bytes that were written.
*/
qint64 written();
@@ -156,6 +160,7 @@ private:
int m_channels, m_precision, m_kbps;
qint64 m_bytesPerMillisecond;
bool m_userStop, m_pause;
+ bool m_finish;
qint64 m_totalWritten, m_currentMilliseconds;
static void checkFactories();
diff --git a/src/qmmp/recycler.cpp b/src/qmmp/recycler.cpp
index 15d2234a6..67d4e4f7e 100644
--- a/src/qmmp/recycler.cpp
+++ b/src/qmmp/recycler.cpp
@@ -13,9 +13,9 @@ Recycler::Recycler ( unsigned int sz )
: add_index ( 0 ), done_index ( 0 ), current_count ( 0 )
{
buffer_count = ( sz / Buffer::size() );
- if ( buffer_count < 1 )
+ if (buffer_count < 4)
{
- buffer_count = 1;
+ buffer_count = 4;
}
buffers = new Buffer*[buffer_count];
@@ -66,7 +66,7 @@ Buffer *Recycler::get(unsigned long size)
{
if (full())
return 0;
- if(size > Buffer::size() + buffers[add_index]->exceeding)
+ if (size > Buffer::size() + buffers[add_index]->exceeding)
{
delete buffers[add_index]->data;
buffers[add_index]->data = new unsigned char[size];
@@ -94,7 +94,8 @@ Buffer *Recycler::next()
void Recycler::done()
{
done_index = ++done_index % buffer_count;
- current_count--;
+ if (current_count)
+ current_count--;
}