1
2 #include "wavetable.h"
3 #include <math.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7
8 #define M_PI 3.14159265358979323846
9
10 const int wavetable_number_of_waves = 8;
11 wave* waves[8];
12 int wavetable_sample_rate = 44100;
13 float tuning = 0;
14
15 float buf0,buf1;
16 float f, pc, q; //filter coefficients
17 float bf0, bf1, bf2, bf3, bf4; //filter buffers (beware denormals!)
18 float t1, t2; //temporary buffers
19 float selectivity, gain1, gain2, ratio, cap;
20
21 float filter_frequency,filter_resonance;
22
23
24
25 //-----------------------------------------------------------
26 // Make waveform
27
wavetable_make_wave(int wave_number,const char * path,const char * filename)28 void wavetable_make_wave(int wave_number, const char* path, const char* filename)
29 {
30 int length = waves[wave_number]->length;
31
32 float* buffer_source_wave = (float *)malloc(12*(length*sizeof(float)) );
33
34 if (buffer_source_wave == NULL) { printf("Failed to allocate memory!\n"); return; }
35
36 float* buffer_filtered_wave = (float *)malloc(12*(length*sizeof(float)) );
37
38 if (buffer_filtered_wave == NULL) { printf("Failed to allocate memory!\n"); return; }
39
40 // Load waveform
41
42
43 FILE *ptr_myfile;
44
45 char* filename_and_path = (char*) malloc( strlen(path) + strlen(filename) + 12);
46
47 sprintf(filename_and_path, "%swaves/%s.wav", path, filename);
48 printf("\n\n");
49 printf("Loading and converting - %s", filename_and_path);
50 printf("\n\n");
51
52
53 ptr_myfile = fopen(filename_and_path,"rb");
54
55 if (ptr_myfile)
56 {
57
58 for (int x=0; x<8; x++)
59 {
60 fseek(ptr_myfile, 80, SEEK_SET);
61 fread(&buffer_source_wave[x*length] ,1, length*sizeof(float), ptr_myfile);
62 }
63
64
65 fclose(ptr_myfile);
66
67 //------ Filter
68
69 // Moog 24 dB/oct resonant lowpass VCF
70 // References: CSound source code, Stilson/Smith CCRMA paper.
71 // Modified by paul.kellett@maxim.abel.co.uk July 2000
72
73 // Set coefficients given frequency & resonance [0.0...1.0]
74
75 float frequency = 0.04;
76 float resonance = 0;
77 float in;
78
79 memcpy( &waves[wave_number]->buffer[0], &buffer_source_wave[0], length*sizeof(4));
80
81 for (int wave=1; wave<8; wave++)
82 {
83
84 float minpeak = 0;
85 float maxpeak = 0;
86 float maxvol = 0;
87
88 for (int x=0; x<length*8; x++)
89 {
90
91 in = buffer_source_wave[x];
92
93 q = 1.0f - frequency;
94 pc = frequency + 0.8f * frequency * q;
95 f = pc + pc - 1.0f;
96 q = resonance * (1.0f + 0.5f * q * (1.0f - q + 5.6f * q * q));
97
98 // Filter (in [-1.0...+1.0])
99
100 in -= q * bf4; //feedback
101 t1 = bf1; bf1 = (in + bf0) * pc - bf1 * f;
102 t2 = bf2; bf2 = (bf1 + t1) * pc - bf2 * f;
103 t1 = bf3; bf3 = (bf2 + t2) * pc - bf3 * f;
104 bf4 = (bf3 + t1) * pc - bf4 * f;
105 bf4 = bf4 - bf4 * bf4 * bf4 * 0.166667f; //clipping
106 bf0 = in;
107
108
109 buffer_filtered_wave[x] = bf4;
110
111
112 if (bf4 < 0 && bf4 < minpeak) minpeak = bf4;
113 if (bf4 > 0 && bf4 > maxpeak) maxpeak = bf4;
114
115
116
117
118 }
119
120 if (-minpeak > maxpeak) maxvol = -minpeak;
121 else maxvol = maxpeak;
122
123 if (-minpeak == maxpeak) maxvol = maxpeak;
124
125
126
127 float amp = 0.7/maxvol;
128
129
130 for (int y=0; y<length-1; y++) // Normalise
131 {
132 waves[wave_number]->buffer[y+(wave*length)] = buffer_filtered_wave[y+(4*4110)]*amp;
133 }
134
135
136 frequency /= 1.8;
137 }
138
139 } else printf("\nFile not found!\n\n");
140
141
142 free(buffer_source_wave);
143 free(buffer_filtered_wave);
144 free(filename_and_path);
145 }
146
147
148
149
150 //-----------------------------------------------------------
151 // Play wavetable
152
wavetable_tick(oscillator * osc)153 float wavetable_tick(oscillator* osc)
154 {
155 int wave1_number = osc->wave1_number;
156 int wave2_number = osc->wave2_number;
157 float wave_mix = osc->wave_mix;
158
159 float frequency = osc->frequency * tuning;
160 int length = waves[wave1_number]->length;
161
162 float increment = osc->increment;
163
164 float index = osc->index;
165 int index_int = index;
166
167 float result1 = 0, result2 = 0;
168
169 unsigned int wavnum = osc->bandlimit_offset;
170
171 if (index == index_int)
172 {
173 result1 = waves[wave1_number]->buffer[wavnum+index_int];
174 result2 = waves[wave2_number]->buffer[wavnum+index_int];
175 }
176 else
177 {
178 float fraction1 = index - index_int;
179 float fraction2 = 1 - fraction1;
180
181
182
183 if (index < length-2)
184 {
185
186 result1 = waves[wave1_number]->buffer[index_int+wavnum] * fraction2;
187 result1 += waves[wave1_number]->buffer[index_int+1+wavnum] * fraction1;
188 result2 = waves[wave2_number]->buffer[index_int+wavnum] * fraction2;
189 result2 += waves[wave2_number]->buffer[index_int+1+wavnum] * fraction1;
190 }
191 else
192 {
193 result1 = waves[wave1_number]->buffer[index_int+wavnum] * fraction2;
194 result1 += waves[wave1_number]->buffer[wavnum] * fraction1;
195 result2 = waves[wave2_number]->buffer[index_int+wavnum] * fraction2;
196 result2 += waves[wave2_number]->buffer[wavnum] * fraction1;
197 }
198 }
199
200 index += increment;
201
202 if (index > length - 1 )
203 {
204 index -= length;
205 osc->start_phase = true;
206
207 int tst = (frequency/100)*8;
208 if (tst<0) tst = 0;
209 if (tst>7) tst = 7;
210 osc->bandlimit_offset = 0; // (tst*4410);
211 }
212
213
214 osc->index = index;
215
216 osc->increment = (wavetable_sample_rate * frequency) / wavetable_sample_rate;
217
218 return (result2 * wave_mix) + (result1 * (1-wave_mix));
219
220 }
221
wavetable_get_buffer(int wave_number)222 float* wavetable_get_buffer(int wave_number)
223 {
224 return waves[wave_number]->buffer;
225 }
226
227
228
229
230 //-----------------------------------------------------------
231 // Set frequency
232
wavetable_set_oscillator_frequency(oscillator * osc,float freq)233 void wavetable_set_oscillator_frequency(oscillator* osc,float freq)
234 {
235 osc->frequency = freq;
236 }
237
238 //-----------------------------------------------------------
239 // Set oscillator wave number
240
wavetable_set_oscillator_wave_number(oscillator * osc,int wave_number,int wave_number2)241 void wavetable_set_oscillator_wave_number(oscillator* osc,int wave_number, int wave_number2)
242 {
243 osc->wave1_number = wave_number;
244 osc->wave2_number = wave_number2;
245 }
246
247 //-----------------------------------------------------------
248 // Set oscillator wave number
249
wavetable_set_oscillator_wave_mix(oscillator * osc,float wave_mix)250 void wavetable_set_oscillator_wave_mix(oscillator* osc,float wave_mix)
251 {
252 osc->wave_mix = wave_mix;
253 }
254
255 //-------------------------------------------------------------
256 // Set sample rate
257
wavetable_set_sample_rate(int sample_rate)258 void wavetable_set_sample_rate(int sample_rate)
259 {
260 wavetable_sample_rate = sample_rate;
261 tuning = (float)44100 / sample_rate;
262
263 printf("Tuning - %f", tuning);
264
265 }
266
267 //-------------------------------------------------------------
268 // Initialise
269
wavetable_initialise()270 void wavetable_initialise()
271 {
272 for (int x=0; x<wavetable_number_of_waves; x++)
273 {
274 waves[x] = (wave *)malloc(sizeof(wave));
275 waves[x]->length = 4410;
276 waves[x]->buffer = (float *)malloc(8*4410*sizeof(float));
277 }
278
279 // Init anti alias filter
280
281 buf0=0; buf1=0;
282
283 f=0; pc=0; q=0; //filter coefficients
284 bf0=0; bf1=0; bf2=0; bf3=0; bf4=0; //filter buffers (beware denormals!)
285 t1=0; t2=0; //temporary buffers
286
287 selectivity=90, gain1=0, gain2=0.25, ratio=7, cap=0;
288
289 return;
290 }
291
292 //-------------------------------------------------------------
293 // Cleanup
294
wavetable_cleanup()295 void wavetable_cleanup()
296 {
297 for (int x=0; x<wavetable_number_of_waves; x++)
298 {
299 free(waves[x]->buffer);
300 free(waves[x]);
301 }
302
303
304
305 }
306
307
308