aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2008-07-20 20:38:44 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2008-07-20 20:38:44 +0000
commitbfbf64f8de94884be422e03ebeeb3d74315b7c5a (patch)
tree1eeacc0dc51d03a35417de245ceaeee699fde1ab
parent6963d98b9619bf1aa930f2f15d8c431ff743816f (diff)
downloadqmmp-bfbf64f8de94884be422e03ebeeb3d74315b7c5a.tar.gz
qmmp-bfbf64f8de94884be422e03ebeeb3d74315b7c5a.tar.bz2
qmmp-bfbf64f8de94884be422e03ebeeb3d74315b7c5a.zip
24-bit support
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@460 90c681e8-e032-0410-971d-27865f9a5e38
-rw-r--r--AUTHORS7
-rw-r--r--src/plugins/Input/flac/decoder_flac.cpp85
-rw-r--r--src/plugins/Input/flac/decoderflacfactory.cpp1
-rw-r--r--src/plugins/Output/alsa/outputalsa.cpp56
4 files changed, 84 insertions, 65 deletions
diff --git a/AUTHORS b/AUTHORS
index 5d01ae6b5..03591cc32 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -48,5 +48,12 @@ Iterative implementation of a FFT (C) 1999
Richard Boulton <richard@tartarus.org>
+MOC - console audio player for Linux/UNIX (C) 2005
+
+ Damian Pietras <daper@daper.net>
+
+libxmms-flac - XMMS FLAC input plugin (c) 2004-2007
+
+ Josh Coalson
diff --git a/src/plugins/Input/flac/decoder_flac.cpp b/src/plugins/Input/flac/decoder_flac.cpp
index 6f6b8d734..28503959c 100644
--- a/src/plugins/Input/flac/decoder_flac.cpp
+++ b/src/plugins/Input/flac/decoder_flac.cpp
@@ -19,6 +19,10 @@
***************************************************************************/
+/* The code is based on MOC by Damian Pietras <daper@daper.net>
+ and libxmms-flac written by Josh Coalson. */
+
+
#include <qmmp/constants.h>
#include <qmmp/buffer.h>
#include <qmmp/output.h>
@@ -82,10 +86,8 @@ static size_t pack_pcm_signed (FLAC__byte *data,
return wide_samples * channels * bytes_per_sample;
}
-static int flac_decode (void *void_data, char *buf, int buf_len) /*,
- struct sound_params *sound_params)*/
+static int flac_decode (void *void_data, char *buf, int buf_len)
{
- //struct flac_data *data = (struct flac_data *)void_data;
DecoderFLAC *dflac = (DecoderFLAC *) void_data;
unsigned to_copy;
int bytes_per_sample;
@@ -93,23 +95,6 @@ static int flac_decode (void *void_data, char *buf, int buf_len) /*,
bytes_per_sample = dflac->data()->bits_per_sample / 8;
- /*switch (bytes_per_sample) {
- case 1:
- sound_params->fmt = SFMT_S8;
- break;
- case 2:
- sound_params->fmt = SFMT_S16 | SFMT_LE;
- break;
- case 3:
- sound_params->fmt = SFMT_S32 | SFMT_LE;
- break;
- }
-
- sound_params->rate = data->sample_rate;
- sound_params->channels = data->channels;*/
-
- //decoder_error_clear (&data->error);
-
if (!dflac->data()->sample_buffer_fill)
{
@@ -136,8 +121,8 @@ static int flac_decode (void *void_data, char *buf, int buf_len) /*,
dflac->data()->bitrate = int(((float)decode_position -
dflac->data()->last_decode_position) * 8.0 *
- bytes_per_sec /
- dflac->data()->sample_buffer_fill / 1000);
+ bytes_per_sec /
+ dflac->data()->sample_buffer_fill / 1000);
}
dflac->data()->last_decode_position = decode_position;
@@ -153,9 +138,10 @@ static int flac_decode (void *void_data, char *buf, int buf_len) /*,
}
-static FLAC__StreamDecoderReadStatus
-flac_callback_read (const FLAC__StreamDecoder *, FLAC__byte buffer[],
- size_t *bytes, void *client_data)
+static FLAC__StreamDecoderReadStatus flac_callback_read (const FLAC__StreamDecoder*,
+ FLAC__byte buffer[],
+ size_t *bytes,
+ void *client_data)
{
DecoderFLAC *dflac = (DecoderFLAC *) client_data;
qint64 res;
@@ -177,8 +163,10 @@ flac_callback_read (const FLAC__StreamDecoder *, FLAC__byte buffer[],
}
-static FLAC__StreamDecoderWriteStatus
-flac_callback_write (const FLAC__StreamDecoder *, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
+static FLAC__StreamDecoderWriteStatus flac_callback_write (const FLAC__StreamDecoder *,
+ const FLAC__Frame *frame,
+ const FLAC__int32* const buffer[],
+ void *client_data)
{
DecoderFLAC *dflac = (DecoderFLAC *) client_data;
const unsigned wide_samples = frame->header.blocksize;
@@ -196,16 +184,18 @@ flac_callback_write (const FLAC__StreamDecoder *, const FLAC__Frame *frame, cons
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
-static FLAC__StreamDecoderTellStatus
-flac_callback_tell (const FLAC__StreamDecoder *, FLAC__uint64 *offset, void *client_data)
+static FLAC__StreamDecoderTellStatus flac_callback_tell (const FLAC__StreamDecoder *,
+ FLAC__uint64 *offset,
+ void *client_data)
{
DecoderFLAC *dflac = (DecoderFLAC *) client_data;
*offset = dflac->input()->pos ();
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
}
-static FLAC__StreamDecoderSeekStatus
-flac_callback_seek (const FLAC__StreamDecoder *, FLAC__uint64 offset, void *client_data)
+static FLAC__StreamDecoderSeekStatus flac_callback_seek (const FLAC__StreamDecoder *,
+ FLAC__uint64 offset,
+ void *client_data)
{
DecoderFLAC *dflac = (DecoderFLAC *) client_data;
@@ -214,16 +204,18 @@ flac_callback_seek (const FLAC__StreamDecoder *, FLAC__uint64 offset, void *clie
: FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
}
-static FLAC__StreamDecoderLengthStatus
-flac_callback_length (const FLAC__StreamDecoder *, FLAC__uint64 *stream_length, void *client_data)
+static FLAC__StreamDecoderLengthStatus flac_callback_length (const FLAC__StreamDecoder *,
+ FLAC__uint64 *stream_length,
+ void *client_data)
{
DecoderFLAC *dflac = (DecoderFLAC *) client_data;
*stream_length = dflac->input()->size();
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
}
-static void
-flac_callback_metadata (const FLAC__StreamDecoder *, const FLAC__StreamMetadata *metadata, void *client_data)
+static void flac_callback_metadata (const FLAC__StreamDecoder *,
+ const FLAC__StreamMetadata *metadata,
+ void *client_data)
{
DecoderFLAC *dflac = (DecoderFLAC *) client_data;
@@ -242,15 +234,17 @@ flac_callback_metadata (const FLAC__StreamDecoder *, const FLAC__StreamMetadata
}
}
-static FLAC__bool
-flac_callback_eof (const FLAC__StreamDecoder *, void *)
+static FLAC__bool flac_callback_eof (const FLAC__StreamDecoder *, void *)
{
return FALSE;
}
-static void
-flac_callback_error (const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus status, void *client_data)
-{}
+static void flac_callback_error (const FLAC__StreamDecoder *,
+ FLAC__StreamDecoderErrorStatus status,
+ void *)
+{
+ Q_UNUSED(status);
+}
// Decoder class
@@ -274,10 +268,6 @@ DecoderFLAC::DecoderFLAC(QObject *parent, DecoderFactory *d, QIODevice *i, Outpu
chan = 0;
output_size = 0;
m_data = 0;
-
-
-
-
}
@@ -436,7 +426,10 @@ bool DecoderFLAC::initialize()
return FALSE;
}
chan = data()->channels;
- configure(data()->sample_rate, data()->channels, 16, bitrate);
+ if (data()->bits_per_sample == 24)
+ configure(data()->sample_rate, data()->channels, 32, bitrate);
+ else
+ configure(data()->sample_rate, data()->channels, data()->bits_per_sample, bitrate);
totalTime = data()->length;
inited = TRUE;
@@ -462,7 +455,7 @@ void DecoderFLAC::seek(double pos)
void DecoderFLAC::deinit()
{
- if(data())
+ if (data())
FLAC__stream_decoder_finish (data()->decoder);
inited = user_stop = done = finish = FALSE;
len = freq = bitrate = 0;
diff --git a/src/plugins/Input/flac/decoderflacfactory.cpp b/src/plugins/Input/flac/decoderflacfactory.cpp
index 5abb60b39..7ee549b11 100644
--- a/src/plugins/Input/flac/decoderflacfactory.cpp
+++ b/src/plugins/Input/flac/decoderflacfactory.cpp
@@ -17,6 +17,7 @@ bool DecoderFLACFactory::supports(const QString &source) const
bool DecoderFLACFactory::canDecode(QIODevice *input) const
{
+ Q_UNUSED(input);
return FALSE;
}
diff --git a/src/plugins/Output/alsa/outputalsa.cpp b/src/plugins/Output/alsa/outputalsa.cpp
index 9d7eb5b0a..c2a8b9595 100644
--- a/src/plugins/Output/alsa/outputalsa.cpp
+++ b/src/plugins/Output/alsa/outputalsa.cpp
@@ -141,8 +141,26 @@ void OutputALSA::configure(long freq, int chan, int prec, int brate)
return;
}
}
- //TODO set format according prec value
- if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE)) < 0)
+ snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN;
+ switch (prec)
+ {
+ case 8:
+ format = SND_PCM_FORMAT_S8;
+ break;
+ case 16:
+ format = SND_PCM_FORMAT_S16_LE;
+ break;
+ case 24:
+ format = SND_PCM_FORMAT_S24_LE;
+ break;
+ case 32:
+ format = SND_PCM_FORMAT_S32_LE;
+ break;
+ default:
+ qWarning("OutputALSA: unsupported format detected");
+ return;
+ }
+ if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format)) < 0)
{
qDebug("OutputALSA: Error setting format: %s", snd_strerror(err));
return;
@@ -198,7 +216,7 @@ void OutputALSA::configure(long freq, int chan, int prec, int brate)
snd_pcm_sw_params_alloca(&swparams);
snd_pcm_sw_params_current(pcm_handle, swparams);
if ((err = snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams,
- buffer_size - period_size)) < 0)
+ buffer_size - period_size)) < 0)
qWarning("OutputALSA: Error setting threshold: %s", snd_strerror(err));
if ((err = snd_pcm_sw_params(pcm_handle, swparams)) < 0)
{
@@ -206,7 +224,7 @@ void OutputALSA::configure(long freq, int chan, int prec, int brate)
return;
}
//setup needed values
- m_bits_per_frame = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE) * chan;
+ m_bits_per_frame = snd_pcm_format_physical_width(format) * chan;
m_chunk_size = period_size;
}
}
@@ -287,10 +305,10 @@ void OutputALSA::run()
long m = 0;
snd_pcm_uframes_t l;
- long prebuffer_max_size = Buffer::size() + m_bits_per_frame * m_chunk_size / 8;
+ long prebuffer_size = Buffer::size() + m_bits_per_frame * m_chunk_size / 8;
- unsigned char *prebuffer = (unsigned uchar *)malloc(prebuffer_max_size);
- ulong prebuffer_size = 0;
+ unsigned char *prebuffer = (unsigned uchar *)malloc(prebuffer_size);
+ ulong prebuffer_fill = 0;
dispatch(OutputState::Playing);
@@ -323,17 +341,17 @@ void OutputALSA::run()
if (b)
{
- if ((ulong)prebuffer_max_size < prebuffer_size + b->nbytes)
+ if ((ulong)prebuffer_size < prebuffer_fill + b->nbytes)
{
- prebuffer_max_size = prebuffer_size + b->nbytes;
- prebuffer = (unsigned char*) realloc(prebuffer, prebuffer_max_size);
+ prebuffer_size = prebuffer_fill + b->nbytes;
+ prebuffer = (unsigned char*) realloc(prebuffer, prebuffer_size);
}
- memcpy(prebuffer + prebuffer_size, b->data, b->nbytes);
- prebuffer_size += b->nbytes;
+ memcpy(prebuffer + prebuffer_fill, b->data, b->nbytes);
+ prebuffer_fill += b->nbytes;
- l = snd_pcm_bytes_to_frames(pcm_handle, prebuffer_size);
+ l = snd_pcm_bytes_to_frames(pcm_handle, prebuffer_fill);
while (l >= m_chunk_size)
{
@@ -342,8 +360,8 @@ void OutputALSA::run()
{
l -= m;
m = snd_pcm_frames_to_bytes(pcm_handle, m); // convert frames to bytes
- prebuffer_size -= m;
- memcpy(prebuffer, prebuffer + m, prebuffer_size); //move data to begin
+ prebuffer_fill -= m;
+ memcpy(prebuffer, prebuffer + m, prebuffer_fill); //move data to begin
m_totalWritten += m;
status();
dispatchVisual(b, m_totalWritten, m_channels, m_precision);
@@ -362,9 +380,9 @@ void OutputALSA::run()
mutex()->lock ();
//write remaining data
- if (prebuffer_size > 0 && recycler()->empty())
+ if (prebuffer_fill > 0 && recycler()->empty())
{
- l = snd_pcm_bytes_to_frames(pcm_handle, prebuffer_size);
+ l = snd_pcm_bytes_to_frames(pcm_handle, prebuffer_fill);
while (l > 0)
{
@@ -372,8 +390,8 @@ void OutputALSA::run()
{
l -= m;
m = snd_pcm_frames_to_bytes(pcm_handle, m); // convert frames to bytes
- prebuffer_size -= m;
- memcpy(prebuffer, prebuffer + m, prebuffer_size);
+ prebuffer_fill -= m;
+ memcpy(prebuffer, prebuffer + m, prebuffer_fill);
m_totalWritten += m;
status();
}