From 0ac5b6e613777bab093d1dbca1f3d6c80c48ca52 Mon Sep 17 00:00:00 2001 From: Tim Phipps Date: Sat, 8 May 2010 00:19:44 -0700 Subject: mixramp: Adjust MixRamp threshold to account for ReplayGain. --- src/crossfade.c | 8 ++++---- src/crossfade.h | 3 +++ src/decoder/_flac_common.c | 6 ++++-- src/decoder/mad_decoder_plugin.c | 7 +++++-- src/decoder_api.c | 16 ++++++++++++++-- src/decoder_api.h | 6 ++++-- src/decoder_control.c | 2 ++ src/decoder_control.h | 2 ++ src/decoder_thread.c | 2 ++ src/player_thread.c | 2 ++ 10 files changed, 42 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/crossfade.c b/src/crossfade.c index b494b64b6..fff179386 100644 --- a/src/crossfade.c +++ b/src/crossfade.c @@ -91,6 +91,7 @@ static float mixramp_interpolate(char *ramp_list, float required_db) unsigned cross_fade_calc(float duration, float total_time, float mixramp_db, float mixramp_delay, + float replay_gain_db, float replay_gain_prev_db, char *mixramp_start, char *mixramp_prev_end, const struct audio_format *af, const struct audio_format *old_format, @@ -113,10 +114,9 @@ unsigned cross_fade_calc(float duration, float total_time, if (isnan(mixramp_delay) || !(mixramp_start) || !(mixramp_prev_end)) { chunks = (chunks_f * duration + 0.5); } else { - /* Calculate mixramp overlap. - * FIXME factor in ReplayGain for both songs. */ - mixramp_overlap = mixramp_interpolate(mixramp_start, mixramp_db) - + mixramp_interpolate(mixramp_prev_end, mixramp_db); + /* Calculate mixramp overlap. */ + mixramp_overlap = mixramp_interpolate(mixramp_start, mixramp_db - replay_gain_db) + + mixramp_interpolate(mixramp_prev_end, mixramp_db - replay_gain_prev_db); if (!isnan(mixramp_overlap) && (mixramp_delay <= mixramp_overlap)) { chunks = (chunks_f * (mixramp_overlap - mixramp_delay)); g_debug("will overlap %d chunks, %fs", chunks, diff --git a/src/crossfade.h b/src/crossfade.h index 8e45ca72d..096a62020 100644 --- a/src/crossfade.h +++ b/src/crossfade.h @@ -30,6 +30,8 @@ struct music_chunk; * @param total_time total_time the duration of the new song * @param mixramp_db the current mixramp_db setting * @param mixramp_delay the current mixramp_delay setting + * @param replay_gain_db the ReplayGain adjustment used for this song + * @param replay_gain_prev_db the ReplayGain adjustment used on the last song * @param mixramp_start the next songs mixramp_start tag * @param mixramp_prev_end the last songs mixramp_end setting * @param af the audio format of the new song @@ -40,6 +42,7 @@ struct music_chunk; */ unsigned cross_fade_calc(float duration, float total_time, float mixramp_db, float mixramp_delay, + float replay_gain_db, float replay_gain_prev_db, char *mixramp_start, char *mixramp_prev_end, const struct audio_format *af, const struct audio_format *old_format, diff --git a/src/decoder/_flac_common.c b/src/decoder/_flac_common.c index 6f6d33f05..8dd22a253 100644 --- a/src/decoder/_flac_common.c +++ b/src/decoder/_flac_common.c @@ -114,6 +114,7 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block, struct replay_gain_info rgi; char *mixramp_start; char *mixramp_end; + float replay_gain_db = 0; switch (block->type) { case FLAC__METADATA_TYPE_STREAMINFO: @@ -122,10 +123,11 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block, case FLAC__METADATA_TYPE_VORBIS_COMMENT: if (flac_parse_replay_gain(&rgi, block)) - decoder_replay_gain(data->decoder, &rgi); + replay_gain_db = decoder_replay_gain(data->decoder, &rgi); if (flac_parse_mixramp(&mixramp_start, &mixramp_end, block)) { g_debug("setting mixramp_tags"); - decoder_mixramp(data->decoder, mixramp_start, mixramp_end); + decoder_mixramp(data->decoder, replay_gain_db, + mixramp_start, mixramp_end); } if (data->tag != NULL) diff --git a/src/decoder/mad_decoder_plugin.c b/src/decoder/mad_decoder_plugin.c index 57221d878..573afc975 100644 --- a/src/decoder/mad_decoder_plugin.c +++ b/src/decoder/mad_decoder_plugin.c @@ -446,13 +446,16 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, struct replay_gain_info rgi; char *mixramp_start; char *mixramp_end; + float replay_gain_db = 0; + if (parse_id3_replay_gain_info(&rgi, id3_tag)) { - decoder_replay_gain(data->decoder, &rgi); + replay_gain_db = decoder_replay_gain(data->decoder, &rgi); data->found_replay_gain = true; } if (parse_id3_mixramp(&mixramp_start, &mixramp_end, id3_tag)) { g_debug("setting mixramp_tags"); - decoder_mixramp(data->decoder, mixramp_start, mixramp_end); + decoder_mixramp(data->decoder, replay_gain_db, + mixramp_start, mixramp_end); } } diff --git a/src/decoder_api.c b/src/decoder_api.c index 948ccb567..a951b07cf 100644 --- a/src/decoder_api.c +++ b/src/decoder_api.c @@ -27,6 +27,7 @@ #include "buffer.h" #include "pipe.h" #include "chunk.h" +#include "replay_gain_config.h" #include @@ -403,10 +404,11 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is, return cmd; } -void +float decoder_replay_gain(struct decoder *decoder, const struct replay_gain_info *replay_gain_info) { + float return_db = 0; assert(decoder != NULL); if (replay_gain_info != NULL) { @@ -414,6 +416,13 @@ decoder_replay_gain(struct decoder *decoder, if (++serial == 0) serial = 1; + if (REPLAY_GAIN_OFF != replay_gain_mode) { + return_db = 20.0 * log10f( + replay_gain_tuple_scale( + &replay_gain_info->tuples[replay_gain_mode], + replay_gain_preamp)); + } + decoder->replay_gain_info = *replay_gain_info; decoder->replay_gain_serial = serial; @@ -426,16 +435,19 @@ decoder_replay_gain(struct decoder *decoder, } } else decoder->replay_gain_serial = 0; + + return return_db; } void -decoder_mixramp(struct decoder *decoder, +decoder_mixramp(struct decoder *decoder, float replay_gain_db, char *mixramp_start, char *mixramp_end) { assert(decoder != NULL); struct decoder_control *dc = decoder->dc; assert(dc != NULL); + dc->replay_gain_db = replay_gain_db; dc_mixramp_start(dc, mixramp_start); dc_mixramp_end(dc, mixramp_end); } diff --git a/src/decoder_api.h b/src/decoder_api.h index e2b645f6d..8b5f3d82b 100644 --- a/src/decoder_api.h +++ b/src/decoder_api.h @@ -152,8 +152,9 @@ decoder_tag(struct decoder *decoder, struct input_stream *is, * @param decoder the decoder object * @param rgi the replay_gain_info object; may be NULL to invalidate * the previous replay gain values + * @return the replay gain adjustment used */ -void +float decoder_replay_gain(struct decoder *decoder, const struct replay_gain_info *replay_gain_info); @@ -161,11 +162,12 @@ decoder_replay_gain(struct decoder *decoder, * Store MixRamp tags. * * @param decoder the decoder object + * @param replay_gain_db the ReplayGain adjustment used for this song * @param mixramp_start the mixramp_start tag; may be NULL to invalidate * @param mixramp_end the mixramp_end tag; may be NULL to invalidate */ void -decoder_mixramp(struct decoder *decoder, +decoder_mixramp(struct decoder *decoder, float replay_gain_db, char *mixramp_start, char *mixramp_end); #endif diff --git a/src/decoder_control.c b/src/decoder_control.c index 7388d307f..9a1d9abfb 100644 --- a/src/decoder_control.c +++ b/src/decoder_control.c @@ -38,6 +38,8 @@ dc_init(struct decoder_control *dc) dc->state = DECODE_STATE_STOP; dc->command = DECODE_COMMAND_NONE; + dc->replay_gain_db = 0; + dc->replay_gain_prev_db = 0; dc->mixramp_start = NULL; dc->mixramp_end = NULL; dc->mixramp_prev_end = NULL; diff --git a/src/decoder_control.h b/src/decoder_control.h index 7794258c9..449e974b7 100644 --- a/src/decoder_control.h +++ b/src/decoder_control.h @@ -90,6 +90,8 @@ struct decoder_control { */ struct music_pipe *pipe; + float replay_gain_db; + float replay_gain_prev_db; char *mixramp_start; char *mixramp_end; char *mixramp_prev_end; diff --git a/src/decoder_thread.c b/src/decoder_thread.c index 3eab61295..a75f09d37 100644 --- a/src/decoder_thread.c +++ b/src/decoder_thread.c @@ -438,6 +438,8 @@ decoder_task(gpointer arg) dc_mixramp_start(dc, NULL); dc_mixramp_prev_end(dc, dc->mixramp_end); dc->mixramp_end = NULL; /* Don't free, it's copied above. */ + dc->replay_gain_prev_db = dc->replay_gain_db; + dc->replay_gain_db = 0; /* fall through */ diff --git a/src/player_thread.c b/src/player_thread.c index 1a420a7fa..cf4e61384 100644 --- a/src/player_thread.c +++ b/src/player_thread.c @@ -895,6 +895,8 @@ static void do_play(struct decoder_control *dc) cross_fade_calc(pc.cross_fade_seconds, dc->total_time, pc.mixramp_db, pc.mixramp_delay_seconds, + dc->replay_gain_db, + dc->replay_gain_prev_db, dc->mixramp_start, dc->mixramp_prev_end, &dc->out_audio_format, -- cgit v1.2.3