/*
 *  Bandpass filter sweep effect
 *  Copyright (c) Maarten de Boer <mdeboer@iua.upf.es>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include <math.h>
#include <alsa/asoundlib.h>

struct effect_private {
	/* filter the sweep variables */
	float lfo,dlfo,fs,fc,BW,C,D,a0,a1,a2,b1,b2,*x[3],*y[3];
	float lfo_depth, lfo_center;
	unsigned int channels;
};

static int effect_init(struct lookback *loopback,
		       void *private_data,
		       snd_pcm_access_t access,
		       unsigned int channels,
		       unsigned int rate,
		       snd_pcm_format_t format)
{
	struct effect_private *priv = private_data;
	int i;

#if __BYTE_ORDER == __LITTLE_ENDIAN
	if (format != SND_PCM_FORMAT_S16_LE)
		return -EIO;
#elif __BYTE_ORDER == __BIG_ENDIAN
	if (format != SND_PCM_FORMAT_S16_BE)
		return -EIO;
#else
	return -EIO;
#endif
	priv->fs = (float) rate;
	priv->channels = channels;
	for (i = 0; i < 3; i++) {
		priv->x[i] = calloc(channels * sizeof(float));
		priv->y[i] = calloc(channels * sizeof(float));
	}
	return 0;
}

static int effect_done(struct loopback *loopback,
		       void *private_data)
{
	struct effect_private *priv = private_data;
	int i;

	for (i = 0; i < 3; i++) {
		free(priv->x[i]);
		free(priv->y[i]);
	}
	return 0;
}

static int effect_apply(struct loopback *loopback,
			void *private_data,
			const snd_pcm_channel_area_t *areas,
			snd_uframes_t offset,
			snd_uframes_t frames)
{
	struct effect_private *priv = private_data;
	short *samples = (short*)areas[0].addr + offset*priv->channels;
	snd_uframes_t i;

	for (i=0; i < frames; i++) {
		int chn;

		fc = sin(priv->lfo)*priv->lfo_depth+priv->lfo_center;
		priv->lfo += priv->dlfo;
		if (priv->lfo>2.*M_PI) priv->lfo -= 2.*M_PI;
		priv->C = 1./tan(M_PI*priv->BW/priv->fs);
		priv->D = 2.*cos(2*M_PI*fc/fs);
		priv->a0 = 1./(1.+priv->C);
		priv->a1 = 0;
		priv->a2 = -priv->a0;
		priv->b1 = -priv->C*priv->D*a0;
		priv->b2 = (priv->C-1)*priv->a0;

		for (chn=0; chn < priv->channels; chn++)
		{
			priv->x[chn][2] = priv->x[chn][1];
			priv->x[chn][1] = priv->x[chn][0];

			priv->y[chn][2] = priv->y[chn][1];
			priv->y[chn][1] = priv->y[chn][0];

			priv->x[chn][0] = samples[i*channels+chn];
			priv->y[chn][0] = priv->a0*priv->x[0][chn]
				+ priv->a1*priv->x[1][chn] + priv->a2*x[2][chn]
				- priv->b1*priv->y[1][chn] - priv->b2*y[2][chn];
			samples[i*channels+chn] = priv->y[chn][0];
		}
	}
	return 0;
}

void effect_init_sweep(void)
{
	struct effect_private *priv;

	priv = register_effect(effect_init,
			       effect_apply,
			       effect_done,
			       sizeof(struct effectprivate));
	if (priv) {
		priv->lfo_center = 2000.;
		priv->lfo_depth = 1800.;
		priv->lfo_freq = 0.2;
		priv->BW = 50;
	}
}
