1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
/* 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 */
|