From 3379a1748feb440c6b6292d89a5b076482bb77ff Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Tue, 5 Nov 2002 07:27:28 +0000 Subject: [PATCH] finish replaygain implementation + config tab --- src/plugin_xmms/Makefile.lite | 2 +- src/plugin_xmms/charset.c | 4 +- src/plugin_xmms/configure.c | 307 +++++++++++++++++++++++++++------- src/plugin_xmms/configure.h | 35 ++-- src/plugin_xmms/plugin.c | 98 ++++++++--- src/plugin_xmms/wrap_id3.c | 7 +- 6 files changed, 352 insertions(+), 101 deletions(-) diff --git a/src/plugin_xmms/Makefile.lite b/src/plugin_xmms/Makefile.lite index 46c8d041..cf7ab698 100644 --- a/src/plugin_xmms/Makefile.lite +++ b/src/plugin_xmms/Makefile.lite @@ -23,7 +23,7 @@ topdir = ../.. LIB_NAME = libxmms-flac INCLUDES = $(shell xmms-config --cflags) -I./include -I$(topdir)/include -I.. -LIBS = $(topdir)/obj/lib/libFLAC.a $(topdir)/obj/lib/libplugin_common.a $(HOME)/local/lib/libid3.a -lstdc++ -lz +LIBS = $(topdir)/obj/lib/libFLAC.a $(topdir)/obj/lib/libplugin_common.a $(topdir)/obj/lib/libreplaygain.a $(topdir)/obj/lib/libgain_analysis.a $(topdir)/obj/lib/libfile_utils.a $(HOME)/local/lib/libid3.a -lstdc++ -lz OBJS = \ charset.o \ diff --git a/src/plugin_xmms/charset.c b/src/plugin_xmms/charset.c index 0ad7a8cb..c27fd129 100644 --- a/src/plugin_xmms/charset.c +++ b/src/plugin_xmms/charset.c @@ -137,12 +137,12 @@ const CharsetInfo charset_trans_array[] = { */ char *convert_from_file_to_user(const char *string) { - return FLAC_plugin__charset_convert_string(string, flac_cfg.file_char_set, flac_cfg.user_char_set); + return FLAC_plugin__charset_convert_string(string, flac_cfg.title.file_char_set, flac_cfg.title.user_char_set); } char *convert_from_user_to_file(const char *string) { - return FLAC_plugin__charset_convert_string(string, flac_cfg.user_char_set, flac_cfg.file_char_set); + return FLAC_plugin__charset_convert_string(string, flac_cfg.title.user_char_set, flac_cfg.title.file_char_set); } void convert_from_file_to_user_in_place(char **string) diff --git a/src/plugin_xmms/configure.c b/src/plugin_xmms/configure.c index e47210d9..59e6fb87 100644 --- a/src/plugin_xmms/configure.c +++ b/src/plugin_xmms/configure.c @@ -42,18 +42,36 @@ * Initialize Global Valueable */ flac_config_t flac_cfg = { - FALSE, - NULL, - FALSE, - NULL, - NULL, - /* replaygain */ + /* title */ + { + FALSE, /* tag_override */ + NULL, /* tag_format */ + FALSE, /* convert_char_set */ + NULL, /* file_char_set */ + NULL /* user_char_set */ + }, + /* output */ { - FALSE, - 0, - TRUE, - TRUE, - 1 + /* replaygain */ + { + FALSE, /* enable */ + TRUE, /* album_mode */ + 0, /* preamp */ + TRUE /* hard_limit */ + }, + /* resolution */ + { + /* normal */ + { + TRUE /* dither_24_to_16 */ + }, + /* replaygain */ + { + TRUE, /* dither */ + 1, /* noise_shaping */ + 16 /* bps_out */ + } + } } }; @@ -63,15 +81,23 @@ static GtkWidget *vbox, *notebook; static GtkWidget *title_tag_override, *title_tag_box, *title_tag_entry, *title_desc; static GtkWidget *convert_char_set, *fileCharacterSetEntry, *userCharacterSetEntry; -static GtkWidget *replaygain_enable, *replaygain_preamp_hscale, *replaygain_preamp_label; +static GtkWidget *replaygain_enable, *replaygain_album_mode; +static GtkWidget *replaygain_preamp_hscale, *replaygain_preamp_label, *replaygain_hard_limit; static GtkObject *replaygain_preamp; +static GtkWidget *resolution_normal_dither_24_to_16; +static GtkWidget *resolution_replaygain_dither; +static GtkWidget *resolution_replaygain_noise_shaping_frame; +static GtkWidget *resolution_replaygain_noise_shaping_radio_none; +static GtkWidget *resolution_replaygain_noise_shaping_radio_low; +static GtkWidget *resolution_replaygain_noise_shaping_radio_medium; +static GtkWidget *resolution_replaygain_noise_shaping_radio_high; +static GtkWidget *resolution_replaygain_bps_out_frame; +static GtkWidget *resolution_replaygain_bps_out_radio_16bps; +static GtkWidget *resolution_replaygain_bps_out_radio_24bps; static gchar *gtk_entry_get_text_1 (GtkWidget *widget); static void flac_configurewin_ok(GtkWidget * widget, gpointer data); static void configure_destroy(GtkWidget * w, gpointer data); -static void title_tag_override_cb(GtkWidget * w, gpointer data); -static void convert_char_set_cb(GtkWidget * w, gpointer data); -static void replaygain_enable_cb(GtkWidget * w, gpointer data); static void flac_configurewin_ok(GtkWidget * widget, gpointer data) { @@ -79,26 +105,30 @@ static void flac_configurewin_ok(GtkWidget * widget, gpointer data) gchar *filename; (void)widget, (void)data; /* unused arguments */ - g_free(flac_cfg.tag_format); - flac_cfg.tag_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(title_tag_entry))); - flac_cfg.file_char_set = Charset_Get_Name_From_Title(gtk_entry_get_text_1(fileCharacterSetEntry)); - flac_cfg.user_char_set = Charset_Get_Name_From_Title(gtk_entry_get_text_1(userCharacterSetEntry)); + g_free(flac_cfg.title.tag_format); + flac_cfg.title.tag_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(title_tag_entry))); + flac_cfg.title.file_char_set = Charset_Get_Name_From_Title(gtk_entry_get_text_1(fileCharacterSetEntry)); + flac_cfg.title.user_char_set = Charset_Get_Name_From_Title(gtk_entry_get_text_1(userCharacterSetEntry)); filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL); cfg = xmms_cfg_open_file(filename); if (!cfg) cfg = xmms_cfg_new(); - xmms_cfg_write_boolean(cfg, "flac", "tag_override", flac_cfg.tag_override); - xmms_cfg_write_string(cfg, "flac", "tag_format", flac_cfg.tag_format); - xmms_cfg_write_boolean(cfg, "flac", "convert_char_set", flac_cfg.convert_char_set); - xmms_cfg_write_string(cfg, "flac", "file_char_set", flac_cfg.file_char_set); - xmms_cfg_write_string(cfg, "flac", "user_char_set", flac_cfg.user_char_set); - /* replaygain */ - xmms_cfg_write_boolean(cfg, "flac", "replaygain_enable", flac_cfg.replaygain.enable); - xmms_cfg_write_int(cfg, "flac", "replaygain_preamp", flac_cfg.replaygain.preamp); - xmms_cfg_write_boolean(cfg, "flac", "replaygain_hard_limit", flac_cfg.replaygain.hard_limit); - xmms_cfg_write_boolean(cfg, "flac", "replaygain_dither", flac_cfg.replaygain.dither); - xmms_cfg_write_int(cfg, "flac", "replaygain_noise_shaping", flac_cfg.replaygain.noise_shaping); + /* title */ + xmms_cfg_write_boolean(cfg, "flac", "title.tag_override", flac_cfg.title.tag_override); + xmms_cfg_write_string(cfg, "flac", "title.tag_format", flac_cfg.title.tag_format); + xmms_cfg_write_boolean(cfg, "flac", "title.convert_char_set", flac_cfg.title.convert_char_set); + xmms_cfg_write_string(cfg, "flac", "title.file_char_set", flac_cfg.title.file_char_set); + xmms_cfg_write_string(cfg, "flac", "title.user_char_set", flac_cfg.title.user_char_set); + /* output */ + xmms_cfg_write_boolean(cfg, "flac", "output.replaygain.enable", flac_cfg.output.replaygain.enable); + xmms_cfg_write_boolean(cfg, "flac", "output.replaygain.album_mode", flac_cfg.output.replaygain.album_mode); + xmms_cfg_write_int(cfg, "flac", "output.replaygain.preamp", flac_cfg.output.replaygain.preamp); + xmms_cfg_write_boolean(cfg, "flac", "output.replaygain.hard_limit", flac_cfg.output.replaygain.hard_limit); + xmms_cfg_write_boolean(cfg, "flac", "output.resolution.normal.dither_24_to_16", flac_cfg.output.resolution.normal.dither_24_to_16); + xmms_cfg_write_boolean(cfg, "flac", "output.resolution.replaygain.dither", flac_cfg.output.resolution.replaygain.dither); + xmms_cfg_write_int(cfg, "flac", "output.resolution.replaygain.noise_shaping", flac_cfg.output.resolution.replaygain.noise_shaping); + xmms_cfg_write_int(cfg, "flac", "output.resolution.replaygain.bps_out", flac_cfg.output.resolution.replaygain.bps_out); xmms_cfg_write_file(cfg, filename); xmms_cfg_free(cfg); g_free(filename); @@ -113,44 +143,98 @@ static void configure_destroy(GtkWidget *widget, gpointer data) static void title_tag_override_cb(GtkWidget *widget, gpointer data) { (void)widget, (void)data; /* unused arguments */ - flac_cfg.tag_override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(title_tag_override)); + flac_cfg.title.tag_override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(title_tag_override)); - gtk_widget_set_sensitive(title_tag_box, flac_cfg.tag_override); - gtk_widget_set_sensitive(title_desc, flac_cfg.tag_override); + gtk_widget_set_sensitive(title_tag_box, flac_cfg.title.tag_override); + gtk_widget_set_sensitive(title_desc, flac_cfg.title.tag_override); } static void convert_char_set_cb(GtkWidget *widget, gpointer data) { (void)widget, (void)data; /* unused arguments */ - flac_cfg.convert_char_set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(convert_char_set)); + flac_cfg.title.convert_char_set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(convert_char_set)); - gtk_widget_set_sensitive(fileCharacterSetEntry, flac_cfg.convert_char_set); - gtk_widget_set_sensitive(userCharacterSetEntry, flac_cfg.convert_char_set); + gtk_widget_set_sensitive(fileCharacterSetEntry, flac_cfg.title.convert_char_set); + gtk_widget_set_sensitive(userCharacterSetEntry, flac_cfg.title.convert_char_set); } static void replaygain_enable_cb(GtkWidget *widget, gpointer data) { (void)widget, (void)data; /* unused arguments */ - flac_cfg.replaygain.enable = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(replaygain_enable)); + flac_cfg.output.replaygain.enable = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(replaygain_enable)); - gtk_widget_set_sensitive(replaygain_preamp_hscale, flac_cfg.replaygain.enable); + gtk_widget_set_sensitive(replaygain_album_mode, flac_cfg.output.replaygain.enable); + gtk_widget_set_sensitive(replaygain_preamp_hscale, flac_cfg.output.replaygain.enable); + gtk_widget_set_sensitive(replaygain_hard_limit, flac_cfg.output.replaygain.enable); +} + +static void replaygain_album_mode_cb(GtkWidget *widget, gpointer data) +{ + (void)widget, (void)data; /* unused arguments */ + flac_cfg.output.replaygain.album_mode = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(replaygain_album_mode)); +} + +static void replaygain_hard_limit_cb(GtkWidget *widget, gpointer data) +{ + (void)widget, (void)data; /* unused arguments */ + flac_cfg.output.replaygain.hard_limit = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(replaygain_hard_limit)); } static void replaygain_preamp_cb(GtkWidget *widget, gpointer data) { GString *gstring = g_string_new(""); (void)widget, (void)data; /* unused arguments */ - flac_cfg.replaygain.preamp = (int) floor(GTK_ADJUSTMENT(replaygain_preamp)->value + 0.5); + flac_cfg.output.replaygain.preamp = (int) floor(GTK_ADJUSTMENT(replaygain_preamp)->value + 0.5); - g_string_sprintf(gstring, "%i dB", flac_cfg.replaygain.preamp); + g_string_sprintf(gstring, "%i dB", flac_cfg.output.replaygain.preamp); gtk_label_set_text(GTK_LABEL(replaygain_preamp_label), _(gstring->str)); } +static void resolution_normal_dither_24_to_16_cb(GtkWidget *widget, gpointer data) +{ + (void)widget, (void)data; /* unused arguments */ + flac_cfg.output.resolution.normal.dither_24_to_16 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(resolution_normal_dither_24_to_16)); +} + +static void resolution_replaygain_dither_cb(GtkWidget *widget, gpointer data) +{ + (void)widget, (void)data; /* unused arguments */ + flac_cfg.output.resolution.replaygain.dither = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(resolution_replaygain_dither)); + + gtk_widget_set_sensitive(resolution_replaygain_noise_shaping_frame, flac_cfg.output.resolution.replaygain.dither); +} + +static void resolution_replaygain_noise_shaping_cb(GtkWidget *widget, gpointer data) +{ + (void)widget, (void)data; /* unused arguments */ + flac_cfg.output.resolution.replaygain.noise_shaping = + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(resolution_replaygain_noise_shaping_radio_none))? 0 : + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(resolution_replaygain_noise_shaping_radio_low))? 1 : + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(resolution_replaygain_noise_shaping_radio_medium))? 2 : + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(resolution_replaygain_noise_shaping_radio_high))? 3 : + 0 + ; +} + +static void resolution_replaygain_bps_out_cb(GtkWidget *widget, gpointer data) +{ + (void)widget, (void)data; /* unused arguments */ + flac_cfg.output.resolution.replaygain.bps_out = + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(resolution_replaygain_bps_out_radio_16bps))? 16 : + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(resolution_replaygain_bps_out_radio_24bps))? 24 : + 16 + ; +} + + void FLAC_XMMS__configure(void) { GtkWidget *title_frame, *title_tag_vbox, *title_tag_label; - GtkWidget *replaygain_frame, *replaygain_vbox; + GtkWidget *replaygain_frame, *resolution_frame, *output_vbox, *resolution_normal_frame, *resolution_replaygain_frame; + GtkWidget *replaygain_vbox, *resolution_hbox, *resolution_normal_vbox, *resolution_replaygain_vbox; + GtkWidget *resolution_replaygain_noise_shaping_vbox; + GtkWidget *resolution_replaygain_bps_out_vbox; GtkWidget *label, *hbox; GtkWidget *bbox, *ok, *cancel; GList *list; @@ -184,7 +268,7 @@ void FLAC_XMMS__configure(void) /* Convert Char Set */ convert_char_set = gtk_check_button_new_with_label(_("Convert Character Set")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(convert_char_set), flac_cfg.convert_char_set); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(convert_char_set), flac_cfg.title.convert_char_set); gtk_signal_connect(GTK_OBJECT(convert_char_set), "clicked", convert_char_set_cb, NULL); gtk_box_pack_start(GTK_BOX(title_tag_vbox), convert_char_set, FALSE, FALSE, 0); /* Combo boxes... */ @@ -208,65 +292,174 @@ void FLAC_XMMS__configure(void) list = Charset_Create_List(); gtk_combo_set_popdown_strings(GTK_COMBO(fileCharacterSetEntry),list); gtk_combo_set_popdown_strings(GTK_COMBO(userCharacterSetEntry),list); - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(fileCharacterSetEntry)->entry),Charset_Get_Title_From_Name(flac_cfg.file_char_set)); - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(userCharacterSetEntry)->entry),Charset_Get_Title_From_Name(flac_cfg.user_char_set)); - gtk_widget_set_sensitive(fileCharacterSetEntry, flac_cfg.convert_char_set); - gtk_widget_set_sensitive(userCharacterSetEntry, flac_cfg.convert_char_set); + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(fileCharacterSetEntry)->entry),Charset_Get_Title_From_Name(flac_cfg.title.file_char_set)); + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(userCharacterSetEntry)->entry),Charset_Get_Title_From_Name(flac_cfg.title.user_char_set)); + gtk_widget_set_sensitive(fileCharacterSetEntry, flac_cfg.title.convert_char_set); + gtk_widget_set_sensitive(userCharacterSetEntry, flac_cfg.title.convert_char_set); /* Override Tagging Format */ title_tag_override = gtk_check_button_new_with_label(_("Override generic titles")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(title_tag_override), flac_cfg.tag_override); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(title_tag_override), flac_cfg.title.tag_override); gtk_signal_connect(GTK_OBJECT(title_tag_override), "clicked", title_tag_override_cb, NULL); gtk_box_pack_start(GTK_BOX(title_tag_vbox), title_tag_override, FALSE, FALSE, 0); title_tag_box = gtk_hbox_new(FALSE, 5); - gtk_widget_set_sensitive(title_tag_box, flac_cfg.tag_override); + gtk_widget_set_sensitive(title_tag_box, flac_cfg.title.tag_override); gtk_box_pack_start(GTK_BOX(title_tag_vbox), title_tag_box, FALSE, FALSE, 0); title_tag_label = gtk_label_new(_("Title format:")); gtk_box_pack_start(GTK_BOX(title_tag_box), title_tag_label, FALSE, FALSE, 0); title_tag_entry = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(title_tag_entry), flac_cfg.tag_format); + gtk_entry_set_text(GTK_ENTRY(title_tag_entry), flac_cfg.title.tag_format); gtk_box_pack_start(GTK_BOX(title_tag_box), title_tag_entry, TRUE, TRUE, 0); title_desc = xmms_titlestring_descriptions("pafFetnygc", 2); - gtk_widget_set_sensitive(title_desc, flac_cfg.tag_override); + gtk_widget_set_sensitive(title_desc, flac_cfg.title.tag_override); gtk_box_pack_start(GTK_BOX(title_tag_vbox), title_desc, FALSE, FALSE, 0); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), title_frame, gtk_label_new(_("Title"))); - /* ReplayGain config.. */ + /* Output config.. */ + + output_vbox = gtk_vbox_new(FALSE, 10); + gtk_container_border_width(GTK_CONTAINER(output_vbox), 5); + + /* replaygain */ replaygain_frame = gtk_frame_new(_("ReplayGain")); gtk_container_border_width(GTK_CONTAINER(replaygain_frame), 5); + gtk_box_pack_start(GTK_BOX(output_vbox), replaygain_frame, TRUE, TRUE, 0); replaygain_vbox = gtk_vbox_new(FALSE, 10); gtk_container_border_width(GTK_CONTAINER(replaygain_vbox), 5); gtk_container_add(GTK_CONTAINER(replaygain_frame), replaygain_vbox); - /* Preamp */ - replaygain_enable = gtk_check_button_new_with_label(_("Enable ReplayGain processing")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(replaygain_enable), flac_cfg.replaygain.enable); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(replaygain_enable), flac_cfg.output.replaygain.enable); gtk_signal_connect(GTK_OBJECT(replaygain_enable), "clicked", replaygain_enable_cb, NULL); gtk_box_pack_start(GTK_BOX(replaygain_vbox), replaygain_enable, FALSE, FALSE, 0); + replaygain_album_mode = gtk_check_button_new_with_label(_("Album mode")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(replaygain_album_mode), flac_cfg.output.replaygain.album_mode); + gtk_signal_connect(GTK_OBJECT(replaygain_album_mode), "clicked", replaygain_album_mode_cb, NULL); + gtk_box_pack_start(GTK_BOX(replaygain_vbox), replaygain_album_mode, FALSE, FALSE, 0); + hbox = gtk_hbox_new(FALSE,3); gtk_container_add(GTK_CONTAINER(replaygain_vbox),hbox); label = gtk_label_new(_("Preamp:")); gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0); - replaygain_preamp = gtk_adjustment_new(flac_cfg.replaygain.preamp, -24.0, +24.0, 1.0, 6.0, 6.0); + replaygain_preamp = gtk_adjustment_new(flac_cfg.output.replaygain.preamp, -24.0, +24.0, 1.0, 6.0, 6.0); gtk_signal_connect(GTK_OBJECT(replaygain_preamp), "value-changed", replaygain_preamp_cb, NULL); replaygain_preamp_hscale = gtk_hscale_new(GTK_ADJUSTMENT(replaygain_preamp)); - gtk_widget_set_sensitive(replaygain_preamp_hscale, flac_cfg.replaygain.enable); gtk_box_pack_start(GTK_BOX(hbox),replaygain_preamp_hscale,TRUE,TRUE,0); replaygain_preamp_label = gtk_label_new(_("0 dB")); gtk_box_pack_start(GTK_BOX(hbox),replaygain_preamp_label,FALSE,FALSE,0); gtk_adjustment_value_changed(GTK_ADJUSTMENT(replaygain_preamp)); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), replaygain_frame, gtk_label_new(_("ReplayGain"))); + replaygain_hard_limit = gtk_check_button_new_with_label(_("6dB hard limiting")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(replaygain_hard_limit), flac_cfg.output.replaygain.hard_limit); + gtk_signal_connect(GTK_OBJECT(replaygain_hard_limit), "clicked", replaygain_hard_limit_cb, NULL); + gtk_box_pack_start(GTK_BOX(replaygain_vbox), replaygain_hard_limit, FALSE, FALSE, 0); + + replaygain_enable_cb(replaygain_enable, NULL); + + /* resolution */ + + resolution_frame = gtk_frame_new(_("Resolution")); + gtk_container_border_width(GTK_CONTAINER(resolution_frame), 5); + gtk_box_pack_start(GTK_BOX(output_vbox), resolution_frame, TRUE, TRUE, 0); + + resolution_hbox = gtk_hbox_new(FALSE, 10); + gtk_container_border_width(GTK_CONTAINER(resolution_hbox), 5); + gtk_container_add(GTK_CONTAINER(resolution_frame), resolution_hbox); + + resolution_normal_frame = gtk_frame_new(_("Without ReplayGain")); + gtk_container_border_width(GTK_CONTAINER(resolution_normal_frame), 5); + gtk_box_pack_start(GTK_BOX(resolution_hbox), resolution_normal_frame, TRUE, TRUE, 0); + + resolution_normal_vbox = gtk_vbox_new(FALSE, 10); + gtk_container_border_width(GTK_CONTAINER(resolution_normal_vbox), 5); + gtk_container_add(GTK_CONTAINER(resolution_normal_frame), resolution_normal_vbox); + + resolution_normal_dither_24_to_16 = gtk_check_button_new_with_label(_("Dither 24bps to 16bps")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(resolution_normal_dither_24_to_16), flac_cfg.output.resolution.normal.dither_24_to_16); + gtk_signal_connect(GTK_OBJECT(resolution_normal_dither_24_to_16), "clicked", resolution_normal_dither_24_to_16_cb, NULL); + gtk_box_pack_start(GTK_BOX(resolution_normal_vbox), resolution_normal_dither_24_to_16, FALSE, FALSE, 0); + + resolution_replaygain_frame = gtk_frame_new(_("With ReplayGain")); + gtk_container_border_width(GTK_CONTAINER(resolution_replaygain_frame), 5); + gtk_box_pack_start(GTK_BOX(resolution_hbox), resolution_replaygain_frame, TRUE, TRUE, 0); + + resolution_replaygain_vbox = gtk_vbox_new(FALSE, 10); + gtk_container_border_width(GTK_CONTAINER(resolution_replaygain_vbox), 5); + gtk_container_add(GTK_CONTAINER(resolution_replaygain_frame), resolution_replaygain_vbox); + + resolution_replaygain_dither = gtk_check_button_new_with_label(_("Enable dithering")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(resolution_replaygain_dither), flac_cfg.output.resolution.replaygain.dither); + gtk_signal_connect(GTK_OBJECT(resolution_replaygain_dither), "clicked", resolution_replaygain_dither_cb, NULL); + gtk_box_pack_start(GTK_BOX(resolution_replaygain_vbox), resolution_replaygain_dither, FALSE, FALSE, 0); + + hbox = gtk_hbox_new(FALSE, 10); + gtk_container_border_width(GTK_CONTAINER(hbox), 5); + gtk_box_pack_start(GTK_BOX(resolution_replaygain_vbox), hbox, TRUE, TRUE, 0); + + resolution_replaygain_noise_shaping_frame = gtk_frame_new(_("Noise shaping")); + gtk_container_border_width(GTK_CONTAINER(resolution_replaygain_noise_shaping_frame), 5); + gtk_box_pack_start(GTK_BOX(hbox), resolution_replaygain_noise_shaping_frame, TRUE, TRUE, 0); + + resolution_replaygain_noise_shaping_vbox = gtk_vbutton_box_new(); + gtk_container_border_width(GTK_CONTAINER(resolution_replaygain_noise_shaping_vbox), 5); + gtk_container_add(GTK_CONTAINER(resolution_replaygain_noise_shaping_frame), resolution_replaygain_noise_shaping_vbox); + + resolution_replaygain_noise_shaping_radio_none = gtk_radio_button_new_with_label(NULL, _("none")); + if(flac_cfg.output.resolution.replaygain.noise_shaping == 0) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(resolution_replaygain_noise_shaping_radio_none), TRUE); + gtk_signal_connect(GTK_OBJECT(resolution_replaygain_noise_shaping_radio_none), "clicked", resolution_replaygain_noise_shaping_cb, NULL); + gtk_container_add(GTK_CONTAINER(resolution_replaygain_noise_shaping_vbox), resolution_replaygain_noise_shaping_radio_none); + + resolution_replaygain_noise_shaping_radio_low = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(resolution_replaygain_noise_shaping_radio_none), _("low")); + if(flac_cfg.output.resolution.replaygain.noise_shaping == 1) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(resolution_replaygain_noise_shaping_radio_low), TRUE); + gtk_signal_connect(GTK_OBJECT(resolution_replaygain_noise_shaping_radio_low), "clicked", resolution_replaygain_noise_shaping_cb, NULL); + gtk_container_add(GTK_CONTAINER(resolution_replaygain_noise_shaping_vbox), resolution_replaygain_noise_shaping_radio_low); + + resolution_replaygain_noise_shaping_radio_medium = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(resolution_replaygain_noise_shaping_radio_none), _("medium")); + if(flac_cfg.output.resolution.replaygain.noise_shaping == 2) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(resolution_replaygain_noise_shaping_radio_medium), TRUE); + gtk_signal_connect(GTK_OBJECT(resolution_replaygain_noise_shaping_radio_medium), "clicked", resolution_replaygain_noise_shaping_cb, NULL); + gtk_container_add(GTK_CONTAINER(resolution_replaygain_noise_shaping_vbox), resolution_replaygain_noise_shaping_radio_medium); + + resolution_replaygain_noise_shaping_radio_high = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(resolution_replaygain_noise_shaping_radio_none), _("high")); + if(flac_cfg.output.resolution.replaygain.noise_shaping == 3) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(resolution_replaygain_noise_shaping_radio_high), TRUE); + gtk_signal_connect(GTK_OBJECT(resolution_replaygain_noise_shaping_radio_high), "clicked", resolution_replaygain_noise_shaping_cb, NULL); + gtk_container_add(GTK_CONTAINER(resolution_replaygain_noise_shaping_vbox), resolution_replaygain_noise_shaping_radio_high); + + resolution_replaygain_bps_out_frame = gtk_frame_new(_("Dither to")); + gtk_container_border_width(GTK_CONTAINER(resolution_replaygain_bps_out_frame), 5); + gtk_box_pack_start(GTK_BOX(hbox), resolution_replaygain_bps_out_frame, FALSE, FALSE, 0); + + resolution_replaygain_bps_out_vbox = gtk_vbutton_box_new(); + gtk_container_border_width(GTK_CONTAINER(resolution_replaygain_bps_out_vbox), 0); + gtk_container_add(GTK_CONTAINER(resolution_replaygain_bps_out_frame), resolution_replaygain_bps_out_vbox); + + resolution_replaygain_bps_out_radio_16bps = gtk_radio_button_new_with_label(NULL, _("16 bps")); + if(flac_cfg.output.resolution.replaygain.bps_out == 16) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(resolution_replaygain_bps_out_radio_16bps), TRUE); + gtk_signal_connect(GTK_OBJECT(resolution_replaygain_bps_out_radio_16bps), "clicked", resolution_replaygain_bps_out_cb, NULL); + gtk_container_add(GTK_CONTAINER(resolution_replaygain_bps_out_vbox), resolution_replaygain_bps_out_radio_16bps); + + resolution_replaygain_bps_out_radio_24bps = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(resolution_replaygain_bps_out_radio_16bps), _("24 bps")); + if(flac_cfg.output.resolution.replaygain.bps_out == 24) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(resolution_replaygain_bps_out_radio_24bps), TRUE); + gtk_signal_connect(GTK_OBJECT(resolution_replaygain_bps_out_radio_24bps), "clicked", resolution_replaygain_bps_out_cb, NULL); + gtk_container_add(GTK_CONTAINER(resolution_replaygain_bps_out_vbox), resolution_replaygain_bps_out_radio_24bps); + + resolution_replaygain_dither_cb(resolution_replaygain_dither, NULL); + + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), output_vbox, gtk_label_new(_("Output"))); /* Buttons */ diff --git a/src/plugin_xmms/configure.h b/src/plugin_xmms/configure.h index 6128921a..77143716 100644 --- a/src/plugin_xmms/configure.h +++ b/src/plugin_xmms/configure.h @@ -24,19 +24,32 @@ #include typedef struct { - gboolean tag_override; - gchar *tag_format; - gboolean convert_char_set; - gchar *file_char_set; - gchar *user_char_set; + struct { + gboolean tag_override; + gchar *tag_format; + gboolean convert_char_set; + gchar *file_char_set; + gchar *user_char_set; + } title; struct { - gboolean enable; - gint preamp; - gboolean hard_limit; - gboolean dither; - guint noise_shaping; /* value must be one of NoiseShaping enum, c.f. plugin_common/replaygain_synthesis.h */ - } replaygain; + struct { + gboolean enable; + gboolean album_mode; + gint preamp; + gboolean hard_limit; + } replaygain; + struct { + struct { + gboolean dither_24_to_16; + } normal; + struct { + gboolean dither; + gint noise_shaping; /* value must be one of NoiseShaping enum, c.f. plugin_common/replaygain_synthesis.h */ + gint bps_out; + } replaygain; + } resolution; + } output; } flac_config_t; extern flac_config_t flac_cfg; diff --git a/src/plugin_xmms/plugin.c b/src/plugin_xmms/plugin.c index 168faf19..3d26891f 100644 --- a/src/plugin_xmms/plugin.c +++ b/src/plugin_xmms/plugin.c @@ -37,6 +37,7 @@ #include "FLAC/all.h" #include "plugin_common/all.h" +#include "share/replaygain.h" #include "configure.h" #include "wrap_id3.h" #include "charset.h" @@ -46,7 +47,6 @@ #endif #define min(x,y) ((x)<(y)?(x):(y)) -#define FLAC__DO_DITHER typedef struct { FLAC__bool abort_flag; @@ -60,6 +60,9 @@ typedef struct { unsigned length_in_msec; AFormat sample_format; int seek_to_in_sec; + FLAC__bool has_replaygain; + double replay_scale; + DitherContext dither_context; } file_info_struct; static void FLAC_XMMS__init(); @@ -127,38 +130,46 @@ void FLAC_XMMS__init() { ConfigFile *cfg; - flac_cfg.tag_override = FALSE; - g_free(flac_cfg.tag_format); - flac_cfg.convert_char_set = FALSE; + flac_cfg.title.tag_override = FALSE; + g_free(flac_cfg.title.tag_format); + flac_cfg.title.convert_char_set = FALSE; cfg = xmms_cfg_open_default_file(); - xmms_cfg_read_boolean(cfg, "flac", "tag_override", &flac_cfg.tag_override); + /* title */ - if(!xmms_cfg_read_string(cfg, "flac", "tag_format", &flac_cfg.tag_format)) - flac_cfg.tag_format = g_strdup("%p - %t"); + xmms_cfg_read_boolean(cfg, "flac", "title.tag_override", &flac_cfg.title.tag_override); - xmms_cfg_read_boolean(cfg, "flac", "convert_char_set", &flac_cfg.convert_char_set); + if(!xmms_cfg_read_string(cfg, "flac", "title.tag_format", &flac_cfg.title.tag_format)) + flac_cfg.title.tag_format = g_strdup("%p - %t"); - if(!xmms_cfg_read_string(cfg, "flac", "file_char_set", &flac_cfg.file_char_set)) - flac_cfg.file_char_set = FLAC_plugin__charset_get_current(); + xmms_cfg_read_boolean(cfg, "flac", "title.convert_char_set", &flac_cfg.title.convert_char_set); - if(!xmms_cfg_read_string(cfg, "flac", "user_char_set", &flac_cfg.user_char_set)) - flac_cfg.user_char_set = FLAC_plugin__charset_get_current(); + if(!xmms_cfg_read_string(cfg, "flac", "title.file_char_set", &flac_cfg.title.file_char_set)) + flac_cfg.title.file_char_set = FLAC_plugin__charset_get_current(); + + if(!xmms_cfg_read_string(cfg, "flac", "title.user_char_set", &flac_cfg.title.user_char_set)) + flac_cfg.title.user_char_set = FLAC_plugin__charset_get_current(); /* replaygain */ - xmms_cfg_read_boolean(cfg, "flac", "replaygain_enable", &flac_cfg.replaygain.enable); + xmms_cfg_read_boolean(cfg, "flac", "output.replaygain.enable", &flac_cfg.output.replaygain.enable); + + xmms_cfg_read_boolean(cfg, "flac", "output.replaygain.album_mode", &flac_cfg.output.replaygain.album_mode); + + if(!xmms_cfg_read_int(cfg, "flac", "output.replaygain.preamp", &flac_cfg.output.replaygain.preamp)) + flac_cfg.output.replaygain.preamp = 0; - if(!xmms_cfg_read_int(cfg, "flac", "replaygain_preamp", &flac_cfg.replaygain.preamp)) - flac_cfg.replaygain.preamp = 0; + xmms_cfg_read_boolean(cfg, "flac", "output.replaygain.hard_limit", &flac_cfg.output.replaygain.hard_limit); - xmms_cfg_read_boolean(cfg, "flac", "replaygain_hard_limit", &flac_cfg.replaygain.hard_limit); + xmms_cfg_read_boolean(cfg, "flac", "output.resolution.normal.dither_24_to_16", &flac_cfg.output.resolution.normal.dither_24_to_16); + xmms_cfg_read_boolean(cfg, "flac", "output.resolution.replaygain.dither", &flac_cfg.output.resolution.replaygain.dither); - xmms_cfg_read_boolean(cfg, "flac", "replaygain_dither", &flac_cfg.replaygain.dither); + if(!xmms_cfg_read_int(cfg, "flac", "output.resolution.replaygain.noise_shaping", &flac_cfg.output.resolution.replaygain.noise_shaping)) + flac_cfg.output.resolution.replaygain.noise_shaping = 1; - if(!xmms_cfg_read_int(cfg, "flac", "replaygain_noise_shaping", &flac_cfg.replaygain.noise_shaping)) - flac_cfg.replaygain.noise_shaping = 1; + if(!xmms_cfg_read_int(cfg, "flac", "output.resolution.replaygain.bps_out", &flac_cfg.output.resolution.replaygain.bps_out)) + flac_cfg.output.resolution.replaygain.bps_out = 16; decoder_ = FLAC__file_decoder_new(); } @@ -185,6 +196,7 @@ void FLAC_XMMS__play_file(char *filename) file_info_.is_playing = false; file_info_.eof = false; file_info_.play_thread_open = false; + file_info_.has_replaygain = false; if(0 == (f = fopen(filename, "r"))) return; @@ -196,6 +208,9 @@ void FLAC_XMMS__play_file(char *filename) if(!safe_decoder_init_(filename, decoder_)) return; + if(file_info_.has_replaygain && flac_cfg.output.replaygain.enable && flac_cfg.output.resolution.replaygain.dither) + FLAC__plugin_common__init_dither_context(&file_info_.dither_context, file_info_.bits_per_sample, flac_cfg.output.resolution.replaygain.noise_shaping); + file_info_.is_playing = true; if(flac_ip.output->open_audio(file_info_.sample_format, file_info_.sample_rate, file_info_.channels) == 0) { @@ -308,16 +323,39 @@ void *play_loop_(void *arg) if(wide_samples_in_reservoir_ > 0) { const unsigned channels = file_info_.channels; const unsigned bits_per_sample = file_info_.bits_per_sample; -#ifdef FLAC__DO_DITHER - const unsigned target_bps = min(bits_per_sample, 16); -#else - const unsigned target_bps = bits_per_sample; -#endif const unsigned n = min(wide_samples_in_reservoir_, SAMPLES_PER_WRITE); const unsigned delta = n * channels; - int bytes = (int)FLAC__plugin_common__pack_pcm_signed_little_endian(sample_buffer_, reservoir_, n, channels, bits_per_sample, target_bps); + int bytes; unsigned i; + if(flac_cfg.output.replaygain.enable && file_info_.has_replaygain) { + bytes = (int)FLAC__plugin_common__apply_gain( + sample_buffer_, + reservoir_, + n, + channels, + bits_per_sample, + flac_cfg.output.resolution.replaygain.bps_out, + file_info_.replay_scale, + flac_cfg.output.replaygain.hard_limit, + flac_cfg.output.resolution.replaygain.dither, + (NoiseShaping)flac_cfg.output.resolution.replaygain.noise_shaping, + &file_info_.dither_context + ); + } + else { + bytes = (int)FLAC__plugin_common__pack_pcm_signed_little_endian( + sample_buffer_, + reservoir_, + n, + channels, + bits_per_sample, + flac_cfg.output.resolution.normal.dither_24_to_16? + min(bits_per_sample, 16) : + bits_per_sample + ); + } + for(i = delta; i < wide_samples_in_reservoir_ * channels; i++) reservoir_[i-delta] = reservoir_[i]; wide_samples_in_reservoir_ -= n; @@ -366,6 +404,9 @@ FLAC__bool safe_decoder_init_(const char *filename, FLAC__FileDecoder *decoder) FLAC__file_decoder_set_md5_checking(decoder, false); FLAC__file_decoder_set_filename(decoder, filename); + FLAC__file_decoder_set_metadata_ignore_all(decoder); + FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO); + FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__file_decoder_set_write_callback(decoder, write_callback_); FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_); FLAC__file_decoder_set_error_callback(decoder, error_callback_); @@ -451,6 +492,13 @@ void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMeta #endif file_info->length_in_msec = file_info->total_samples * 10 / (file_info->sample_rate / 100); } + else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { + double gain, peak; + if(FLAC__replaygain_load_from_vorbiscomment(metadata, flac_cfg.output.replaygain.album_mode, &gain, &peak)) { + file_info_.has_replaygain = true; + file_info_.replay_scale = FLAC__replaygain_compute_scale_factor(peak, gain, (double)flac_cfg.output.replaygain.preamp, /*prevent_clipping=*/true); + } + } } void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) diff --git a/src/plugin_xmms/wrap_id3.c b/src/plugin_xmms/wrap_id3.c index c5a0ef90..e6bc12ea 100644 --- a/src/plugin_xmms/wrap_id3.c +++ b/src/plugin_xmms/wrap_id3.c @@ -82,7 +82,7 @@ char *flac_format_song_title(char *filename) FLAC_plugin__canonical_tag_get_combined(filename, &tag); - if(flac_cfg.convert_char_set) { + if(flac_cfg.title.convert_char_set) { convert_from_file_to_user_in_place(&tag.title); convert_from_file_to_user_in_place(&tag.composer); convert_from_file_to_user_in_place(&tag.performer); @@ -108,10 +108,7 @@ char *flac_format_song_title(char *filename) input->file_name = g_basename(filename); input->file_path = filename; input->file_ext = local__extname(filename); - ret = xmms_get_titlestring(flac_cfg.tag_override ? flac_cfg.tag_format : xmms_get_gentitle_format(), input); -fprintf(stderr,"@@@@ override=%c\n",flac_cfg.tag_override?'y':'n'); -fprintf(stderr,"@@@@ fmt=%s\n",flac_cfg.tag_override ? flac_cfg.tag_format : xmms_get_gentitle_format()); -fprintf(stderr,"@@@@ ret=%s\n",ret); + ret = xmms_get_titlestring(flac_cfg.title.tag_override ? flac_cfg.title.tag_format : xmms_get_gentitle_format(), input); g_free(input); if (!ret) { -- 2.34.1