# HG changeset patch # User Eugene Zagidullin # Date 1201906395 -10800 # Node ID 8f695613037291bf274eb8d2d25cccd28ee8ce69 # Parent 1ab015fe2ade72a444973fed320d740163c4ea3b initial Replay Gain support diff -r 1ab015fe2ade -r 8f6956130372 src/audacious/Makefile --- a/src/audacious/Makefile Thu Jan 31 21:43:51 2008 +0300 +++ b/src/audacious/Makefile Sat Feb 02 01:53:15 2008 +0300 @@ -134,6 +134,7 @@ images/playback.png \ images/playlist.png \ images/plugins.png \ + images/replay_gain.png \ ui/equalizer.ui \ ui/mainwin.ui \ ui/playlist.ui \ diff -r 1ab015fe2ade -r 8f6956130372 src/audacious/output.c --- a/src/audacious/output.c Thu Jan 31 21:43:51 2008 +0300 +++ b/src/audacious/output.c Sat Feb 02 01:53:15 2008 +0300 @@ -142,6 +142,8 @@ } } +static void apply_replaygain_info (ReplayGainInfo *rg_info); + static SAD_sample_format sadfmt_from_afmt(AFormat fmt) { @@ -332,6 +334,12 @@ static SAD_dither_t *sad_state_from_float = NULL; static void *sad_out_buf = NULL; static int sad_out_buf_length = 0; +static ReplayGainInfo replay_gain_info = { + .track_gain = 0.0, + .track_peak = 0.0, + .album_gain = 0.0, + .album_peak = 0.0, +}; static void freeSAD() @@ -347,19 +355,19 @@ { gint ret; OutputPlugin *op; - ConfigDb *db; AUDDBG("\n"); AFormat output_fmt; int bit_depth; SAD_buffer_format input_sad_fmt; SAD_buffer_format output_sad_fmt; - - db = cfg_db_open(); #ifdef USE_SRC gboolean src_enabled; gint src_rate, src_type; + ConfigDb *db; + + db = cfg_db_open(); if (cfg_db_get_bool(db, NULL, "enable_src", &src_enabled) == FALSE) src_enabled = FALSE; @@ -394,10 +402,12 @@ src_enabled = FALSE; } } + + cfg_db_close(db); #endif - if (cfg_db_get_int(db, NULL, "output_bit_depth", &bit_depth) == FALSE) bit_depth = 16; - cfg_db_close(db); + /*if (cfg_db_get_int(db, NULL, "output_bit_depth", &bit_depth) == FALSE) bit_depth = 16;*/ + bit_depth = cfg.output_bit_depth; AUDDBG("bit depth: %d\n", bit_depth); output_fmt = (bit_depth == 24) ? FMT_S24_NE : FMT_S16_NE; /* no reason to support other output formats --asphyx */ @@ -451,7 +461,7 @@ fmt = output_fmt; } else #endif /* USE_SRC */ - if (output_fmt != fmt) { + { /* needed for RG processing !*/ AUDDBG("initializing dithering engine for direct conversion\n"); input_sad_fmt.sample_format = sadfmt_from_afmt(fmt); @@ -476,6 +486,9 @@ fmt = output_fmt; } + + if(replay_gain_info.album_peak != 0.0 || replay_gain_info.track_peak != 0.0) + apply_replaygain_info(&replay_gain_info); op = get_current_output_plugin(); @@ -530,6 +543,12 @@ freeSRC(); #endif freeSAD(); + + AUDDBG("clearing RG settings\n"); + replay_gain_info.track_gain = 0.0; + replay_gain_info.track_peak = 0.0; + replay_gain_info.album_gain = 0.0; + replay_gain_info.album_peak = 0.0; /* Do not close if there are still songs to play and the user has * not requested a stop. --nenolod @@ -727,9 +746,57 @@ } } -/* called by input plugin when RG info available */ +/* called by input plugin when RG info available --asphyx */ void output_set_replaygain_info (InputPlayback *pb, ReplayGainInfo *rg_info) { - /*stub*/ + replay_gain_info = *rg_info; + apply_replaygain_info(rg_info); } + +static void +apply_replaygain_info (ReplayGainInfo *rg_info) +{ + SAD_replaygain_mode mode; + SAD_replaygain_info info; + /*ConfigDb *db;*/ + gboolean rg_enabled; + gboolean album_mode; + SAD_dither_t *active_state; + + + if(sad_state == NULL && sad_state_from_float == NULL) { + AUDDBG("SAD not initialized!\n"); + return; + } + + rg_enabled = cfg.enable_replay_gain; + album_mode = cfg.replay_gain_album; + mode.clipping_prevention = cfg.enable_clipping_prevention; + mode.hard_limit = cfg.enable_hard_limiter; + + if(!rg_enabled) return; + + mode.mode = album_mode ? SAD_RG_ALBUM : SAD_RG_TRACK; + mode.preamp = 0.0; /*FIXME*/ + + info.present = TRUE; + info.track_gain = rg_info->track_gain; + info.track_peak = rg_info->track_peak; + info.album_gain = rg_info->album_gain; + info.album_peak = rg_info->album_peak; + + AUDDBG("Applying Replay Gain settings:\n"); + AUDDBG("* mode: %s\n", mode.mode == SAD_RG_ALBUM ? "album" : "track"); + AUDDBG("* clipping prevention: %s\n", mode.clipping_prevention ? "yes" : "no"); + AUDDBG("* hard limit: %s\n", mode.hard_limit ? "yes" : "no"); + AUDDBG("* preamp: %+f dB\n", mode.preamp); + AUDDBG("Replay Gain info for current track:\n"); + AUDDBG("* track gain: %+f dB\n", info.track_gain); + AUDDBG("* track peak: %f\n", info.track_peak); + AUDDBG("* album gain: %+f dB\n", info.album_gain); + AUDDBG("* album peak: %f\n", info.album_peak); + + active_state = sad_state != NULL ? sad_state : sad_state_from_float; + SAD_dither_apply_replaygain(active_state, &info, &mode); +} diff -r 1ab015fe2ade -r 8f6956130372 src/audacious/plugin.h --- a/src/audacious/plugin.h Thu Jan 31 21:43:51 2008 +0300 +++ b/src/audacious/plugin.h Sat Feb 02 01:53:15 2008 +0300 @@ -1080,7 +1080,8 @@ void (*pass_audio) (InputPlayback *, AFormat, gint, gint, gpointer, gint *); /* added in Audacious 1.5 */ - void (*set_replaygain_info) (InputPlayback *, ReplayGainInfo *); /* called by input plugin when RG info available --asphyx */ + /* called by input plugin when RG info available --asphyx */ + void (*set_replaygain_info) (InputPlayback *, ReplayGainInfo *); }; struct _InputPlugin { diff -r 1ab015fe2ade -r 8f6956130372 src/audacious/ui_preferences.c --- a/src/audacious/ui_preferences.c Thu Jan 31 21:43:51 2008 +0300 +++ b/src/audacious/ui_preferences.c Sat Feb 02 01:53:15 2008 +0300 @@ -127,6 +127,7 @@ static Category categories[] = { {DATA_DIR "/images/appearance.png", N_("Appearance")}, {DATA_DIR "/images/audio.png", N_("Audio")}, + {DATA_DIR "/images/replay_gain.png", N_("Replay Gain")}, {DATA_DIR "/images/connectivity.png", N_("Connectivity")}, {DATA_DIR "/images/mouse.png", N_("Mouse")}, {DATA_DIR "/images/playback.png", N_("Playback")}, @@ -218,6 +219,9 @@ N_("When checked, Audacious will detect file formats based by extension. Only files with extensions of supported formats will be loaded."), FALSE}, {WIDGET_LABEL, N_("Bit Depth"), NULL, NULL, NULL, FALSE}, {WIDGET_CUSTOM, NULL, NULL, NULL, NULL, TRUE, ui_preferences_bit_depth}, +}; + +static PreferencesWidget replay_gain_page_widgets[] = { {WIDGET_LABEL, N_("Replay Gain"), NULL, NULL, NULL, FALSE}, {WIDGET_CHK_BTN, N_("Enable Replay Gain"), &cfg.enable_replay_gain, NULL, NULL, FALSE}, {WIDGET_RADIO_BTN, N_("Use track gain/peak"), &cfg.replay_gain_track, NULL, NULL, TRUE}, @@ -1982,6 +1986,20 @@ } static void +create_replay_gain_category(void) +{ + GtkWidget *rg_page_vbox; + GtkWidget *widgets_vbox; + + rg_page_vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (category_notebook), rg_page_vbox); + + widgets_vbox = gtk_vbox_new (FALSE, 0); + create_widgets(GTK_BOX(widgets_vbox), replay_gain_page_widgets, G_N_ELEMENTS(replay_gain_page_widgets)); + gtk_box_pack_start (GTK_BOX (rg_page_vbox), widgets_vbox, TRUE, TRUE, 0); +} + +static void create_playlist_category(void) { GtkWidget *playlist_page_vbox; @@ -2997,6 +3015,7 @@ create_appearence_category(); create_audio_category(); + create_replay_gain_category(); create_connectivity_category(); create_mouse_category(); create_playback_category(); diff -r 1ab015fe2ade -r 8f6956130372 src/libSAD/dither.c --- a/src/libSAD/dither.c Thu Jan 31 21:43:51 2008 +0300 +++ b/src/libSAD/dither.c Sat Feb 02 01:53:15 2008 +0300 @@ -457,6 +457,11 @@ case SAD_RG_TRACK: scale = db2scale(rg_info->track_gain); peak = rg_info->track_peak; + if (peak == 0.0) { + scale = db2scale(rg_info->album_gain); // fallback to per-album mode + peak = rg_info->album_peak; + DEBUG_MSG("f: SAD_dither_apply_replaygain: fallback to album mode\n",0); + } break; case SAD_RG_NONE: scale = -1.0; @@ -464,7 +469,7 @@ if (scale != -1.0 && peak != 0.0) { DEBUG_MSG("f: SAD_dither_apply_replaygain: applying\n",0); - scale *= mode->preamp; + scale *= db2scale(mode->preamp); // Clipping prevention if(mode->clipping_prevention) { #ifdef DEBUG