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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
#include "artsmodulessynth.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
enum { MAXDELAY = 44100 };
39
float lfopos, b1pos, b2pos, b1inc, b2inc;
40
bool b1reset, b2reset, initialized;
44
Synth_PITCH_SHIFT_impl() : _speed(1.0), _frequency(5.0)
48
float speed() { return _speed; }
49
void speed(float newSpeed) { _speed = newSpeed; }
51
float frequency() { return _frequency; }
52
void frequency(float newFrequency) { _frequency = newFrequency; }
57
dbuffer = new float[MAXDELAY];
58
for (dbpos=0; dbpos<MAXDELAY; dbpos++)
70
void calculateBlock(unsigned long samples)
72
float *outend = outvalue + samples;
73
float fsr = (float)samplingRate;
75
float lfo, b1value, b2value;
76
float lfoposinc = _frequency / fsr;
82
b1inc = b2inc = 1.0 - _speed;
84
/* not yet sure what would be a nice initialization here? */
91
while (outvalue < outend)
94
* fill delay buffer with the input signal
96
dbuffer[dbpos] = *invalue++;
99
lfopos -= floor(lfopos);
102
b1reset = b2reset = false;
106
* _speed < 1.0 (downpitching)
108
* start with current sample and increase delay slowly
110
* _speed > 1.0 (uppitching)
112
* start with a sample from long ago and slowly decrease delay
114
if (!b1reset && lfopos > 0.25) {
120
b1pos = 10 + ((-b1inc) * (1 / lfoposinc));
121
/* 10+ are not strictly necessary */
126
if (!b2reset && lfopos > 0.75) {
132
b2pos = 10 + ((-b2inc) * (1/lfoposinc));
133
/* 10+ are not strictly necessary */
141
int position, position1;
142
double error,int_pos;
145
* Interpolate value from buffer position 1
147
error = modf(b1pos, &int_pos);
149
position = dbpos - (int)int_pos;
151
position += MAXDELAY;
152
position1 = position - 1;
154
position1 += MAXDELAY;
156
b1value = dbuffer[position] * (1 - error) + dbuffer[position1] * error;
159
* Interpolate value from buffer position 2
161
error = modf(b2pos,&int_pos);
163
position = dbpos - (int)int_pos;
165
position += MAXDELAY;
166
position1 = position-1;
168
position1 += MAXDELAY;
170
b2value = dbuffer[position]*(1-error) + dbuffer[position1]*error;
173
* Calculate output signal from these two buffers
176
lfo = (sin(pi2 * lfopos) + 1) / 2;
178
/* position sin lfo variable
179
*------------------------------------------------------------------
180
* lfo value: 0.25 1 1 => buffer 2 is used
181
* 0.75 -1 0 => buffer 1 is used
184
*outvalue++ = b1value * (1.0 - lfo) + b2value * lfo;
187
* increment delay buffer position
190
if (dbpos == MAXDELAY)
196
REGISTER_IMPLEMENTATION(Synth_PITCH_SHIFT_impl);