Commit cd8f92c9 authored by Max Kellermann's avatar Max Kellermann

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.
parent e58b4f77
...@@ -44,7 +44,6 @@ flac_data_init(struct flac_data *data, struct decoder * decoder, ...@@ -44,7 +44,6 @@ flac_data_init(struct flac_data *data, struct decoder * decoder,
data->position = 0; data->position = 0;
data->decoder = decoder; data->decoder = decoder;
data->input_stream = input_stream; data->input_stream = input_stream;
data->replay_gain_info = NULL;
data->tag = NULL; data->tag = NULL;
} }
...@@ -53,9 +52,6 @@ flac_data_deinit(struct flac_data *data) ...@@ -53,9 +52,6 @@ flac_data_deinit(struct flac_data *data)
{ {
pcm_buffer_deinit(&data->buffer); pcm_buffer_deinit(&data->buffer);
if (data->replay_gain_info != NULL)
replay_gain_info_free(data->replay_gain_info);
if (data->tag != NULL) if (data->tag != NULL)
tag_free(data->tag); tag_free(data->tag);
} }
...@@ -111,6 +107,8 @@ flac_data_get_audio_format(struct flac_data *data, ...@@ -111,6 +107,8 @@ flac_data_get_audio_format(struct flac_data *data,
void flac_metadata_common_cb(const FLAC__StreamMetadata * block, void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
struct flac_data *data) struct flac_data *data)
{ {
struct replay_gain_info *rgi;
switch (block->type) { switch (block->type) {
case FLAC__METADATA_TYPE_STREAMINFO: case FLAC__METADATA_TYPE_STREAMINFO:
data->stream_info = block->data.stream_info; data->stream_info = block->data.stream_info;
...@@ -118,9 +116,11 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block, ...@@ -118,9 +116,11 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
break; break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT: case FLAC__METADATA_TYPE_VORBIS_COMMENT:
if (data->replay_gain_info) rgi = flac_parse_replay_gain(block);
replay_gain_info_free(data->replay_gain_info); if (rgi != NULL) {
data->replay_gain_info = flac_parse_replay_gain(block); decoder_replay_gain(data->decoder, rgi);
replay_gain_info_free(rgi);
}
if (data->tag != NULL) if (data->tag != NULL)
flac_vorbis_comments_to_tag(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, ...@@ -177,8 +177,7 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
cmd = decoder_data(data->decoder, data->input_stream, cmd = decoder_data(data->decoder, data->input_stream,
buffer, buffer_size, buffer, buffer_size,
bit_rate, bit_rate);
data->replay_gain_info);
data->next_frame += frame->header.blocksize; data->next_frame += frame->header.blocksize;
switch (cmd) { switch (cmd) {
case DECODE_COMMAND_NONE: case DECODE_COMMAND_NONE:
......
...@@ -72,7 +72,6 @@ struct flac_data { ...@@ -72,7 +72,6 @@ struct flac_data {
FLAC__uint64 position; FLAC__uint64 position;
struct decoder *decoder; struct decoder *decoder;
struct input_stream *input_stream; struct input_stream *input_stream;
struct replay_gain_info *replay_gain_info;
struct tag *tag; struct tag *tag;
}; };
......
...@@ -206,7 +206,7 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) ...@@ -206,7 +206,7 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
cmd = decoder_data(decoder, NULL, cmd = decoder_data(decoder, NULL,
chunk, ret * fs, chunk, ret * fs,
bit_rate, NULL); bit_rate);
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {
AFframecount frame = decoder_seek_where(decoder) * AFframecount frame = decoder_seek_where(decoder) *
......
...@@ -479,7 +479,7 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is) ...@@ -479,7 +479,7 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
cmd = decoder_data(mpd_decoder, is, decoded, cmd = decoder_data(mpd_decoder, is, decoded,
(size_t)frame_info.samples * 2, (size_t)frame_info.samples * 2,
bit_rate, NULL); bit_rate);
} while (cmd != DECODE_COMMAND_STOP); } while (cmd != DECODE_COMMAND_STOP);
/* cleanup */ /* cleanup */
......
...@@ -270,7 +270,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, ...@@ -270,7 +270,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
cmd = decoder_data(decoder, is, cmd = decoder_data(decoder, is,
aligned_buffer, audio_size, aligned_buffer, audio_size,
codec_context->bit_rate / 1000, NULL); codec_context->bit_rate / 1000);
} }
return cmd; return cmd;
} }
......
...@@ -204,7 +204,7 @@ fluidsynth_file_decode(struct decoder *decoder, const char *path_fs) ...@@ -204,7 +204,7 @@ fluidsynth_file_decode(struct decoder *decoder, const char *path_fs)
break; break;
cmd = decoder_data(decoder, NULL, buffer, sizeof(buffer), cmd = decoder_data(decoder, NULL, buffer, sizeof(buffer),
0, NULL); 0);
} while (cmd == DECODE_COMMAND_NONE); } while (cmd == DECODE_COMMAND_NONE);
/* clean up */ /* clean up */
......
...@@ -126,6 +126,7 @@ struct mp3_data { ...@@ -126,6 +126,7 @@ struct mp3_data {
unsigned int drop_end_frames; unsigned int drop_end_frames;
unsigned int drop_start_samples; unsigned int drop_start_samples;
unsigned int drop_end_samples; unsigned int drop_end_samples;
bool found_replay_gain;
bool found_xing; bool found_xing;
bool found_first_frame; bool found_first_frame;
bool decoded_first_frame; bool decoded_first_frame;
...@@ -149,6 +150,7 @@ mp3_data_init(struct mp3_data *data, struct decoder *decoder, ...@@ -149,6 +150,7 @@ mp3_data_init(struct mp3_data *data, struct decoder *decoder,
data->drop_end_frames = 0; data->drop_end_frames = 0;
data->drop_start_samples = 0; data->drop_start_samples = 0;
data->drop_end_samples = 0; data->drop_end_samples = 0;
data->found_replay_gain = false;
data->found_xing = false; data->found_xing = false;
data->found_first_frame = false; data->found_first_frame = false;
data->decoded_first_frame = false; data->decoded_first_frame = false;
...@@ -352,8 +354,7 @@ parse_id3_replay_gain_info(struct id3_tag *tag) ...@@ -352,8 +354,7 @@ parse_id3_replay_gain_info(struct id3_tag *tag)
#endif #endif
static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, static void mp3_parse_id3(struct mp3_data *data, size_t tagsize,
struct tag **mpd_tag, struct tag **mpd_tag)
struct replay_gain_info **replay_gain_info_r)
{ {
#ifdef HAVE_ID3TAG #ifdef HAVE_ID3TAG
struct id3_tag *id3_tag = NULL; struct id3_tag *id3_tag = NULL;
...@@ -406,13 +407,13 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, ...@@ -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 = struct replay_gain_info *tmp_rgi =
parse_id3_replay_gain_info(id3_tag); parse_id3_replay_gain_info(id3_tag);
if (tmp_rgi != NULL) { if (tmp_rgi != NULL) {
if (*replay_gain_info_r) decoder_replay_gain(data->decoder, tmp_rgi);
replay_gain_info_free(*replay_gain_info_r); replay_gain_info_free(tmp_rgi);
*replay_gain_info_r = tmp_rgi; data->found_replay_gain = true;
} }
} }
...@@ -449,8 +450,7 @@ id3_tag_query(const void *p0, size_t length) ...@@ -449,8 +450,7 @@ id3_tag_query(const void *p0, size_t length)
#endif /* !HAVE_ID3TAG */ #endif /* !HAVE_ID3TAG */
static enum mp3_action static enum mp3_action
decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag, 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)
{ {
enum mad_layer layer; enum mad_layer layer;
...@@ -472,7 +472,7 @@ decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag, ...@@ -472,7 +472,7 @@ decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag,
if (tagsize > 0) { if (tagsize > 0) {
if (tag && !(*tag)) { if (tag && !(*tag)) {
mp3_parse_id3(data, (size_t)tagsize, mp3_parse_id3(data, (size_t)tagsize,
tag, replay_gain_info_r); tag);
} else { } else {
mad_stream_skip(&(data->stream), mad_stream_skip(&(data->stream),
tagsize); tagsize);
...@@ -820,8 +820,7 @@ mp3_filesize_to_song_length(struct mp3_data *data) ...@@ -820,8 +820,7 @@ mp3_filesize_to_song_length(struct mp3_data *data)
} }
static bool static bool
mp3_decode_first_frame(struct mp3_data *data, struct tag **tag, mp3_decode_first_frame(struct mp3_data *data, struct tag **tag)
struct replay_gain_info **replay_gain_info_r)
{ {
struct xing xing; struct xing xing;
struct lame lame; struct lame lame;
...@@ -835,8 +834,7 @@ mp3_decode_first_frame(struct mp3_data *data, struct tag **tag, ...@@ -835,8 +834,7 @@ mp3_decode_first_frame(struct mp3_data *data, struct tag **tag,
while (true) { while (true) {
do { do {
ret = decode_next_frame_header(data, tag, ret = decode_next_frame_header(data, tag);
replay_gain_info_r);
} while (ret == DECODE_CONT); } while (ret == DECODE_CONT);
if (ret == DECODE_BREAK) if (ret == DECODE_BREAK)
return false; return false;
...@@ -879,11 +877,15 @@ mp3_decode_first_frame(struct mp3_data *data, struct tag **tag, ...@@ -879,11 +877,15 @@ mp3_decode_first_frame(struct mp3_data *data, struct tag **tag,
/* Album gain isn't currently used. See comment in /* Album gain isn't currently used. See comment in
* parse_lame() for details. -- jat */ * 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) { lame.track_gain) {
*replay_gain_info_r = replay_gain_info_new(); struct replay_gain_info *rgi
(*replay_gain_info_r)->tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain; = replay_gain_info_new();
(*replay_gain_info_r)->tuples[REPLAY_GAIN_TRACK].peak = lame.peak; 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) ...@@ -921,7 +923,7 @@ mad_decoder_total_file_time(struct input_stream *is)
int ret; int ret;
mp3_data_init(&data, NULL, is); mp3_data_init(&data, NULL, is);
if (!mp3_decode_first_frame(&data, NULL, NULL)) if (!mp3_decode_first_frame(&data, NULL))
ret = -1; ret = -1;
else else
ret = data.total_time + 0.5; ret = data.total_time + 0.5;
...@@ -932,12 +934,11 @@ mad_decoder_total_file_time(struct input_stream *is) ...@@ -932,12 +934,11 @@ mad_decoder_total_file_time(struct input_stream *is)
static bool static bool
mp3_open(struct input_stream *is, struct mp3_data *data, mp3_open(struct input_stream *is, struct mp3_data *data,
struct decoder *decoder, struct tag **tag, struct decoder *decoder, struct tag **tag)
struct replay_gain_info **replay_gain_info_r)
{ {
mp3_data_init(data, decoder, is); mp3_data_init(data, decoder, is);
*tag = NULL; *tag = NULL;
if (!mp3_decode_first_frame(data, tag, replay_gain_info_r)) { if (!mp3_decode_first_frame(data, tag)) {
mp3_data_finish(data); mp3_data_finish(data);
if (tag && *tag) if (tag && *tag)
tag_free(*tag); tag_free(*tag);
...@@ -996,8 +997,7 @@ mp3_update_timer_next_frame(struct mp3_data *data) ...@@ -996,8 +997,7 @@ mp3_update_timer_next_frame(struct mp3_data *data)
* Sends the synthesized current frame via decoder_data(). * Sends the synthesized current frame via decoder_data().
*/ */
static enum decoder_command static enum decoder_command
mp3_send_pcm(struct mp3_data *data, unsigned i, unsigned pcm_length, mp3_send_pcm(struct mp3_data *data, unsigned i, unsigned pcm_length)
struct replay_gain_info *replay_gain_info)
{ {
unsigned max_samples; unsigned max_samples;
...@@ -1022,8 +1022,7 @@ mp3_send_pcm(struct mp3_data *data, unsigned i, unsigned pcm_length, ...@@ -1022,8 +1022,7 @@ mp3_send_pcm(struct mp3_data *data, unsigned i, unsigned pcm_length,
cmd = decoder_data(data->decoder, data->input_stream, cmd = decoder_data(data->decoder, data->input_stream,
data->output_buffer, data->output_buffer,
sizeof(data->output_buffer[0]) * num_samples, sizeof(data->output_buffer[0]) * num_samples,
data->bit_rate / 1000, data->bit_rate / 1000);
replay_gain_info);
if (cmd != DECODE_COMMAND_NONE) if (cmd != DECODE_COMMAND_NONE)
return cmd; return cmd;
} }
...@@ -1035,8 +1034,7 @@ mp3_send_pcm(struct mp3_data *data, unsigned i, unsigned pcm_length, ...@@ -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(). * Synthesize the current frame and send it via decoder_data().
*/ */
static enum decoder_command static enum decoder_command
mp3_synth_and_send(struct mp3_data *data, mp3_synth_and_send(struct mp3_data *data)
struct replay_gain_info *replay_gain_info)
{ {
unsigned i, pcm_length; unsigned i, pcm_length;
enum decoder_command cmd; enum decoder_command cmd;
...@@ -1077,7 +1075,7 @@ mp3_synth_and_send(struct mp3_data *data, ...@@ -1077,7 +1075,7 @@ mp3_synth_and_send(struct mp3_data *data,
pcm_length -= data->drop_end_samples; 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) if (cmd != DECODE_COMMAND_NONE)
return cmd; return cmd;
...@@ -1091,7 +1089,7 @@ mp3_synth_and_send(struct mp3_data *data, ...@@ -1091,7 +1089,7 @@ mp3_synth_and_send(struct mp3_data *data,
} }
static bool 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; struct decoder *decoder = data->decoder;
enum mp3_action ret; enum mp3_action ret;
...@@ -1108,9 +1106,7 @@ mp3_read(struct mp3_data *data, struct replay_gain_info **replay_gain_info_r) ...@@ -1108,9 +1106,7 @@ mp3_read(struct mp3_data *data, struct replay_gain_info **replay_gain_info_r)
data->mute_frame = MUTEFRAME_NONE; data->mute_frame = MUTEFRAME_NONE;
break; break;
case MUTEFRAME_NONE: case MUTEFRAME_NONE:
cmd = mp3_synth_and_send(data, cmd = mp3_synth_and_send(data);
replay_gain_info_r != NULL
? *replay_gain_info_r : NULL);
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {
unsigned long j; unsigned long j;
...@@ -1139,8 +1135,7 @@ mp3_read(struct mp3_data *data, struct replay_gain_info **replay_gain_info_r) ...@@ -1139,8 +1135,7 @@ mp3_read(struct mp3_data *data, struct replay_gain_info **replay_gain_info_r)
do { do {
struct tag *tag = NULL; struct tag *tag = NULL;
ret = decode_next_frame_header(data, &tag, ret = decode_next_frame_header(data, &tag);
replay_gain_info_r);
if (tag != NULL) { if (tag != NULL) {
decoder_tag(decoder, data->input_stream, tag); decoder_tag(decoder, data->input_stream, tag);
...@@ -1173,10 +1168,9 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream) ...@@ -1173,10 +1168,9 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
struct mp3_data data; struct mp3_data data;
GError *error = NULL; GError *error = NULL;
struct tag *tag = NULL; struct tag *tag = NULL;
struct replay_gain_info *replay_gain_info = NULL;
struct audio_format audio_format; 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) if (decoder_get_command(decoder) == DECODE_COMMAND_NONE)
g_warning g_warning
("Input does not appear to be a mp3 bit stream.\n"); ("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) ...@@ -1193,8 +1187,6 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
if (tag != NULL) if (tag != NULL)
tag_free(tag); tag_free(tag);
if (replay_gain_info != NULL)
replay_gain_info_free(replay_gain_info);
mp3_data_finish(&data); mp3_data_finish(&data);
return; return;
} }
...@@ -1207,10 +1199,7 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream) ...@@ -1207,10 +1199,7 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
tag_free(tag); tag_free(tag);
} }
while (mp3_read(&data, &replay_gain_info)) ; while (mp3_read(&data)) ;
if (replay_gain_info)
replay_gain_info_free(replay_gain_info);
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK && if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK &&
data.mute_frame == MUTEFRAME_SEEK) data.mute_frame == MUTEFRAME_SEEK)
......
...@@ -169,8 +169,7 @@ mikmod_decoder_file_decode(struct decoder *decoder, const char *path_fs) ...@@ -169,8 +169,7 @@ mikmod_decoder_file_decode(struct decoder *decoder, const char *path_fs)
Player_Start(handle); Player_Start(handle);
while (cmd == DECODE_COMMAND_NONE && Player_Active()) { while (cmd == DECODE_COMMAND_NONE && Player_Active()) {
ret = VC_WriteBytes(buffer, sizeof(buffer)); ret = VC_WriteBytes(buffer, sizeof(buffer));
cmd = decoder_data(decoder, NULL, buffer, ret, cmd = decoder_data(decoder, NULL, buffer, ret, 0);
0, NULL);
} }
Player_Stop(); Player_Stop();
......
...@@ -134,7 +134,7 @@ mod_decode(struct decoder *decoder, struct input_stream *is) ...@@ -134,7 +134,7 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
cmd = decoder_data(decoder, NULL, cmd = decoder_data(decoder, NULL,
audio_buffer, ret, audio_buffer, ret,
0, NULL); 0);
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {
float where = decoder_seek_where(decoder); float where = decoder_seek_where(decoder);
......
...@@ -328,7 +328,7 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream) ...@@ -328,7 +328,7 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
cmd = decoder_data(mpd_decoder, input_stream, cmd = decoder_data(mpd_decoder, input_stream,
sample_buffer, sample_buffer_length, sample_buffer, sample_buffer_length,
bit_rate, NULL); bit_rate);
} }
g_free(seek_table); g_free(seek_table);
......
...@@ -210,6 +210,8 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) ...@@ -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_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].gain = info.gain_title * 0.01;
replay_gain_info->tuples[REPLAY_GAIN_TRACK].peak = info.peak_title / 32767.0; 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, decoder_initialized(mpd_decoder, &audio_format,
is->seekable, is->seekable,
...@@ -264,11 +266,9 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) ...@@ -264,11 +266,9 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
cmd = decoder_data(mpd_decoder, is, cmd = decoder_data(mpd_decoder, is,
chunk, ret * sizeof(chunk[0]), chunk, ret * sizeof(chunk[0]),
bit_rate, replay_gain_info); bit_rate);
} while (cmd != DECODE_COMMAND_STOP); } while (cmd != DECODE_COMMAND_STOP);
replay_gain_info_free(replay_gain_info);
#ifndef MPC_IS_OLD_API #ifndef MPC_IS_OLD_API
mpc_demux_exit(demux); mpc_demux_exit(demux);
#endif #endif
......
...@@ -146,8 +146,7 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs) ...@@ -146,8 +146,7 @@ mpd_mpg123_file_decode(struct decoder *decoder, const char *path_fs)
/* send to MPD */ /* send to MPD */
cmd = decoder_data(decoder, NULL, buffer, nbytes, cmd = decoder_data(decoder, NULL, buffer, nbytes, 0);
0, NULL);
/* seeking not yet implemented */ /* seeking not yet implemented */
} while (cmd == DECODE_COMMAND_NONE); } while (cmd == DECODE_COMMAND_NONE);
......
...@@ -298,8 +298,7 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs) ...@@ -298,8 +298,7 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs)
decoder_timestamp(decoder, (double)player.time() / timebase); decoder_timestamp(decoder, (double)player.time() / timebase);
cmd = decoder_data(decoder, NULL, buffer, nbytes, cmd = decoder_data(decoder, NULL, buffer, nbytes, 0);
0, NULL);
if(cmd==DECODE_COMMAND_SEEK) { if(cmd==DECODE_COMMAND_SEEK) {
unsigned data_time = player.time(); unsigned data_time = player.time();
......
...@@ -155,7 +155,7 @@ sndfile_stream_decode(struct decoder *decoder, struct input_stream *is) ...@@ -155,7 +155,7 @@ sndfile_stream_decode(struct decoder *decoder, struct input_stream *is)
cmd = decoder_data(decoder, is, cmd = decoder_data(decoder, is,
buffer, num_frames * frame_size, buffer, num_frames * frame_size,
0, NULL); 0);
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {
sf_count_t c = sf_count_t c =
time_to_frame(decoder_seek_where(decoder), time_to_frame(decoder_seek_where(decoder),
......
...@@ -277,7 +277,6 @@ vorbis_stream_decode(struct decoder *decoder, ...@@ -277,7 +277,6 @@ vorbis_stream_decode(struct decoder *decoder,
char chunk[OGG_CHUNK_SIZE]; char chunk[OGG_CHUNK_SIZE];
long bitRate = 0; long bitRate = 0;
long test; long test;
struct replay_gain_info *replay_gain_info = NULL;
const vorbis_info *vi; const vorbis_info *vi;
enum decoder_command cmd = DECODE_COMMAND_NONE; enum decoder_command cmd = DECODE_COMMAND_NONE;
...@@ -364,9 +363,8 @@ vorbis_stream_decode(struct decoder *decoder, ...@@ -364,9 +363,8 @@ vorbis_stream_decode(struct decoder *decoder,
vorbis_send_comments(decoder, input_stream, comments); vorbis_send_comments(decoder, input_stream, comments);
new_rgi = vorbis_comments_to_replay_gain(comments); new_rgi = vorbis_comments_to_replay_gain(comments);
if (new_rgi != NULL) { if (new_rgi != NULL) {
if (replay_gain_info != NULL) decoder_replay_gain(decoder, new_rgi);
replay_gain_info_free(replay_gain_info); replay_gain_info_free(new_rgi);
replay_gain_info = new_rgi;
} }
prev_section = current_section; prev_section = current_section;
...@@ -377,12 +375,9 @@ vorbis_stream_decode(struct decoder *decoder, ...@@ -377,12 +375,9 @@ vorbis_stream_decode(struct decoder *decoder,
cmd = decoder_data(decoder, input_stream, cmd = decoder_data(decoder, input_stream,
chunk, ret, chunk, ret,
bitRate, replay_gain_info); bitRate);
} while (cmd != DECODE_COMMAND_STOP); } while (cmd != DECODE_COMMAND_STOP);
if (replay_gain_info)
replay_gain_info_free(replay_gain_info);
ov_clear(&vf); ov_clear(&vf);
} }
......
...@@ -155,8 +155,7 @@ wavpack_bits_to_sample_format(bool is_float, int bytes_per_sample) ...@@ -155,8 +155,7 @@ wavpack_bits_to_sample_format(bool is_float, int bytes_per_sample)
* Requires an already opened WavpackContext. * Requires an already opened WavpackContext.
*/ */
static void static void
wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek)
struct replay_gain_info *replay_gain_info)
{ {
GError *error = NULL; GError *error = NULL;
bool is_float; bool is_float;
...@@ -233,8 +232,7 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, ...@@ -233,8 +232,7 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
decoder_data( decoder_data(
decoder, NULL, chunk, decoder, NULL, chunk,
samples_got * output_sample_size, samples_got * output_sample_size,
bitrate, bitrate
replay_gain_info
); );
} }
} while (samples_got > 0); } while (samples_got > 0);
...@@ -544,7 +542,7 @@ wavpack_streamdecode(struct decoder * decoder, struct input_stream *is) ...@@ -544,7 +542,7 @@ wavpack_streamdecode(struct decoder * decoder, struct input_stream *is)
return; return;
} }
wavpack_decode(decoder, wpc, can_seek, NULL); wavpack_decode(decoder, wpc, can_seek);
WavpackCloseFile(wpc); WavpackCloseFile(wpc);
if (open_flags & OPEN_WVC) { if (open_flags & OPEN_WVC) {
...@@ -575,13 +573,13 @@ wavpack_filedecode(struct decoder *decoder, const char *fname) ...@@ -575,13 +573,13 @@ wavpack_filedecode(struct decoder *decoder, const char *fname)
} }
replay_gain_info = wavpack_replaygain(wpc); replay_gain_info = wavpack_replaygain(wpc);
if (replay_gain_info != NULL) {
wavpack_decode(decoder, wpc, true, replay_gain_info); decoder_replay_gain(decoder, replay_gain_info);
if (replay_gain_info) {
replay_gain_info_free(replay_gain_info); replay_gain_info_free(replay_gain_info);
} }
wavpack_decode(decoder, wpc, true);
WavpackCloseFile(wpc); WavpackCloseFile(wpc);
} }
......
...@@ -91,8 +91,7 @@ wildmidi_file_decode(struct decoder *decoder, const char *path_fs) ...@@ -91,8 +91,7 @@ wildmidi_file_decode(struct decoder *decoder, const char *path_fs)
if (len <= 0) if (len <= 0)
break; break;
cmd = decoder_data(decoder, NULL, buffer, len, cmd = decoder_data(decoder, NULL, buffer, len, 0);
0, NULL);
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {
unsigned long seek_where = WILDMIDI_SAMPLE_RATE * unsigned long seek_where = WILDMIDI_SAMPLE_RATE *
......
...@@ -266,8 +266,7 @@ enum decoder_command ...@@ -266,8 +266,7 @@ enum decoder_command
decoder_data(struct decoder *decoder, decoder_data(struct decoder *decoder,
struct input_stream *is, struct input_stream *is,
const void *_data, size_t length, const void *_data, size_t length,
uint16_t kbit_rate, uint16_t kbit_rate)
struct replay_gain_info *replay_gain_info)
{ {
struct decoder_control *dc = decoder->dc; struct decoder_control *dc = decoder->dc;
const char *data = _data; const char *data = _data;
...@@ -354,7 +353,8 @@ decoder_data(struct decoder *decoder, ...@@ -354,7 +353,8 @@ decoder_data(struct decoder *decoder,
/* apply replay gain or normalization */ /* apply replay gain or normalization */
if (replay_gain_mode != REPLAY_GAIN_OFF) 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); &dc->out_audio_format);
/* expand the music pipe chunk */ /* expand the music pipe chunk */
...@@ -418,3 +418,17 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is, ...@@ -418,3 +418,17 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is,
return cmd; 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;
}
...@@ -138,8 +138,7 @@ decoder_timestamp(struct decoder *decoder, double t); ...@@ -138,8 +138,7 @@ decoder_timestamp(struct decoder *decoder, double t);
enum decoder_command enum decoder_command
decoder_data(struct decoder *decoder, struct input_stream *is, decoder_data(struct decoder *decoder, struct input_stream *is,
const void *data, size_t length, const void *data, size_t length,
uint16_t kbit_rate, uint16_t kbit_rate);
struct replay_gain_info *replay_gain_info);
/** /**
* This function is called by the decoder plugin when it has * This function is called by the decoder plugin when it has
...@@ -156,4 +155,15 @@ enum decoder_command ...@@ -156,4 +155,15 @@ enum decoder_command
decoder_tag(struct decoder *decoder, struct input_stream *is, decoder_tag(struct decoder *decoder, struct input_stream *is,
const struct tag *tag); 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 #endif
...@@ -52,6 +52,8 @@ struct decoder { ...@@ -52,6 +52,8 @@ struct decoder {
/** the chunk currently being written to */ /** the chunk currently being written to */
struct music_chunk *chunk; struct music_chunk *chunk;
struct replay_gain_info *replay_gain;
}; };
/** /**
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "mapper.h" #include "mapper.h"
#include "path.h" #include "path.h"
#include "uri.h" #include "uri.h"
#include "replay_gain.h"
#include <glib.h> #include <glib.h>
...@@ -302,6 +303,7 @@ decoder_run_song(struct decoder_control *dc, ...@@ -302,6 +303,7 @@ decoder_run_song(struct decoder_control *dc,
{ {
struct decoder decoder = { struct decoder decoder = {
.dc = dc, .dc = dc,
.replay_gain = NULL,
}; };
int ret; int ret;
...@@ -329,6 +331,9 @@ decoder_run_song(struct decoder_control *dc, ...@@ -329,6 +331,9 @@ decoder_run_song(struct decoder_control *dc,
pcm_convert_deinit(&decoder.conv_state); pcm_convert_deinit(&decoder.conv_state);
/* flush the last chunk */ /* flush the last chunk */
if (decoder.replay_gain != NULL)
replay_gain_info_free(decoder.replay_gain);
if (decoder.chunk != NULL) if (decoder.chunk != NULL)
decoder_flush_chunk(&decoder); decoder_flush_chunk(&decoder);
......
...@@ -106,8 +106,7 @@ enum decoder_command ...@@ -106,8 +106,7 @@ enum decoder_command
decoder_data(G_GNUC_UNUSED struct decoder *decoder, decoder_data(G_GNUC_UNUSED struct decoder *decoder,
G_GNUC_UNUSED struct input_stream *is, G_GNUC_UNUSED struct input_stream *is,
const void *data, size_t datalen, const void *data, size_t datalen,
G_GNUC_UNUSED uint16_t bit_rate, G_GNUC_UNUSED uint16_t bit_rate)
G_GNUC_UNUSED struct replay_gain_info *replay_gain_info)
{ {
write(1, data, datalen); write(1, data, datalen);
return DECODE_COMMAND_NONE; return DECODE_COMMAND_NONE;
...@@ -121,6 +120,12 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, ...@@ -121,6 +120,12 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder,
return DECODE_COMMAND_NONE; return DECODE_COMMAND_NONE;
} }
void
decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder,
G_GNUC_UNUSED const struct replay_gain_info *replay_gain_info)
{
}
static void static void
print_tag(const struct tag *tag) print_tag(const struct tag *tag)
{ {
......
...@@ -127,8 +127,7 @@ enum decoder_command ...@@ -127,8 +127,7 @@ enum decoder_command
decoder_data(G_GNUC_UNUSED struct decoder *decoder, decoder_data(G_GNUC_UNUSED struct decoder *decoder,
G_GNUC_UNUSED struct input_stream *is, G_GNUC_UNUSED struct input_stream *is,
const void *data, size_t datalen, const void *data, size_t datalen,
G_GNUC_UNUSED uint16_t kbit_rate, G_GNUC_UNUSED uint16_t kbit_rate)
G_GNUC_UNUSED struct replay_gain_info *replay_gain_info)
{ {
write(1, data, datalen); write(1, data, datalen);
return DECODE_COMMAND_NONE; return DECODE_COMMAND_NONE;
...@@ -142,6 +141,12 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, ...@@ -142,6 +141,12 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder,
return DECODE_COMMAND_NONE; return DECODE_COMMAND_NONE;
} }
void
decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder,
G_GNUC_UNUSED const struct replay_gain_info *replay_gain_info)
{
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
GError *error = NULL; GError *error = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment