aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-09-23 23:59:54 +0200
committerMax Kellermann <max@duempel.org>2008-09-23 23:59:54 +0200
commit8bcbe90b250e651fa499524a8c677e19198427a7 (patch)
treee25cf4ea20b028c4ce3296fcc6ed17b966a2df88
parentaac5f4269847e508e01ecc8b99d229185e925659 (diff)
downloadmpd-8bcbe90b250e651fa499524a8c677e19198427a7.tar.gz
mpd-8bcbe90b250e651fa499524a8c677e19198427a7.tar.xz
mpd-8bcbe90b250e651fa499524a8c677e19198427a7.zip
flac: moved code from flacWrite() to _flac_common.c
There is still a lot of duplicated code in flac_plugin.c and oggflac_plugin.c. Move code from flac_plugin.c to _flac_common.c, and use the new function flac_common_write() also in oggflac_plugin.c, porting lots of optimizations over to it.
-rw-r--r--src/inputPlugins/_flac_common.c91
-rw-r--r--src/inputPlugins/_flac_common.h15
-rw-r--r--src/inputPlugins/flac_plugin.c74
-rw-r--r--src/inputPlugins/oggflac_plugin.c46
4 files changed, 97 insertions, 129 deletions
diff --git a/src/inputPlugins/_flac_common.c b/src/inputPlugins/_flac_common.c
index e0c251489..5a98e63bc 100644
--- a/src/inputPlugins/_flac_common.c
+++ b/src/inputPlugins/_flac_common.c
@@ -196,4 +196,95 @@ void flac_error_common_cb(const char *plugin,
}
}
+/* keep this inlined, this is just macro but prettier :) */
+static inline int flacSendChunk(FlacData * data)
+{
+ if (decoder_data(data->decoder, data->inStream,
+ 1, data->chunk,
+ data->chunk_length, data->time,
+ data->bitRate,
+ data->replayGainInfo) == DECODE_COMMAND_STOP)
+ return -1;
+
+ return 0;
+}
+
+static void flac_convert_stereo16(unsigned char *dest,
+ const FLAC__int32 * const buf[],
+ unsigned int position, unsigned int end)
+{
+ for (; position < end; ++position) {
+ *(uint16_t*)dest = buf[0][position];
+ dest += 2;
+ *(uint16_t*)dest = buf[1][position];
+ dest += 2;
+ }
+}
+
+static void flac_convert(unsigned char *dest,
+ unsigned int num_channels,
+ unsigned int bytes_per_sample,
+ const FLAC__int32 * const buf[],
+ unsigned int position, unsigned int end)
+{
+ unsigned int c_chan, i;
+ FLAC__uint16 u16;
+ unsigned char *uc;
+
+ for (; position < end; ++position) {
+ for (c_chan = 0; c_chan < num_channels; c_chan++) {
+ u16 = buf[c_chan][position];
+ uc = (unsigned char *)&u16;
+ for (i = 0; i < bytes_per_sample; i++) {
+ *dest++ = *uc++;
+ }
+ }
+ }
+}
+
+FLAC__StreamDecoderWriteStatus
+flac_common_write(FlacData *data, const FLAC__Frame * frame,
+ const FLAC__int32 *const buf[])
+{
+ unsigned int c_samp;
+ const unsigned int num_channels = frame->header.channels;
+ const unsigned int bytes_per_sample =
+ audio_format_sample_size(&data->audio_format);
+ const unsigned int bytes_per_channel =
+ bytes_per_sample * frame->header.channels;
+ const unsigned int max_samples = FLAC_CHUNK_SIZE / bytes_per_channel;
+ unsigned int num_samples;
+
+ assert(data->audio_format.bits > 0);
+
+ for (c_samp = 0; c_samp < frame->header.blocksize;
+ c_samp += num_samples) {
+ num_samples = frame->header.blocksize - c_samp;
+ if (num_samples > max_samples)
+ num_samples = max_samples;
+
+ if (num_channels == 2 && bytes_per_sample == 2)
+ flac_convert_stereo16(data->chunk,
+ buf, c_samp,
+ c_samp + num_samples);
+ else
+ flac_convert(data->chunk,
+ num_channels, bytes_per_sample, buf,
+ c_samp, c_samp + num_samples);
+ data->chunk_length = num_samples * bytes_per_channel;
+
+ if (flacSendChunk(data) < 0) {
+ return
+ FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+ }
+ data->chunk_length = 0;
+ if (decoder_get_command(data->decoder) == DECODE_COMMAND_SEEK) {
+ return
+ FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ }
+ }
+
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+}
+
#endif /* HAVE_FLAC || HAVE_OGGFLAC */
diff --git a/src/inputPlugins/_flac_common.h b/src/inputPlugins/_flac_common.h
index a758a7369..4ca97cae0 100644
--- a/src/inputPlugins/_flac_common.h
+++ b/src/inputPlugins/_flac_common.h
@@ -164,18 +164,9 @@ void flac_error_common_cb(const char *plugin,
struct tag *copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
struct tag *tag);
-/* keep this inlined, this is just macro but prettier :) */
-static inline int flacSendChunk(FlacData * data)
-{
- if (decoder_data(data->decoder, data->inStream,
- 1, data->chunk,
- data->chunk_length, data->time,
- data->bitRate,
- data->replayGainInfo) == DECODE_COMMAND_STOP)
- return -1;
-
- return 0;
-}
+FLAC__StreamDecoderWriteStatus
+flac_common_write(FlacData *data, const FLAC__Frame * frame,
+ const FLAC__int32 *const buf[]);
#endif /* HAVE_FLAC || HAVE_OGGFLAC */
diff --git a/src/inputPlugins/flac_plugin.c b/src/inputPlugins/flac_plugin.c
index efa3e8355..fb518871a 100644
--- a/src/inputPlugins/flac_plugin.c
+++ b/src/inputPlugins/flac_plugin.c
@@ -195,59 +195,16 @@ static void flacMetadata(mpd_unused const flac_decoder * dec,
flac_metadata_common_cb(block, (FlacData *) vdata);
}
-static void flac_convert_stereo16(unsigned char *dest,
- const FLAC__int32 * const buf[],
- unsigned int position, unsigned int end)
-{
- for (; position < end; ++position) {
- *(uint16_t*)dest = buf[0][position];
- dest += 2;
- *(uint16_t*)dest = buf[1][position];
- dest += 2;
- }
-}
-
-static void flac_convert(unsigned char *dest,
- unsigned int num_channels,
- unsigned int bytes_per_sample,
- const FLAC__int32 * const buf[],
- unsigned int position, unsigned int end)
-{
- unsigned int c_chan, i;
- FLAC__uint16 u16;
- unsigned char *uc;
-
- for (; position < end; ++position) {
- for (c_chan = 0; c_chan < num_channels; c_chan++) {
- u16 = buf[c_chan][position];
- uc = (unsigned char *)&u16;
- for (i = 0; i < bytes_per_sample; i++) {
- *dest++ = *uc++;
- }
- }
- }
-}
-
static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
const FLAC__Frame * frame,
const FLAC__int32 * const buf[],
void *vdata)
{
- FlacData *data = (FlacData *) vdata;
FLAC__uint32 samples = frame->header.blocksize;
- unsigned int c_samp;
- const unsigned int num_channels = frame->header.channels;
- const unsigned int bytes_per_sample =
- audio_format_sample_size(&data->audio_format);
- const unsigned int bytes_per_channel =
- bytes_per_sample * frame->header.channels;
- const unsigned int max_samples = FLAC_CHUNK_SIZE / bytes_per_channel;
- unsigned int num_samples;
+ FlacData *data = (FlacData *) vdata;
float timeChange;
FLAC__uint64 newPosition = 0;
- assert(data->audio_format.bits > 0);
-
timeChange = ((float)samples) / frame->header.sample_rate;
data->time += timeChange;
@@ -261,34 +218,7 @@ static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
}
data->position = newPosition;
- for (c_samp = 0; c_samp < frame->header.blocksize;
- c_samp += num_samples) {
- num_samples = frame->header.blocksize - c_samp;
- if (num_samples > max_samples)
- num_samples = max_samples;
-
- if (num_channels == 2 && bytes_per_sample == 2)
- flac_convert_stereo16(data->chunk,
- buf, c_samp,
- c_samp + num_samples);
- else
- flac_convert(data->chunk,
- num_channels, bytes_per_sample, buf,
- c_samp, c_samp + num_samples);
- data->chunk_length = num_samples * bytes_per_channel;
-
- if (flacSendChunk(data) < 0) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
- data->chunk_length = 0;
- if (decoder_get_command(data->decoder) == DECODE_COMMAND_SEEK) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
- }
- }
-
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ return flac_common_write(data, frame, buf);
}
static struct tag *flacMetadataDup(char *file, int *vorbisCommentFound)
diff --git a/src/inputPlugins/oggflac_plugin.c b/src/inputPlugins/oggflac_plugin.c
index 31ddaab7f..342ebc149 100644
--- a/src/inputPlugins/oggflac_plugin.c
+++ b/src/inputPlugins/oggflac_plugin.c
@@ -157,50 +157,12 @@ static FLAC__StreamDecoderWriteStatus oggflacWrite(mpd_unused const
{
FlacData *data = (FlacData *) vdata;
FLAC__uint32 samples = frame->header.blocksize;
- FLAC__uint16 u16;
- unsigned char *uc;
- unsigned int c_samp, c_chan;
- unsigned int i;
float timeChange;
timeChange = ((float)samples) / frame->header.sample_rate;
data->time += timeChange;
- /* ogg123 uses a complicated method of calculating bitrate
- * with averaging which I'm not too fond of.
- * (waste of memory/CPU cycles, especially given this is _lossless_)
- * a get_decode_position() is not available in OggFLAC, either
- *
- * this does not give an accurate bitrate:
- * (bytes_last_read was set in the read callback)
- data->bitRate = ((8.0 * data->bytes_last_read *
- frame->header.sample_rate)
- /((float)samples * 1000)) + 0.5;
- */
-
- for (c_samp = 0; c_samp < frame->header.blocksize; c_samp++) {
- for (c_chan = 0; c_chan < frame->header.channels;
- c_chan++) {
- u16 = buf[c_chan][c_samp];
- uc = (unsigned char *)&u16;
- for (i = 0; i < audio_format_sample_size(&data->audio_format); i++) {
- if (data->chunk_length >= FLAC_CHUNK_SIZE) {
- if (flacSendChunk(data) < 0) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
- data->chunk_length = 0;
- if (decoder_get_command(data->decoder) == DECODE_COMMAND_SEEK) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
- }
- }
- data->chunk[data->chunk_length++] = *(uc++);
- }
- }
- }
-
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ return flac_common_write(data, frame, buf);
}
/* used by TagDup */
@@ -372,12 +334,6 @@ static int oggflac_decode(struct decoder * mpd_decoder, InputStream * inStream)
(OggFLAC__seekable_stream_decoder_get_state(decoder));
OggFLAC__seekable_stream_decoder_finish(decoder);
}
- /* send last little bit */
- if (data.chunk_length > 0 &&
- decoder_get_command(mpd_decoder) == DECODE_COMMAND_NONE) {
- flacSendChunk(&data);
- decoder_flush(mpd_decoder);
- }
fail:
oggflac_cleanup(&data, decoder);