From cd8f92c9285e9b3b460ff47d2f251bfabce544da Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 3 Jan 2010 22:44:23 +0100 Subject: decoder_api: added function decoder_replay_gain() This function replaces the replay_gain_info parameter for decoder_data(). This allows the decoder to announce replay gain changes, instead of having to pass the same object over and over. --- src/decoder/_flac_common.c | 17 ++++----- src/decoder/_flac_common.h | 1 - src/decoder/audiofile_plugin.c | 2 +- src/decoder/faad_plugin.c | 2 +- src/decoder/ffmpeg_plugin.c | 2 +- src/decoder/fluidsynth_plugin.c | 2 +- src/decoder/mad_plugin.c | 73 +++++++++++++++--------------------- src/decoder/mikmod_plugin.c | 3 +- src/decoder/modplug_plugin.c | 2 +- src/decoder/mp4ff_plugin.c | 2 +- src/decoder/mpcdec_plugin.c | 6 +-- src/decoder/mpg123_decoder_plugin.c | 3 +- src/decoder/sidplay_plugin.cxx | 3 +- src/decoder/sndfile_decoder_plugin.c | 2 +- src/decoder/vorbis_plugin.c | 11 ++---- src/decoder/wavpack_plugin.c | 16 ++++---- src/decoder/wildmidi_plugin.c | 3 +- 17 files changed, 63 insertions(+), 87 deletions(-) mode change 100755 => 100644 src/decoder/vorbis_plugin.c (limited to 'src/decoder') diff --git a/src/decoder/_flac_common.c b/src/decoder/_flac_common.c index b970567c4..471e52522 100644 --- a/src/decoder/_flac_common.c +++ b/src/decoder/_flac_common.c @@ -44,7 +44,6 @@ flac_data_init(struct flac_data *data, struct decoder * decoder, data->position = 0; data->decoder = decoder; data->input_stream = input_stream; - data->replay_gain_info = NULL; data->tag = NULL; } @@ -53,9 +52,6 @@ flac_data_deinit(struct flac_data *data) { pcm_buffer_deinit(&data->buffer); - if (data->replay_gain_info != NULL) - replay_gain_info_free(data->replay_gain_info); - if (data->tag != NULL) tag_free(data->tag); } @@ -111,6 +107,8 @@ flac_data_get_audio_format(struct flac_data *data, void flac_metadata_common_cb(const FLAC__StreamMetadata * block, struct flac_data *data) { + struct replay_gain_info *rgi; + switch (block->type) { case FLAC__METADATA_TYPE_STREAMINFO: data->stream_info = block->data.stream_info; @@ -118,9 +116,11 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block, break; case FLAC__METADATA_TYPE_VORBIS_COMMENT: - if (data->replay_gain_info) - replay_gain_info_free(data->replay_gain_info); - data->replay_gain_info = flac_parse_replay_gain(block); + rgi = flac_parse_replay_gain(block); + if (rgi != NULL) { + decoder_replay_gain(data->decoder, rgi); + replay_gain_info_free(rgi); + } if (data->tag != NULL) flac_vorbis_comments_to_tag(data->tag, NULL, @@ -177,8 +177,7 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame, cmd = decoder_data(data->decoder, data->input_stream, buffer, buffer_size, - bit_rate, - data->replay_gain_info); + bit_rate); data->next_frame += frame->header.blocksize; switch (cmd) { case DECODE_COMMAND_NONE: diff --git a/src/decoder/_flac_common.h b/src/decoder/_flac_common.h index 19aaf8388..b94515c03 100644 --- a/src/decoder/_flac_common.h +++ b/src/decoder/_flac_common.h @@ -72,7 +72,6 @@ struct flac_data { FLAC__uint64 position; struct decoder *decoder; struct input_stream *input_stream; - struct replay_gain_info *replay_gain_info; struct tag *tag; }; diff --git a/src/decoder/audiofile_plugin.c b/src/decoder/audiofile_plugin.c index 29ad9e88d..3026f3cc7 100644 --- a/src/decoder/audiofile_plugin.c +++ b/src/decoder/audiofile_plugin.c @@ -206,7 +206,7 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) cmd = decoder_data(decoder, NULL, chunk, ret * fs, - bit_rate, NULL); + bit_rate); if (cmd == DECODE_COMMAND_SEEK) { AFframecount frame = decoder_seek_where(decoder) * diff --git a/src/decoder/faad_plugin.c b/src/decoder/faad_plugin.c index ada6ea65a..8f932ad58 100644 --- a/src/decoder/faad_plugin.c +++ b/src/decoder/faad_plugin.c @@ -479,7 +479,7 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is) cmd = decoder_data(mpd_decoder, is, decoded, (size_t)frame_info.samples * 2, - bit_rate, NULL); + bit_rate); } while (cmd != DECODE_COMMAND_STOP); /* cleanup */ diff --git a/src/decoder/ffmpeg_plugin.c b/src/decoder/ffmpeg_plugin.c index f895426cf..99fbc2108 100644 --- a/src/decoder/ffmpeg_plugin.c +++ b/src/decoder/ffmpeg_plugin.c @@ -270,7 +270,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, cmd = decoder_data(decoder, is, aligned_buffer, audio_size, - codec_context->bit_rate / 1000, NULL); + codec_context->bit_rate / 1000); } return cmd; } diff --git a/src/decoder/fluidsynth_plugin.c b/src/decoder/fluidsynth_plugin.c index f34ad088f..b9a2d0d99 100644 --- a/src/decoder/fluidsynth_plugin.c +++ b/src/decoder/fluidsynth_plugin.c @@ -204,7 +204,7 @@ fluidsynth_file_decode(struct decoder *decoder, const char *path_fs) break; cmd = decoder_data(decoder, NULL, buffer, sizeof(buffer), - 0, NULL); + 0); } while (cmd == DECODE_COMMAND_NONE); /* clean up */ diff --git a/src/decoder/mad_plugin.c b/src/decoder/mad_plugin.c index 4cb02bcc8..8f64ae8d3 100644 --- a/src/decoder/mad_plugin.c +++ b/src/decoder/mad_plugin.c @@ -126,6 +126,7 @@ struct mp3_data { unsigned int drop_end_frames; unsigned int drop_start_samples; unsigned int drop_end_samples; + bool found_replay_gain; bool found_xing; bool found_first_frame; bool decoded_first_frame; @@ -149,6 +150,7 @@ mp3_data_init(struct mp3_data *data, struct decoder *decoder, data->drop_end_frames = 0; data->drop_start_samples = 0; data->drop_end_samples = 0; + data->found_replay_gain = false; data->found_xing = false; data->found_first_frame = false; data->decoded_first_frame = false; @@ -352,8 +354,7 @@ parse_id3_replay_gain_info(struct id3_tag *tag) #endif static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, - struct tag **mpd_tag, - struct replay_gain_info **replay_gain_info_r) + struct tag **mpd_tag) { #ifdef HAVE_ID3TAG struct id3_tag *id3_tag = NULL; @@ -406,13 +407,13 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, } } - if (replay_gain_info_r) { + if (data->decoder != NULL) { struct replay_gain_info *tmp_rgi = parse_id3_replay_gain_info(id3_tag); if (tmp_rgi != NULL) { - if (*replay_gain_info_r) - replay_gain_info_free(*replay_gain_info_r); - *replay_gain_info_r = tmp_rgi; + decoder_replay_gain(data->decoder, tmp_rgi); + replay_gain_info_free(tmp_rgi); + data->found_replay_gain = true; } } @@ -449,8 +450,7 @@ id3_tag_query(const void *p0, size_t length) #endif /* !HAVE_ID3TAG */ static enum mp3_action -decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag, - G_GNUC_UNUSED struct replay_gain_info **replay_gain_info_r) +decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag) { enum mad_layer layer; @@ -472,7 +472,7 @@ decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag, if (tagsize > 0) { if (tag && !(*tag)) { mp3_parse_id3(data, (size_t)tagsize, - tag, replay_gain_info_r); + tag); } else { mad_stream_skip(&(data->stream), tagsize); @@ -820,8 +820,7 @@ mp3_filesize_to_song_length(struct mp3_data *data) } static bool -mp3_decode_first_frame(struct mp3_data *data, struct tag **tag, - struct replay_gain_info **replay_gain_info_r) +mp3_decode_first_frame(struct mp3_data *data, struct tag **tag) { struct xing xing; struct lame lame; @@ -835,8 +834,7 @@ mp3_decode_first_frame(struct mp3_data *data, struct tag **tag, while (true) { do { - ret = decode_next_frame_header(data, tag, - replay_gain_info_r); + ret = decode_next_frame_header(data, tag); } while (ret == DECODE_CONT); if (ret == DECODE_BREAK) return false; @@ -879,11 +877,15 @@ mp3_decode_first_frame(struct mp3_data *data, struct tag **tag, /* Album gain isn't currently used. See comment in * parse_lame() for details. -- jat */ - if (replay_gain_info_r && !*replay_gain_info_r && + if (data->decoder != NULL && + !data->found_replay_gain && lame.track_gain) { - *replay_gain_info_r = replay_gain_info_new(); - (*replay_gain_info_r)->tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain; - (*replay_gain_info_r)->tuples[REPLAY_GAIN_TRACK].peak = lame.peak; + struct replay_gain_info *rgi + = replay_gain_info_new(); + rgi->tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain; + rgi->tuples[REPLAY_GAIN_TRACK].peak = lame.peak; + decoder_replay_gain(data->decoder, rgi); + replay_gain_info_free(rgi); } } } @@ -921,7 +923,7 @@ mad_decoder_total_file_time(struct input_stream *is) int ret; mp3_data_init(&data, NULL, is); - if (!mp3_decode_first_frame(&data, NULL, NULL)) + if (!mp3_decode_first_frame(&data, NULL)) ret = -1; else ret = data.total_time + 0.5; @@ -932,12 +934,11 @@ mad_decoder_total_file_time(struct input_stream *is) static bool mp3_open(struct input_stream *is, struct mp3_data *data, - struct decoder *decoder, struct tag **tag, - struct replay_gain_info **replay_gain_info_r) + struct decoder *decoder, struct tag **tag) { mp3_data_init(data, decoder, is); *tag = NULL; - if (!mp3_decode_first_frame(data, tag, replay_gain_info_r)) { + if (!mp3_decode_first_frame(data, tag)) { mp3_data_finish(data); if (tag && *tag) tag_free(*tag); @@ -996,8 +997,7 @@ mp3_update_timer_next_frame(struct mp3_data *data) * Sends the synthesized current frame via decoder_data(). */ static enum decoder_command -mp3_send_pcm(struct mp3_data *data, unsigned i, unsigned pcm_length, - struct replay_gain_info *replay_gain_info) +mp3_send_pcm(struct mp3_data *data, unsigned i, unsigned pcm_length) { unsigned max_samples; @@ -1022,8 +1022,7 @@ mp3_send_pcm(struct mp3_data *data, unsigned i, unsigned pcm_length, cmd = decoder_data(data->decoder, data->input_stream, data->output_buffer, sizeof(data->output_buffer[0]) * num_samples, - data->bit_rate / 1000, - replay_gain_info); + data->bit_rate / 1000); if (cmd != DECODE_COMMAND_NONE) return cmd; } @@ -1035,8 +1034,7 @@ mp3_send_pcm(struct mp3_data *data, unsigned i, unsigned pcm_length, * Synthesize the current frame and send it via decoder_data(). */ static enum decoder_command -mp3_synth_and_send(struct mp3_data *data, - struct replay_gain_info *replay_gain_info) +mp3_synth_and_send(struct mp3_data *data) { unsigned i, pcm_length; enum decoder_command cmd; @@ -1077,7 +1075,7 @@ mp3_synth_and_send(struct mp3_data *data, pcm_length -= data->drop_end_samples; } - cmd = mp3_send_pcm(data, i, pcm_length, replay_gain_info); + cmd = mp3_send_pcm(data, i, pcm_length); if (cmd != DECODE_COMMAND_NONE) return cmd; @@ -1091,7 +1089,7 @@ mp3_synth_and_send(struct mp3_data *data, } static bool -mp3_read(struct mp3_data *data, struct replay_gain_info **replay_gain_info_r) +mp3_read(struct mp3_data *data) { struct decoder *decoder = data->decoder; enum mp3_action ret; @@ -1108,9 +1106,7 @@ mp3_read(struct mp3_data *data, struct replay_gain_info **replay_gain_info_r) data->mute_frame = MUTEFRAME_NONE; break; case MUTEFRAME_NONE: - cmd = mp3_synth_and_send(data, - replay_gain_info_r != NULL - ? *replay_gain_info_r : NULL); + cmd = mp3_synth_and_send(data); if (cmd == DECODE_COMMAND_SEEK) { unsigned long j; @@ -1139,8 +1135,7 @@ mp3_read(struct mp3_data *data, struct replay_gain_info **replay_gain_info_r) do { struct tag *tag = NULL; - ret = decode_next_frame_header(data, &tag, - replay_gain_info_r); + ret = decode_next_frame_header(data, &tag); if (tag != NULL) { decoder_tag(decoder, data->input_stream, tag); @@ -1173,10 +1168,9 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream) struct mp3_data data; GError *error = NULL; struct tag *tag = NULL; - struct replay_gain_info *replay_gain_info = NULL; struct audio_format audio_format; - if (!mp3_open(input_stream, &data, decoder, &tag, &replay_gain_info)) { + if (!mp3_open(input_stream, &data, decoder, &tag)) { if (decoder_get_command(decoder) == DECODE_COMMAND_NONE) g_warning ("Input does not appear to be a mp3 bit stream.\n"); @@ -1193,8 +1187,6 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream) if (tag != NULL) tag_free(tag); - if (replay_gain_info != NULL) - replay_gain_info_free(replay_gain_info); mp3_data_finish(&data); return; } @@ -1207,10 +1199,7 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream) tag_free(tag); } - while (mp3_read(&data, &replay_gain_info)) ; - - if (replay_gain_info) - replay_gain_info_free(replay_gain_info); + while (mp3_read(&data)) ; if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK && data.mute_frame == MUTEFRAME_SEEK) diff --git a/src/decoder/mikmod_plugin.c b/src/decoder/mikmod_plugin.c index 8a61fca32..69212da59 100644 --- a/src/decoder/mikmod_plugin.c +++ b/src/decoder/mikmod_plugin.c @@ -169,8 +169,7 @@ mikmod_decoder_file_decode(struct decoder *decoder, const char *path_fs) Player_Start(handle); while (cmd == DECODE_COMMAND_NONE && Player_Active()) { ret = VC_WriteBytes(buffer, sizeof(buffer)); - cmd = decoder_data(decoder, NULL, buffer, ret, - 0, NULL); + cmd = decoder_data(decoder, NULL, buffer, ret, 0); } Player_Stop(); diff --git a/src/decoder/modplug_plugin.c b/src/decoder/modplug_plugin.c index 32533cbb0..037c2fd74 100644 --- a/src/decoder/modplug_plugin.c +++ b/src/decoder/modplug_plugin.c @@ -134,7 +134,7 @@ mod_decode(struct decoder *decoder, struct input_stream *is) cmd = decoder_data(decoder, NULL, audio_buffer, ret, - 0, NULL); + 0); if (cmd == DECODE_COMMAND_SEEK) { float where = decoder_seek_where(decoder); diff --git a/src/decoder/mp4ff_plugin.c b/src/decoder/mp4ff_plugin.c index 6bf4c4c49..74fa13339 100644 --- a/src/decoder/mp4ff_plugin.c +++ b/src/decoder/mp4ff_plugin.c @@ -328,7 +328,7 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream) cmd = decoder_data(mpd_decoder, input_stream, sample_buffer, sample_buffer_length, - bit_rate, NULL); + bit_rate); } g_free(seek_table); diff --git a/src/decoder/mpcdec_plugin.c b/src/decoder/mpcdec_plugin.c index 2d6979a78..92f0cad84 100644 --- a/src/decoder/mpcdec_plugin.c +++ b/src/decoder/mpcdec_plugin.c @@ -210,6 +210,8 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) replay_gain_info->tuples[REPLAY_GAIN_ALBUM].peak = info.peak_album / 32767.0; replay_gain_info->tuples[REPLAY_GAIN_TRACK].gain = info.gain_title * 0.01; replay_gain_info->tuples[REPLAY_GAIN_TRACK].peak = info.peak_title / 32767.0; + decoder_replay_gain(mpd_decoder, replay_gain_info); + replay_gain_info_free(replay_gain_info); decoder_initialized(mpd_decoder, &audio_format, is->seekable, @@ -264,11 +266,9 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) cmd = decoder_data(mpd_decoder, is, chunk, ret * sizeof(chunk[0]), - bit_rate, replay_gain_info); + bit_rate); } while (cmd != DECODE_COMMAND_STOP); - replay_gain_info_free(replay_gain_info); - #ifndef MPC_IS_OLD_API mpc_demux_exit(demux); #endif diff --git a/src/decoder/mpg123_decoder_plugin.c b/src/decoder/mpg123_decoder_plugin.c index 44b91675d..7b48ebfaf 100644 --- a/src/decoder/mpg123_decoder_plugin.c +++ b/src/decoder/mpg123_decoder_plugin.c @@ -146,8 +146,7 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs) /* send to MPD */ - cmd = decoder_data(decoder, NULL, buffer, nbytes, - 0, NULL); + cmd = decoder_data(decoder, NULL, buffer, nbytes, 0); /* seeking not yet implemented */ } while (cmd == DECODE_COMMAND_NONE); diff --git a/src/decoder/sidplay_plugin.cxx b/src/decoder/sidplay_plugin.cxx index 95b8082a1..a2eb21ae4 100644 --- a/src/decoder/sidplay_plugin.cxx +++ b/src/decoder/sidplay_plugin.cxx @@ -298,8 +298,7 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs) decoder_timestamp(decoder, (double)player.time() / timebase); - cmd = decoder_data(decoder, NULL, buffer, nbytes, - 0, NULL); + cmd = decoder_data(decoder, NULL, buffer, nbytes, 0); if(cmd==DECODE_COMMAND_SEEK) { unsigned data_time = player.time(); diff --git a/src/decoder/sndfile_decoder_plugin.c b/src/decoder/sndfile_decoder_plugin.c index c0fc208d8..af68f117d 100644 --- a/src/decoder/sndfile_decoder_plugin.c +++ b/src/decoder/sndfile_decoder_plugin.c @@ -155,7 +155,7 @@ sndfile_stream_decode(struct decoder *decoder, struct input_stream *is) cmd = decoder_data(decoder, is, buffer, num_frames * frame_size, - 0, NULL); + 0); if (cmd == DECODE_COMMAND_SEEK) { sf_count_t c = time_to_frame(decoder_seek_where(decoder), diff --git a/src/decoder/vorbis_plugin.c b/src/decoder/vorbis_plugin.c old mode 100755 new mode 100644 index 15f88c960..12a6623b2 --- a/src/decoder/vorbis_plugin.c +++ b/src/decoder/vorbis_plugin.c @@ -277,7 +277,6 @@ vorbis_stream_decode(struct decoder *decoder, char chunk[OGG_CHUNK_SIZE]; long bitRate = 0; long test; - struct replay_gain_info *replay_gain_info = NULL; const vorbis_info *vi; enum decoder_command cmd = DECODE_COMMAND_NONE; @@ -364,9 +363,8 @@ vorbis_stream_decode(struct decoder *decoder, vorbis_send_comments(decoder, input_stream, comments); new_rgi = vorbis_comments_to_replay_gain(comments); if (new_rgi != NULL) { - if (replay_gain_info != NULL) - replay_gain_info_free(replay_gain_info); - replay_gain_info = new_rgi; + decoder_replay_gain(decoder, new_rgi); + replay_gain_info_free(new_rgi); } prev_section = current_section; @@ -377,12 +375,9 @@ vorbis_stream_decode(struct decoder *decoder, cmd = decoder_data(decoder, input_stream, chunk, ret, - bitRate, replay_gain_info); + bitRate); } while (cmd != DECODE_COMMAND_STOP); - if (replay_gain_info) - replay_gain_info_free(replay_gain_info); - ov_clear(&vf); } diff --git a/src/decoder/wavpack_plugin.c b/src/decoder/wavpack_plugin.c index 1615d70d0..380985f85 100644 --- a/src/decoder/wavpack_plugin.c +++ b/src/decoder/wavpack_plugin.c @@ -155,8 +155,7 @@ wavpack_bits_to_sample_format(bool is_float, int bytes_per_sample) * Requires an already opened WavpackContext. */ static void -wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, - struct replay_gain_info *replay_gain_info) +wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek) { GError *error = NULL; bool is_float; @@ -233,8 +232,7 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, decoder_data( decoder, NULL, chunk, samples_got * output_sample_size, - bitrate, - replay_gain_info + bitrate ); } } while (samples_got > 0); @@ -544,7 +542,7 @@ wavpack_streamdecode(struct decoder * decoder, struct input_stream *is) return; } - wavpack_decode(decoder, wpc, can_seek, NULL); + wavpack_decode(decoder, wpc, can_seek); WavpackCloseFile(wpc); if (open_flags & OPEN_WVC) { @@ -575,13 +573,13 @@ wavpack_filedecode(struct decoder *decoder, const char *fname) } replay_gain_info = wavpack_replaygain(wpc); - - wavpack_decode(decoder, wpc, true, replay_gain_info); - - if (replay_gain_info) { + if (replay_gain_info != NULL) { + decoder_replay_gain(decoder, replay_gain_info); replay_gain_info_free(replay_gain_info); } + wavpack_decode(decoder, wpc, true); + WavpackCloseFile(wpc); } diff --git a/src/decoder/wildmidi_plugin.c b/src/decoder/wildmidi_plugin.c index 1166fe02c..60696fb1a 100644 --- a/src/decoder/wildmidi_plugin.c +++ b/src/decoder/wildmidi_plugin.c @@ -91,8 +91,7 @@ wildmidi_file_decode(struct decoder *decoder, const char *path_fs) if (len <= 0) break; - cmd = decoder_data(decoder, NULL, buffer, len, - 0, NULL); + cmd = decoder_data(decoder, NULL, buffer, len, 0); if (cmd == DECODE_COMMAND_SEEK) { unsigned long seek_where = WILDMIDI_SAMPLE_RATE * -- cgit v1.2.3