Mercurial > audlegacy-plugins
view src/echo_plugin/echo.c @ 972:cf7021ca4e7b trunk
[svn] Add lastfm:// transport, an abstract VFS class which derives from curl
to provide lastfm radio support. Written by majeru with some cleanups
by me. Most last.fm metadata support isn't yet implemented, however, and
will need to be done by majeru. ;)
| author | nenolod |
|---|---|
| date | Sun, 22 Apr 2007 04:16:08 -0700 |
| parents | d124034ebea3 |
| children | 8ca72224786a |
line wrap: on
line source
#include <audacious/plugin.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <gtk/gtk.h> #include <audacious/i18n.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; }
