diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2008-07-20 20:38:44 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2008-07-20 20:38:44 +0000 |
| commit | bfbf64f8de94884be422e03ebeeb3d74315b7c5a (patch) | |
| tree | 1eeacc0dc51d03a35417de245ceaeee699fde1ab /src | |
| parent | 6963d98b9619bf1aa930f2f15d8c431ff743816f (diff) | |
| download | qmmp-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
Diffstat (limited to 'src')
| -rw-r--r-- | src/plugins/Input/flac/decoder_flac.cpp | 85 | ||||
| -rw-r--r-- | src/plugins/Input/flac/decoderflacfactory.cpp | 1 | ||||
| -rw-r--r-- | src/plugins/Output/alsa/outputalsa.cpp | 56 |
3 files changed, 77 insertions, 65 deletions
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(); } |
