changeset 127:46730e83b1e2 trunk

[svn] - echo plugin support by Christian Birchinger <joker -at- gentoo.org>
author nenolod
date Thu, 26 Oct 2006 12:41:45 -0700
parents 29857e91c6d5
children d358a61fe55e
files ChangeLog configure.ac src/echo_plugin/Makefile src/echo_plugin/echo.c src/echo_plugin/echo.h src/echo_plugin/gui.c
diffstat 6 files changed, 323 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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 <nenolod@nenolod.net>
+  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 <nenolod@nenolod.net>
   revision [250]
   - re-enable extra stereo plugin build
--- 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 "  -------------"
--- /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
--- /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 <audacious/plugin.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#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;
+}
--- /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 <glib.h>
+
+#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
--- /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 <gtk/gtk.h>
+#include <glib/gi18n.h>
+#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);
+}