# HG changeset patch # User William Pitcock # Date 1207685431 18000 # Node ID eef3a506a2b87c11c7efc788a987f0859592c0d9 # Parent 862477de235bd4311e5a3ea1e36faf36dbfcb8c8 Add crystalizer plugin. diff -r 862477de235b -r eef3a506a2b8 configure.ac --- a/configure.ac Mon Mar 31 04:45:30 2008 -0500 +++ b/configure.ac Tue Apr 08 15:10:31 2008 -0500 @@ -122,7 +122,7 @@ INPUT_PLUGINS="tonegen console sexypsf cue alac metronom vtx" OUTPUT_PLUGINS="null" -EFFECT_PLUGINS="audiocompress ladspa voice_removal sndstretch stereo_plugin echo_plugin" +EFFECT_PLUGINS="audiocompress crystalizer ladspa voice_removal sndstretch stereo_plugin echo_plugin" GENERAL_PLUGINS="song_change alarm" VISUALIZATION_PLUGINS="blur_scope spectrum" CONTAINER_PLUGINS="m3u pls" diff -r 862477de235b -r eef3a506a2b8 src/crystalizer/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/crystalizer/Makefile Tue Apr 08 15:10:31 2008 -0500 @@ -0,0 +1,12 @@ +PLUGIN = crystalizer${PLUGIN_SUFFIX} + +SRCS = crystalizer.c + +include ../../buildsys.mk +include ../../extra.mk + +plugindir := ${plugindir}/${EFFECT_PLUGIN_DIR} + +CFLAGS += ${PLUGIN_CFLAGS} +CPPFLAGS += ${PLUGIN_CPPFLAGS} ${MOWGLI_CFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${PANGO_CFLAGS} -I../../intl -I../.. +LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${PANGO_LIBS} diff -r 862477de235b -r eef3a506a2b8 src/crystalizer/crystalizer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/crystalizer/crystalizer.c Tue Apr 08 15:10:31 2008 -0500 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2008 William Pitcock + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include + +#include "../../config.h" + +static void init(void); +static void configure(void); +static int mod_samples(gpointer *d, gint length, AFormat afmt, gint srate, gint nch); + +EffectPlugin crystalizer_ep = +{ + .description = "Crystalizer", /* Description */ + .init = init, + .configure = configure, + .mod_samples = mod_samples +}; + +static GtkWidget *conf_dialog = NULL; +static gdouble value; + +EffectPlugin *crystalizer_eplist[] = { &crystalizer_ep, NULL }; + +DECLARE_PLUGIN(crystalizer, NULL, NULL, NULL, NULL, crystalizer_eplist, NULL, NULL, NULL); + +static void init(void) +{ + ConfigDb *db; + db = aud_cfg_db_open(); + if (!aud_cfg_db_get_double(db, "crystalizer", "intensity", &value)) + value = 1.0; + aud_cfg_db_close(db); +} + +static void conf_ok_cb(GtkButton * button, gpointer data) +{ + ConfigDb *db; + + value = *(gdouble *) data; + + db = aud_cfg_db_open(); + aud_cfg_db_set_double(db, "crystalizer", "intensity", value); + aud_cfg_db_close(db); + gtk_widget_destroy(conf_dialog); +} + +static void conf_cancel_cb(GtkButton * button, gpointer data) +{ + gtk_widget_destroy(conf_dialog); +} + +static void conf_apply_cb(GtkButton *button, gpointer data) +{ + value = *(gdouble *) data; +} + +static void configure(void) +{ + GtkWidget *hbox, *label, *scale, *button, *bbox; + GtkObject *adjustment; + + if (conf_dialog != NULL) + return; + + conf_dialog = gtk_dialog_new(); + g_signal_connect_swapped(GTK_OBJECT(conf_dialog), "destroy", + GTK_SIGNAL_FUNC(gtk_widget_destroyed), &conf_dialog); + gtk_window_set_title(GTK_WINDOW(conf_dialog), _("Configure Crystalizer")); + + label = gtk_label_new(_("Effect intensity:")); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(conf_dialog)->vbox), label, + TRUE, TRUE, 0); + gtk_widget_show(label); + + hbox = gtk_hbox_new(FALSE, 10); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(conf_dialog)->vbox), hbox, + TRUE, TRUE, 10); + gtk_widget_show(hbox); + + adjustment = gtk_adjustment_new(value, 0.0, 15.0 + 1.0, 0.1, 1.0, 1.0); + scale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment)); + gtk_box_pack_start(GTK_BOX(hbox), scale, TRUE, TRUE, 10); + gtk_widget_show(scale); + + 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); + g_signal_connect_swapped(GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC(conf_ok_cb), + >K_ADJUSTMENT(adjustment)->value); + 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); + g_signal_connect_swapped(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); + g_signal_connect_swapped(GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC(conf_apply_cb), + >K_ADJUSTMENT(adjustment)->value); + gtk_widget_show(button); + + gtk_widget_show(bbox); + + gtk_widget_show(conf_dialog); +} + +static int mod_samples(gpointer *d, gint length, AFormat afmt, gint srate, gint nch) +{ + gint i; + gdouble tmp; + static gdouble prev[2], diff[2]; + + gint16 *data = (gint16 *)*d; + + 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; + + for (i = 0; i < length / 2; i += 2) + { + diff[0] = data[i] - prev[0]; + diff[1] = data[i + 1] - prev[1]; + + tmp = data[i] + (diff[0] * value); + if (tmp < -32768) + tmp = -32768; + if (tmp > 32767) + tmp = 32767; + data[i] = tmp; + + tmp = data[i + 1] + (diff[1] * value); + if (tmp < -32768) + tmp = -32768; + if (tmp > 32767) + tmp = 32767; + data[i + 1] = tmp; + + prev[0] = data[i]; + prev[1] = data[i + 1]; + } + + return length; +}