aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2010-01-03 22:44:23 +0100
committerMax Kellermann <max@duempel.org>2010-01-04 20:42:49 +0100
commitcd8f92c9285e9b3b460ff47d2f251bfabce544da (patch)
tree594de0f646b0fc69405132c3a9e2f05060399abf /src/decoder
parente58b4f773f28ad7b8e26c14c9c853fc2798408a1 (diff)
downloadmpd-cd8f92c9285e9b3b460ff47d2f251bfabce544da.tar.gz
mpd-cd8f92c9285e9b3b460ff47d2f251bfabce544da.tar.xz
mpd-cd8f92c9285e9b3b460ff47d2f251bfabce544da.zip
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.
Diffstat (limited to '')
-rw-r--r--src/decoder/_flac_common.c17
-rw-r--r--src/decoder/_flac_common.h1
-rw-r--r--src/decoder/audiofile_plugin.c2
-rw-r--r--src/decoder/faad_plugin.c2
-rw-r--r--src/decoder/ffmpeg_plugin.c2
-rw-r--r--src/decoder/fluidsynth_plugin.c2
-rw-r--r--src/decoder/mad_plugin.c73
-rw-r--r--src/decoder/mikmod_plugin.c3
-rw-r--r--src/decoder/modplug_plugin.c2
-rw-r--r--src/decoder/mp4ff_plugin.c2
-rw-r--r--src/decoder/mpcdec_plugin.c6
-rw-r--r--src/decoder/mpg123_decoder_plugin.c3
-rw-r--r--src/decoder/sidplay_plugin.cxx3
-rw-r--r--src/decoder/sndfile_decoder_plugin.c2
-rw-r--r--[-rwxr-xr-x]src/decoder/vorbis_plugin.c11
-rw-r--r--src/decoder/wavpack_plugin.c16
-rw-r--r--src/decoder/wildmidi_plugin.c3
-rw-r--r--src/decoder_api.c20
-rw-r--r--src/decoder_api.h14
-rw-r--r--src/decoder_internal.h2
-rw-r--r--src/decoder_thread.c5
21 files changed, 99 insertions, 92 deletions
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
index 15f88c960..12a6623b2 100755..100644
--- 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 *
diff --git a/src/decoder_api.c b/src/decoder_api.c
index 3ef24ee97..5106b564f 100644
--- a/src/decoder_api.c
+++ b/src/decoder_api.c
@@ -266,8 +266,7 @@ enum decoder_command
decoder_data(struct decoder *decoder,
struct input_stream *is,
const void *_data, size_t length,
- uint16_t kbit_rate,
- struct replay_gain_info *replay_gain_info)
+ uint16_t kbit_rate)
{
struct decoder_control *dc = decoder->dc;
const char *data = _data;
@@ -354,7 +353,8 @@ decoder_data(struct decoder *decoder,
/* apply replay gain or normalization */
if (replay_gain_mode != REPLAY_GAIN_OFF)
- replay_gain_apply(replay_gain_info, dest, nbytes,
+ replay_gain_apply(decoder->replay_gain,
+ dest, nbytes,
&dc->out_audio_format);
/* expand the music pipe chunk */
@@ -418,3 +418,17 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is,
return cmd;
}
+
+void
+decoder_replay_gain(struct decoder *decoder,
+ const struct replay_gain_info *replay_gain_info)
+{
+ assert(decoder != NULL);
+
+ if (decoder->replay_gain != NULL)
+ replay_gain_info_free(decoder->replay_gain);
+
+ decoder->replay_gain = replay_gain_info != NULL
+ ? replay_gain_info_dup(replay_gain_info)
+ : NULL;
+}
diff --git a/src/decoder_api.h b/src/decoder_api.h
index 60dc190bd..39e7972d0 100644
--- a/src/decoder_api.h
+++ b/src/decoder_api.h
@@ -138,8 +138,7 @@ decoder_timestamp(struct decoder *decoder, double t);
enum decoder_command
decoder_data(struct decoder *decoder, struct input_stream *is,
const void *data, size_t length,
- uint16_t kbit_rate,
- struct replay_gain_info *replay_gain_info);
+ uint16_t kbit_rate);
/**
* This function is called by the decoder plugin when it has
@@ -156,4 +155,15 @@ enum decoder_command
decoder_tag(struct decoder *decoder, struct input_stream *is,
const struct tag *tag);
+/**
+ * Set replay gain values for the following chunks.
+ *
+ * @param decoder the decoder object
+ * @param rgi the replay_gain_info object; may be NULL to invalidate
+ * the previous replay gain values
+ */
+void
+decoder_replay_gain(struct decoder *decoder,
+ const struct replay_gain_info *replay_gain_info);
+
#endif
diff --git a/src/decoder_internal.h b/src/decoder_internal.h
index 38ad0b396..b15b06888 100644
--- a/src/decoder_internal.h
+++ b/src/decoder_internal.h
@@ -52,6 +52,8 @@ struct decoder {
/** the chunk currently being written to */
struct music_chunk *chunk;
+
+ struct replay_gain_info *replay_gain;
};
/**
diff --git a/src/decoder_thread.c b/src/decoder_thread.c
index de095216a..f793fd032 100644
--- a/src/decoder_thread.c
+++ b/src/decoder_thread.c
@@ -31,6 +31,7 @@
#include "mapper.h"
#include "path.h"
#include "uri.h"
+#include "replay_gain.h"
#include <glib.h>
@@ -302,6 +303,7 @@ decoder_run_song(struct decoder_control *dc,
{
struct decoder decoder = {
.dc = dc,
+ .replay_gain = NULL,
};
int ret;
@@ -329,6 +331,9 @@ decoder_run_song(struct decoder_control *dc,
pcm_convert_deinit(&decoder.conv_state);
/* flush the last chunk */
+ if (decoder.replay_gain != NULL)
+ replay_gain_info_free(decoder.replay_gain);
+
if (decoder.chunk != NULL)
decoder_flush_chunk(&decoder);