/* FluidSynth - A Software Synthesizer * * Copyright (C) 2003 Peter Hanappe and others. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307, USA */ #ifndef _FLUID_CHORUS_H #define _FLUID_CHORUS_H namespace FluidS { #define MAX_CHORUS 99 /* Interpolate how many steps between samples? Must be power of two For example: 8 => use a resolution of 256 steps between any two samples */ #define INTERPOLATION_SUBSAMPLES_LN2 8 #define INTERPOLATION_SUBSAMPLES (1 << (INTERPOLATION_SUBSAMPLES_LN2-1)) #define INTERPOLATION_SUBSAMPLES_ANDMASK (INTERPOLATION_SUBSAMPLES-1) /* Use how many samples for interpolation? Must be odd. '7' sounds relatively clean, when listening to the modulated delay signal alone. For a demo on aliasing try '1' With '3', the aliasing is still quite pronounced for some input frequencies */ #define INTERPOLATION_SAMPLES 5 //--------------------------------------------------------- // Chorus //--------------------------------------------------------- class Chorus { static void triangle(int *buf, int len, int depth); static void sine(int *buf, int len, int depth); /* Store the values between fluid_chorus_set_xxx and fluid_chorus_update * Logic behind this: * - both 'parameter' and 'new_parameter' hold the same value. * - To change the chorus settings, 'new_parameter' is modified and * fluid_chorus_update is called. * - If the new value is valid, it is copied to 'parameter'. * - If it is invalid, 'new_parameter' is restored to 'parameter'. */ int type; // current value int new_type; // next value, if parameter check is OK float depth_ms; // current value float new_depth_ms; // next value, if parameter check is OK float level; // current value float new_level; // next value, if parameter check is OK float speed_Hz; // current value float new_speed_Hz; // next value, if parameter check is OK int number_blocks; // current value int new_number_blocks; // next value, if parameter check is OK float *chorusbuf; int counter; long phase[MAX_CHORUS]; long modulation_period_samples; int *lookup_tab; float sample_rate; /* sinc lookup table */ float sinc_table[INTERPOLATION_SAMPLES][INTERPOLATION_SUBSAMPLES]; public: Chorus(float sample_rate); ~Chorus(); void update(); void set_nr(int nr) { new_number_blocks = nr; } void set_level(float level) { new_level = level; } void set_speed_Hz(float speed_Hz) { new_speed_Hz = speed_Hz; } void set_depth_ms(float depth_ms) { new_depth_ms = depth_ms; } void set_type(int type) { new_type = type; } void process(int, float *in, float *left_out, float *right_out); void reset(); int get_nr() const { return number_blocks; } float get_level() const { return level; } float get_speed_Hz() const { return speed_Hz; } float get_depth_ms() const { return depth_ms; } int get_type() const { return type; } void setParameter(int parameter, double value); double parameter(int idx) const; }; } #endif /* _FLUID_CHORUS_H */