# HG changeset patch # User nenolod # Date 1161891705 25200 # Node ID 46730e83b1e274be9f5879449052f12414c483e7 # Parent 29857e91c6d506d3d7ec14194e18ef3485143551 [svn] - echo plugin support by Christian Birchinger diff -r 29857e91c6d5 -r 46730e83b1e2 ChangeLog --- a/ChangeLog Thu Oct 26 12:10:32 2006 -0700 +++ b/ChangeLog Thu Oct 26 12:41:45 2006 -0700 @@ -1,3 +1,11 @@ +2006-10-26 19:10:32 +0000 William Pitcock + revision [252] + - xmms-a52dec -> 'AC-3 / A52 Decoding Plugin' + + trunk/src/a52dec/a52dec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + + 2006-10-26 18:35:49 +0000 William Pitcock revision [250] - re-enable extra stereo plugin build diff -r 29857e91c6d5 -r 46730e83b1e2 configure.ac --- a/configure.ac Thu Oct 26 12:10:32 2006 -0700 +++ b/configure.ac Thu Oct 26 12:41:45 2006 -0700 @@ -87,7 +87,7 @@ INPUT_PLUGINS="tonegen console sexypsf wav cue alac" OUTPUT_PLUGINS="disk_writer" -EFFECT_PLUGINS="audiocompress ladspa voice_removal stereo_plugin" +EFFECT_PLUGINS="audiocompress ladspa voice_removal stereo_plugin echo_plugin" GENERAL_PLUGINS="song_change alarm" VISUALIZATION_PLUGINS="blur_scope" CONTAINER_PLUGINS="m3u pls" @@ -1143,6 +1143,7 @@ echo " LADSPA effects host (ladspa): yes" echo " Voice Removal: yes" echo " Extra Stereo: yes" +echo " Echo/Surround: yes" echo echo " Visualization" echo " -------------" diff -r 29857e91c6d5 -r 46730e83b1e2 src/echo_plugin/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/echo_plugin/Makefile Thu Oct 26 12:41:45 2006 -0700 @@ -0,0 +1,16 @@ +include ../../mk/rules.mk +include ../../mk/init.mk + +OBJECTIVE_LIBS = libecho$(SHARED_SUFFIX) + +LIBDIR = $(plugindir)/$(EFFECT_PLUGIN_DIR) + +LIBADD = $(GTK_LIBS) + +SOURCES = echo.c gui.c + +CFLAGS += $(PICFLAGS) $(GTK_CFLAGS) -I../../intl -I../.. + +OBJECTS = ${SOURCES:.c=.o} + +include ../../mk/objective.mk diff -r 29857e91c6d5 -r 46730e83b1e2 src/echo_plugin/echo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/echo_plugin/echo.c Thu Oct 26 12:41:45 2006 -0700 @@ -0,0 +1,124 @@ +#include + +#include +#include +#include +#include +#include +#include "audacious/configdb.h" +#include "echo.h" + +#include "../../config.h" + +static void init(void); +static void cleanup(void); +static int mod_samples(gpointer * d, gint length, AFormat afmt, gint srate, gint nch); + +#define MAX_SRATE 50000 +#define MAX_CHANNELS 2 +#define BYTES_PS 2 +#define BUFFER_SAMPLES (MAX_SRATE * MAX_DELAY / 1000) +#define BUFFER_SHORTS (BUFFER_SAMPLES * MAX_CHANNELS) +#define BUFFER_BYTES (BUFFER_SHORTS * BYTES_PS) + +EffectPlugin echo_ep = +{ + NULL, + NULL, + NULL, /* Description */ + init, + cleanup, + echo_about, + echo_configure, + mod_samples, + NULL +}; + +static gint16 *buffer = NULL; +gint echo_delay = 500, echo_feedback = 50, echo_volume = 50; +gboolean echo_surround_enable = FALSE; +static int w_ofs; + +EffectPlugin *get_eplugin_info(void) +{ + echo_ep.description = g_strdup_printf(_("Echo Plugin %s"), VERSION); + return &echo_ep; +} + +static void init(void) +{ + ConfigDb *cfg; + + if (sizeof(short) != sizeof(gint16)) + abort(); + + cfg = bmp_cfg_db_open(); + bmp_cfg_db_get_int(cfg, "echo_plugin", "delay", &echo_delay); + bmp_cfg_db_get_int(cfg, "echo_plugin", "feedback", &echo_feedback); + bmp_cfg_db_get_int(cfg, "echo_plugin", "volume", &echo_volume); + bmp_cfg_db_get_bool(cfg, "echo_plugin", "enable_surround", &echo_surround_enable); + bmp_cfg_db_close(cfg); +} + +static void cleanup(void) +{ + g_free(buffer); + buffer = NULL; +} + +static int mod_samples(gpointer * d, gint length, AFormat afmt, gint srate, gint nch) +{ + gint i, in, out, buf, r_ofs, fb_div; + gint16 *data = (gint16 *) * d; + static gint old_srate, old_nch; + + if (!(afmt == FMT_S16_NE || + (afmt == FMT_S16_LE && G_BYTE_ORDER == G_LITTLE_ENDIAN) || + (afmt == FMT_S16_BE && G_BYTE_ORDER == G_BIG_ENDIAN))) + return length; + + if (!buffer) + buffer = g_malloc0(BUFFER_BYTES + 2); + + if (nch != old_nch || srate != old_srate) + { + memset(buffer, 0, BUFFER_BYTES); + w_ofs = 0; + old_nch = nch; + old_srate = srate; + } + + if (echo_surround_enable && nch == 2) + fb_div = 200; + else + fb_div = 100; + + r_ofs = w_ofs - (srate * echo_delay / 1000) * nch; + if (r_ofs < 0) + r_ofs += BUFFER_SHORTS; + + for (i = 0; i < length / BYTES_PS; i++) + { + in = data[i]; + buf = buffer[r_ofs]; + if (echo_surround_enable && nch == 2) + { + if (i & 1) + buf -= buffer[r_ofs - 1]; + else + buf -= buffer[r_ofs + 1]; + } + out = in + buf * echo_volume / 100; + buf = in + buf * echo_feedback / fb_div; + out = CLAMP(out, -32768, 32767); + buf = CLAMP(buf, -32768, 32767); + buffer[w_ofs] = buf; + data[i] = out; + if (++r_ofs >= BUFFER_SHORTS) + r_ofs -= BUFFER_SHORTS; + if (++w_ofs >= BUFFER_SHORTS) + w_ofs -= BUFFER_SHORTS; + } + + return length; +} diff -r 29857e91c6d5 -r 46730e83b1e2 src/echo_plugin/echo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/echo_plugin/echo.h Thu Oct 26 12:41:45 2006 -0700 @@ -0,0 +1,15 @@ +#ifndef ECHO_H +#define ECHO_H + +#include + +#define MAX_DELAY 1000 + +void echo_about(void); +void echo_configure(void); + +extern gint echo_delay, echo_feedback, echo_volume; +extern gboolean echo_surround_enable; + + +#endif diff -r 29857e91c6d5 -r 46730e83b1e2 src/echo_plugin/gui.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/echo_plugin/gui.c Thu Oct 26 12:41:45 2006 -0700 @@ -0,0 +1,158 @@ +#include +#include +#include "audacious/util.h" +#include "audacious/configdb.h" +#include "echo.h" + +static const char *echo_about_text = +N_("Echo Plugin\n" + "By Johan Levin 1999.\n\n" + "Surround echo by Carl van Schaik 1999"); + +static GtkWidget *conf_dialog = NULL, *surround_btn; +static GtkObject *echo_delay_adj, *echo_feedback_adj, *echo_volume_adj; + +void echo_about(void) +{ + static GtkWidget *echo_about_dialog = NULL; + + if (echo_about_dialog != NULL) + return; + + echo_about_dialog = xmms_show_message(_("About Echo Plugin"), + _(echo_about_text), _("Ok"), + FALSE, NULL, NULL); + gtk_signal_connect(GTK_OBJECT(echo_about_dialog), "destroy", + GTK_SIGNAL_FUNC(gtk_widget_destroyed), + &echo_about_dialog); +} + +static void apply_changes(void) +{ + ConfigDb *cfg; + echo_delay = GTK_ADJUSTMENT(echo_delay_adj)->value; + echo_feedback = GTK_ADJUSTMENT(echo_feedback_adj)->value; + echo_volume = GTK_ADJUSTMENT(echo_volume_adj)->value; + echo_surround_enable = + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(surround_btn)); + + cfg = bmp_cfg_db_open(); + bmp_cfg_db_set_int(cfg, "echo_plugin", "delay", echo_delay); + bmp_cfg_db_set_int(cfg, "echo_plugin", "feedback", echo_feedback); + bmp_cfg_db_set_int(cfg, "echo_plugin", "volume", echo_volume); + bmp_cfg_db_set_bool(cfg, "echo_plugin", "enable_surround", echo_surround_enable); + bmp_cfg_db_close(cfg); +} + +static void conf_ok_cb(GtkButton * button, gpointer data) +{ + apply_changes(); + gtk_widget_destroy(GTK_WIDGET(conf_dialog)); +} + +static void conf_cancel_cb(GtkButton * button, gpointer data) +{ + gtk_widget_destroy(GTK_WIDGET(conf_dialog)); +} + +static void conf_apply_cb(GtkButton * button, gpointer data) +{ + apply_changes(); +} + +void echo_configure(void) +{ + GtkWidget *button, *table, *label, *hscale, *bbox; + + if (conf_dialog != NULL) + return; + + conf_dialog = gtk_dialog_new(); + gtk_signal_connect(GTK_OBJECT(conf_dialog), "destroy", + GTK_SIGNAL_FUNC(gtk_widget_destroyed), &conf_dialog); + gtk_window_set_title(GTK_WINDOW(conf_dialog), _("Configure Echo")); + + echo_delay_adj = gtk_adjustment_new(echo_delay, 0, MAX_DELAY + 100, 10, 100, 100); + echo_feedback_adj = gtk_adjustment_new(echo_feedback, 0, 100 + 10, 2, 10, 10); + echo_volume_adj = gtk_adjustment_new(echo_volume, 0, 100 + 10, 2, 10, 10); + + table = gtk_table_new(2, 3, FALSE); + gtk_table_set_col_spacings(GTK_TABLE(table), 5); + gtk_container_set_border_width(GTK_CONTAINER(table), 5); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(conf_dialog)->vbox), table, + TRUE, TRUE, 5); + gtk_widget_show(table); + + label = gtk_label_new(_("Delay: (ms)")); + gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + label = gtk_label_new(_("Feedback: (%)")); + gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + label = gtk_label_new(_("Volume: (%)")); + gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show(label); + + hscale = gtk_hscale_new(GTK_ADJUSTMENT(echo_delay_adj)); + gtk_widget_set_usize(hscale, 400, 35); + gtk_scale_set_digits(GTK_SCALE(hscale), 0); + gtk_table_attach_defaults(GTK_TABLE(table), hscale, 1, 2, 0, 1); + gtk_widget_show(hscale); + + hscale = gtk_hscale_new(GTK_ADJUSTMENT(echo_feedback_adj)); + gtk_widget_set_usize(hscale, 400, 35); + gtk_scale_set_digits(GTK_SCALE(hscale), 0); + gtk_table_attach_defaults(GTK_TABLE(table), hscale, 1, 2, 1, 2); + gtk_widget_show(hscale); + + hscale = gtk_hscale_new(GTK_ADJUSTMENT(echo_volume_adj)); + gtk_widget_set_usize(hscale, 400, 35); + gtk_scale_set_digits(GTK_SCALE(hscale), 0); + gtk_table_attach_defaults(GTK_TABLE(table), hscale, 1, 2, 2, 3); + gtk_widget_show(hscale); + + surround_btn = gtk_check_button_new_with_label(_("Surround echo")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(surround_btn), + echo_surround_enable); + gtk_widget_show(surround_btn); + + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(conf_dialog)->vbox), surround_btn, + TRUE, TRUE, 5); + + bbox = gtk_hbutton_box_new(); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5); + gtk_box_pack_start(GTK_BOX((GTK_DIALOG(conf_dialog)->action_area)), + bbox, TRUE, TRUE, 0); + + + button = gtk_button_new_with_label(_("Ok")); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0); + gtk_signal_connect(GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC(conf_ok_cb), NULL); + gtk_widget_grab_default(button); + gtk_widget_show(button); + + button = gtk_button_new_with_label(_("Cancel")); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0); + gtk_signal_connect(GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC(conf_cancel_cb), NULL); + gtk_widget_show(button); + + button = gtk_button_new_with_label(_("Apply")); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0); + gtk_signal_connect(GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC(conf_apply_cb), NULL); + gtk_widget_show(button); + gtk_widget_show(bbox); + + gtk_widget_show(conf_dialog); +}