LMMS
Loading...
Searching...
No Matches
osc.h
Go to the documentation of this file.
1/* Calf DSP Library
2 * Oscillators
3 *
4 * Copyright (C) 2001-2007 Krzysztof Foltman
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#ifndef CALF_OSC_H
23#define CALF_OSC_H
24
25#include "fft.h"
26#include <map>
27
28namespace dsp
29{
30
36{
42 void reset()
43 {
44 phase = 0;
45 }
46
47 void set_freq(float freq, float sr)
48 {
49 phasedelta = (int)(freq * 65536.0 * 256.0 * 16.0 / sr) << 4;
50 }
51
52 void set_freq_odsr(float freq, double odsr)
53 {
54 phasedelta = (int)(freq * 65536.0 * 256.0 * 16.0 * odsr) << 4;
55 }
56
57 inline void step()
58 {
60 }
61
62 inline float get()
63 {
64 float value = (phase >> 16 ) / 65535.0 - 0.5;
65 step();
66 return value;
67 }
68};
69
75template<int SIZE_BITS>
77{
78 enum { SIZE = 1 << SIZE_BITS };
80 {
82 return fft;
83 }
84
86
88 void compute_spectrum(float input[SIZE])
89 {
92 for (int i = 0; i < SIZE; i++)
93 data[i] = input[i];
94 fft.calculate(data, spectrum, false);
95 delete []data;
96 }
97
99 void compute_waveform(float output[SIZE])
100 {
103 fft.calculate(spectrum, data, true);
104 for (int i = 0; i < SIZE; i++)
105 output[i] = data[i].real();
106 delete []data;
107 }
108
111 {
112 spectrum[0] = 0.f;
113 }
114
117 void make_waveform(float output[SIZE], int cutoff, bool foldover = false)
118 {
120 std::vector<std::complex<float> > new_spec, iffted;
121 new_spec.resize(SIZE);
122 iffted.resize(SIZE);
123 // Copy original harmonics up to cutoff point
124 new_spec[0] = spectrum[0];
125 for (int i = 1; i < cutoff; i++)
126 new_spec[i] = spectrum[i],
127 new_spec[SIZE - i] = spectrum[SIZE - i];
128 // Fill the rest with zeros, optionally folding over harmonics over the
129 // cutoff point into the lower octaves while halving the amplitude.
130 // (I think it is almost nice for bell type waveforms when the original
131 // waveform has few widely spread harmonics)
132 if (foldover)
133 {
134 std::complex<float> fatt(0.5);
135 cutoff /= 2;
136 if (cutoff < 2)
137 cutoff = 2;
138 for (int i = SIZE / 2; i >= cutoff; i--)
139 {
140 new_spec[i / 2] += new_spec[i] * fatt;
141 new_spec[SIZE - i / 2] += new_spec[SIZE - i] * fatt;
142 new_spec[i] = 0.f,
143 new_spec[SIZE - i] = 0.f;
144 }
145 }
146 else
147 {
148 if (cutoff < 1)
149 cutoff = 1;
150 for (int i = cutoff; i < SIZE / 2; i++)
151 new_spec[i] = 0.f,
152 new_spec[SIZE - i] = 0.f;
153 }
154 // convert back to time domain (IFFT) and extract only real part
155 fft.calculate(&new_spec.front(), &iffted.front(), true);
156 for (int i = 0; i < SIZE; i++)
157 output[i] = iffted[i].real();
158 }
159};
160
162template<int SIZE_BITS>
163struct waveform_family: public std::map<uint32_t, float *>
164{
165 enum { SIZE = 1 << SIZE_BITS };
166 using std::map<uint32_t, float *>::iterator;
167 using std::map<uint32_t, float *>::end;
168 using std::map<uint32_t, float *>::lower_bound;
170
173 void make(bandlimiter<SIZE_BITS> &bl, float input[SIZE], bool foldover = false, uint32_t limit = SIZE / 2)
174 {
175 memcpy(original, input, sizeof(original));
176 bl.compute_spectrum(input);
177 make_from_spectrum(bl, foldover);
178 }
179
182 void make_from_spectrum(bandlimiter<SIZE_BITS> &bl, bool foldover = false, uint32_t limit = SIZE / 2)
183 {
184 bl.remove_dc();
185
186 uint32_t base = 1 << (32 - SIZE_BITS);
187 uint32_t cutoff = SIZE / 2, top = SIZE / 2;
188 float vmax = 0;
189 for (unsigned int i = 0; i < cutoff; i++)
190 vmax = std::max(vmax, abs(bl.spectrum[i]));
191 float vthres = vmax / 1024.0; // -60dB
192 float cumul = 0.f;
193 while(cutoff > (SIZE / limit)) {
194 if (!foldover)
195 {
196 // skip harmonics too quiet to be heard, but measure their loudness cumulatively,
197 // because even if a single harmonic is too quiet, a whole bunch of them may add up
198 // to considerable amount of space
199 cumul = 0.f;
200 while(cutoff > 1 && cumul + abs(bl.spectrum[cutoff - 1]) < vthres)
201 {
202 cumul += abs(bl.spectrum[cutoff - 1]);
203 cutoff--;
204 }
205 }
206 float *wf = new float[SIZE+1];
207 bl.make_waveform(wf, cutoff, foldover);
208 wf[SIZE] = wf[0];
209 float **storage = &(*this)[base * (top / cutoff)];
210 delete[] *storage;
211 *storage = wf;
212 cutoff = (int)(0.75 * cutoff);
213 }
214 }
215
217 inline float *get_level(uint32_t phase_delta)
218 {
219 iterator i = upper_bound(phase_delta);
220 if (i == end())
221 return NULL;
222 // printf("Level = %08x\n", i->first);
223 return i->second;
224 }
225
227 {
228 for (iterator i = begin(); i != end(); i++)
229 delete []i->second;
230 clear();
231 }
232};
233
234#if 0
235// cubic interpolation
236static inline float cerp(float pm1, float p0, float p1, float p2, float t)
237{
238 return (-t*(t-1)*(t-2) * pm1 + 3*(t+1)*(t-1)*(t-2) * p0 - 3*(t+1)*t*(t-2) * p1 + (t+1)*t*(t-1) * p2) * (1.0 / 6.0);
239}
240#endif
247template<int SIZE_BITS>
249{
250 enum { SIZE = 1 << SIZE_BITS, MASK = SIZE - 1, SCALE = 1 << (32 - SIZE_BITS) };
251 float *waveform;
253 {
254 waveform = NULL;
255 }
256
258 inline float get()
259 {
260 uint32_t wpos = phase >> (32 - SIZE_BITS);
261 return dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
262 }
263
264 inline float get_phaseshifted(uint32_t shift, float mix)
265 {
266 uint32_t wpos = phase >> (32 - SIZE_BITS);
267 float value1 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
268 wpos = (phase + shift) >> (32 - SIZE_BITS);
269 float value2 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], ((phase + shift) & (SCALE - 1)) * (1.0f / SCALE));
270 return value1 + mix * value2;
271 }
272
273 inline float get_phaseshifted2(uint32_t shift, int32_t gshift, float mix)
274 {
275 uint32_t wpos = (phase + gshift) >> (32 - SIZE_BITS);
276 float value1 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
277 wpos = (phase + gshift + shift) >> (32 - SIZE_BITS);
278 float value2 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], ((phase + shift) & (SCALE - 1)) * (1.0f / SCALE));
279 return value1 + mix * value2;
280 }
281
282 inline float get_phasedist(uint32_t sync, uint32_t shift, float mix)
283 {
284 uint32_t phase_mod = (uint64_t(phase) * sync >> 16);
285
286 uint32_t wpos = phase_mod >> (32 - SIZE_BITS);
287 float value1 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
288 wpos = (phase_mod + shift) >> (32 - SIZE_BITS);
289 float value2 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], ((phase + shift) & (SCALE - 1)) * (1.0f / SCALE));
290 return value1 + mix * value2;
291 }
292
293 inline void advance()
294 {
295 phase += phasedelta;
296 }
297};
298
303{
305 float last;
306
308 {
309 reset();
310 }
311 void reset()
312 {
314 last = 0;
315 }
316 inline float get()
317 {
318 uint32_t phase2 = phase;
319 // start at 90 degrees point of the "/\" wave (-1 to +1)
320 phase2 += 1<<30;
321 // if in second half, invert the wave (so it falls back into 0..0x7FFFFFFF)
322 phase2 ^= ((int32_t)phase2)>>31;
323
324 float value = (phase2 >> 6) / 16777216.0 - 1.0;
325 phase += phasedelta;
326 return value;
327 }
328};
329
331static inline void normalize_waveform(float *table, unsigned int size)
332{
333 float dc = 0;
334 for (unsigned int i = 0; i < size; i++)
335 dc += table[i];
336 dc /= size;
337 for (unsigned int i = 0; i < size; i++)
338 table[i] -= dc;
339 float thismax = 0;
340 for (unsigned int i = 0; i < size; i++)
341 thismax = std::max(thismax, fabsf(table[i]));
342 if (thismax < 0.000001f)
343 return;
344 double divv = 1.0 / thismax;
345 for (unsigned int i = 0; i < size; i++)
346 table[i] *= divv;
347}
348
349
350
351};
352
353#endif
#define NULL
Definition CarlaBridgeFormat.cpp:30
T limit(T val, T min, T max)
Definition Util.h:78
float abs(const fft_t *freqs, off_t x)
Definition OscilGen.cpp:52
Definition fft.h:34
void calculate(complex *input, complex *output, bool inverse) const
Definition fft.h:64
struct huft * t
Definition inflate.c:943
unsigned bl
Definition inflate.c:935
register unsigned i
Definition inflate.c:1575
static PuglViewHint int value
Definition pugl.h:1708
JHUFF_TBL long freq[]
Definition jchuff.h:50
int int32_t
Definition mid.cpp:97
unsigned int uint32_t
Definition mid.cpp:100
Definition audio_fx.h:36
static void normalize_waveform(float *table, unsigned int size)
Simple stupid inline function to normalize a waveform (by removing DC offset and ensuring max absolut...
Definition osc.h:331
T lerp(T v1, T v2, U mix)
Definition primitives.h:267
T sine_table< T, N, Multiplier >::data[N+1]
Definition primitives.h:442
fixed_point< unsigned long long int, 24 > wpos
wave position (unsigned 64-bit int including 24-bit fractional part)
Definition fixed_point.h:264
Definition osc.h:77
void make_waveform(float output[SIZE], int cutoff, bool foldover=false)
Definition osc.h:117
void remove_dc()
remove DC offset of the spectrum (it usually does more harm than good!)
Definition osc.h:110
void compute_spectrum(float input[SIZE])
Import time domain waveform and calculate spectrum from it.
Definition osc.h:88
void compute_waveform(float output[SIZE])
Generate the waveform from the contained spectrum.
Definition osc.h:99
static dsp::fft< float, SIZE_BITS > & get_fft()
Definition osc.h:79
std::complex< float > spectrum[SIZE]
Definition osc.h:85
@ SIZE
Definition osc.h:78
Definition osc.h:36
void set_freq(float freq, float sr)
Set phase delta based on oscillator frequency and sample rate.
Definition osc.h:47
uint32_t phasedelta
Per-sample phase delta (phase increment), equal to 2^32*freq/sr.
Definition osc.h:40
void step()
Make one phase increment.
Definition osc.h:57
float get()
Make one phase increment and return a value from -0.5 to 0.5.
Definition osc.h:62
void reset()
Reset oscillator phase to zero.
Definition osc.h:42
uint32_t phase
Phase (from 0 to 0xFFFFFFFF).
Definition osc.h:38
void set_freq_odsr(float freq, double odsr)
Set phase delta based on oscillator frequency and inverse of sample rate.
Definition osc.h:52
float get()
Definition osc.h:316
float last
Previous value (not stored here, but may be used by calling code).
Definition osc.h:305
void reset()
Definition osc.h:311
triangle_lfo()
Definition osc.h:307
Set of bandlimited wavetables.
Definition osc.h:164
void make(bandlimiter< SIZE_BITS > &bl, float input[SIZE], bool foldover=false, uint32_t limit=SIZE/2)
Definition osc.h:173
void make_from_spectrum(bandlimiter< SIZE_BITS > &bl, bool foldover=false, uint32_t limit=SIZE/2)
Definition osc.h:182
float original[SIZE]
Definition osc.h:169
float * get_level(uint32_t phase_delta)
Retrieve waveform pointer suitable for specified phase_delta.
Definition osc.h:217
~waveform_family()
Destructor, deletes the waveforms and removes them from the map.
Definition osc.h:226
float get()
Get the value from single oscillator at current position.
Definition osc.h:258
float * waveform
Definition osc.h:251
float get_phaseshifted(uint32_t shift, float mix)
Add/substract two phase-shifted values.
Definition osc.h:264
float get_phaseshifted2(uint32_t shift, int32_t gshift, float mix)
Add/substract two phase-shifted values.
Definition osc.h:273
@ MASK
Definition osc.h:250
@ SIZE
Definition osc.h:250
@ SCALE
Definition osc.h:250
waveform_oscillator()
Definition osc.h:252
float get_phasedist(uint32_t sync, uint32_t shift, float mix)
Get the value of a hard synced osc (65536 = 1:1 ratio).
Definition osc.h:282
void advance()
One step.
Definition osc.h:293
Definition globals.h:33
memcpy(hh, h, RAND_HEAD_LEN)
ulg size
Definition extract.c:2350
typedef int(UZ_EXP MsgFn)()