3
Copyright (C) 2000 Jeff Tranter
6
(C) 1999 Stefan Westerfeld
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
#include "artsmodules.h"
27
#include "stdsynthmodule.h"
31
class Synth_PITCH_SHIFT_impl : virtual public Synth_PITCH_SHIFT_skel,
32
virtual public StdSynthModule
35
float _speed, _frequency;
37
static const int MAXDELAY = 44100;
39
float lfopos, b1pos, b2pos, b1inc, b2inc;
40
bool b1reset, b2reset, initialized;
44
float speed() { return _speed; }
45
void speed(float newSpeed) { _speed = newSpeed; }
47
float frequency() { return _frequency; }
48
void frequency(float newFrequency) { _frequency = newFrequency; }
53
dbuffer = new float[MAXDELAY];
54
for (dbpos=0; dbpos<MAXDELAY; dbpos++)
66
void calculateBlock(unsigned long samples)
68
float *outend = outvalue + samples;
69
float fsr = (float)samplingRate;
71
float lfo, b1value, b2value;
72
float lfoposinc = _frequency / fsr;
78
b1inc = b2inc = 1.0 - _speed;
80
/* not yet sure what would be a nice initialization here? */
87
while (outvalue < outend)
90
* fill delay buffer with the input signal
92
dbuffer[dbpos] = *invalue++;
95
lfopos -= floor(lfopos);
98
b1reset = b2reset = false;
102
* _speed < 1.0 (downpitching)
104
* start with current sample and increase delay slowly
106
* _speed > 1.0 (uppitching)
108
* start with a sample from long ago and slowly decrease delay
110
if (!b1reset && lfopos > 0.25) {
116
b1pos = 10 + ((-b1inc) * (1 / lfoposinc));
117
/* 10+ are not strictly necessary */
122
if (!b2reset && lfopos > 0.75) {
128
b2pos = 10 + ((-b2inc) * (1/lfoposinc));
129
/* 10+ are not strictly necessary */
137
int position, position1;
138
double error,int_pos;
141
* Interpolate value from buffer position 1
143
error = modf(b1pos, &int_pos);
145
position = dbpos - (int)int_pos;
147
position += MAXDELAY;
148
position1 = position - 1;
150
position1 += MAXDELAY;
152
b1value = dbuffer[position] * (1 - error) + dbuffer[position1] * error;
155
* Interpolate value from buffer position 2
157
error = modf(b2pos,&int_pos);
159
position = dbpos - (int)int_pos;
161
position += MAXDELAY;
162
position1 = position-1;
164
position1 += MAXDELAY;
166
b2value = dbuffer[position]*(1-error) + dbuffer[position1]*error;
169
* Calculate output signal from these two buffers
172
lfo = (sin(pi2 * lfopos) + 1) / 2;
174
/* position sin lfo variable
175
*------------------------------------------------------------------
176
* lfo value: 0.25 1 1 => buffer 2 is used
177
* 0.75 -1 0 => buffer 1 is used
180
*outvalue++ = b1value * (1.0 - lfo) + b2value * lfo;
183
* increment delay buffer position
186
if (dbpos == MAXDELAY)
192
REGISTER_IMPLEMENTATION(Synth_PITCH_SHIFT_impl);