instantiate LV2::Synth, not AudioEffectX
[software/lv2-mdametapiano.git] / src / mdaPiano.cpp
1 /* ==================================================
2 * LV2 port of the famous mda Piano VSTi
3 * ==================================================
4 *
5 * Port
6 * Author: Ricardo Wurmus (rekado)
7 * Based on: mda-vst-src-2010-02-14.zip
8 *
9 * mda Piano v1.0
10 * Copyright(c)1999-2000 Paul Kellett (maxim digital audio)
11 * Based on VST2 SDK (c)1996-1999 Steinberg Soft und Hardware GmbH, All Rights Reserved
12 *
13 * ==================================================
14 */
15
16 #include "mdaPiano.h"
17
18 #include <stdio.h>
19 #include <math.h>
20
21 #define STRING_BUF 2048
22 static const char* sample_file = "samples.raw";
23
24 mdaPianoProgram::mdaPianoProgram()
25 {
26 param[0] = 0.50f; //Decay
27 param[1] = 0.50f; //Release
28 param[2] = 0.50f; //Hardness
29
30 param[3] = 0.50f; //Vel>Hard
31 param[4] = 1.00f; //Muffle
32 param[5] = 0.50f; //Vel>Muff
33
34 param[6] = 0.33f; //Vel Curve
35 param[7] = 0.50f; //Stereo
36 param[8] = 0.33f; //Max Poly
37
38 param[9] = 0.50f; //Tune
39 param[10] = 0.00f; //Random
40 param[11] = 0.50f; //Stretch
41
42 strcpy (name, "mda Piano");
43 }
44
45
46 mdaPiano::mdaPiano(double rate)
47 : LV2::Synth<mdaPianoVoice, mdaPiano>(NPROGS, NPARAMS)
48 {
49 Fs = 44100.0f; iFs = 1.0f/Fs; cmax = 0x7F; //just in case...
50
51 programs = new mdaPianoProgram[NPROGS];
52 if(programs)
53 {
54 //fill patches...
55 VstInt32 i=0;
56 //TODO: load initial values from default preset
57 fillpatch(i++, "mda Piano", 0.500f, 0.500f, 0.500f, 0.5f, 0.803f, 0.251f, 0.376f, 0.500f, 0.330f, 0.500f, 0.246f, 0.500f);
58 setProgram(0);
59 }
60
61
62 //Waveform data and keymapping is hard-wired in *this* version
63 kgrp[ 0].root = 36; kgrp[ 0].high = 37; kgrp[ 0].pos = 0; kgrp[ 0].end = 36275; kgrp[ 0].loop = 14774;
64 kgrp[ 1].root = 40; kgrp[ 1].high = 41; kgrp[ 1].pos = 36278; kgrp[ 1].end = 83135; kgrp[ 1].loop = 16268;
65 kgrp[ 2].root = 43; kgrp[ 2].high = 45; kgrp[ 2].pos = 83137; kgrp[ 2].end = 146756; kgrp[ 2].loop = 33541;
66 kgrp[ 3].root = 48; kgrp[ 3].high = 49; kgrp[ 3].pos = 146758; kgrp[ 3].end = 204997; kgrp[ 3].loop = 21156;
67 kgrp[ 4].root = 52; kgrp[ 4].high = 53; kgrp[ 4].pos = 204999; kgrp[ 4].end = 244908; kgrp[ 4].loop = 17191;
68 kgrp[ 5].root = 55; kgrp[ 5].high = 57; kgrp[ 5].pos = 244910; kgrp[ 5].end = 290978; kgrp[ 5].loop = 23286;
69 kgrp[ 6].root = 60; kgrp[ 6].high = 61; kgrp[ 6].pos = 290980; kgrp[ 6].end = 342948; kgrp[ 6].loop = 18002;
70 kgrp[ 7].root = 64; kgrp[ 7].high = 65; kgrp[ 7].pos = 342950; kgrp[ 7].end = 391750; kgrp[ 7].loop = 19746;
71 kgrp[ 8].root = 67; kgrp[ 8].high = 69; kgrp[ 8].pos = 391752; kgrp[ 8].end = 436915; kgrp[ 8].loop = 22253;
72 kgrp[ 9].root = 72; kgrp[ 9].high = 73; kgrp[ 9].pos = 436917; kgrp[ 9].end = 468807; kgrp[ 9].loop = 8852;
73 kgrp[10].root = 76; kgrp[10].high = 77; kgrp[10].pos = 468809; kgrp[10].end = 492772; kgrp[10].loop = 9693;
74 kgrp[11].root = 79; kgrp[11].high = 81; kgrp[11].pos = 492774; kgrp[11].end = 532293; kgrp[11].loop = 10596;
75 kgrp[12].root = 84; kgrp[12].high = 85; kgrp[12].pos = 532295; kgrp[12].end = 560192; kgrp[12].loop = 6011;
76 kgrp[13].root = 88; kgrp[13].high = 89; kgrp[13].pos = 560194; kgrp[13].end = 574121; kgrp[13].loop = 3414;
77 kgrp[14].root = 93; kgrp[14].high = 999; kgrp[14].pos = 574123; kgrp[14].end = 586343; kgrp[14].loop = 2399;
78 load_samples(&waves);
79
80 //initialise...
81 for(VstInt32 v=0; v<NVOICES; v++)
82 {
83 voice[v].env = 0.0f;
84 voice[v].dec = 0.99f; //all notes off
85 }
86 notes[0] = EVENTS_DONE;
87 volume = 0.2f;
88 muff = 160.0f;
89 cpos = sustain = activevoices = 0;
90 comb = new float[256];
91
92 update();
93 suspend();
94 }
95
96
97 void mdaPiano::update() //parameter change
98 {
99 float * param = programs[curProgram].param;
100 size = (VstInt32)(12.0f * param[2] - 6.0f);
101 sizevel = 0.12f * param[3];
102 muffvel = param[5] * param[5] * 5.0f;
103
104 velsens = 1.0f + param[6] + param[6];
105 if(param[6] < 0.25f) velsens -= 0.75f - 3.0f * param[6];
106
107 fine = param[9] - 0.5f;
108 random = 0.077f * param[10] * param[10];
109 stretch = 0.000434f * (param[11] - 0.5f);
110
111 cdep = param[7] * param[7];
112 trim = 1.50f - 0.79f * cdep;
113 width = 0.04f * param[7]; if(width > 0.03f) width = 0.03f;
114
115 poly = 8 + (VstInt32)(24.9f * param[8]);
116 }
117
118
119 void mdaPiano::resume()
120 {
121 Fs = getSampleRate();
122 iFs = 1.0f / Fs;
123 if(Fs > 64000.0f) cmax = 0xFF; else cmax = 0x7F;
124 memset(comb, 0, sizeof(float) * 256);
125 }
126
127
128 mdaPiano::~mdaPiano () //destroy any buffers...
129 {
130 if(programs) delete [] programs;
131 if(comb) delete[] comb;
132 }
133
134
135 void mdaPiano::setParameter(VstInt32 index, float value)
136 {
137 programs[curProgram].param[index] = value;
138 update();
139 }
140
141
142 void mdaPiano::process(float **inputs, float **outputs, VstInt32 sampleFrames)
143 {
144 float* out0 = outputs[0];
145 float* out1 = outputs[1];
146 VstInt32 event=0, frame=0, frames, v;
147 float x, l, r;
148 VstInt32 i;
149
150 while(frame<sampleFrames)
151 {
152 frames = notes[event++];
153 if(frames>sampleFrames) frames = sampleFrames;
154 frames -= frame;
155 frame += frames;
156
157 while(--frames>=0)
158 {
159 VOICE *V = voice;
160 l = r = 0.0f;
161
162 for(v=0; v<activevoices; v++)
163 {
164 V->frac += V->delta; //integer-based linear interpolation
165 V->pos += V->frac >> 16;
166 V->frac &= 0xFFFF;
167 if(V->pos > V->end) V->pos -= V->loop;
168 i = waves[V->pos];
169 i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000;
170 x = V->env * (*(float *)&i - 3.0f); //fast int->float
171
172 V->env = V->env * V->dec; //envelope
173 V->f0 += V->ff * (x + V->f1 - V->f0); //muffle filter
174 V->f1 = x;
175
176 l += V->outl * V->f0;
177 r += V->outr * V->f0;
178
179 V++;
180 }
181 comb[cpos] = l + r;
182 ++cpos &= cmax;
183 x = cdep * comb[cpos]; //stereo simulator
184
185 *out0++ += l + x;
186 *out1++ += r - x;
187 }
188
189 if(frame<sampleFrames)
190 {
191 VstInt32 note = notes[event++];
192 VstInt32 vel = notes[event++];
193 noteOn(note, vel);
194 }
195 }
196 for(v=0; v<activevoices; v++) if(voice[v].env < SILENCE) voice[v] = voice[--activevoices];
197 notes[0] = EVENTS_DONE; //mark events buffer as done
198 }
199
200
201 void mdaPiano::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames)
202 {
203 float* out0 = outputs[0];
204 float* out1 = outputs[1];
205 VstInt32 event=0, frame=0, frames, v;
206 float x, l, r;
207 VstInt32 i;
208
209 while(frame<sampleFrames)
210 {
211 frames = notes[event++];
212 if(frames>sampleFrames) frames = sampleFrames;
213 frames -= frame;
214 frame += frames;
215
216 while(--frames>=0)
217 {
218 VOICE *V = voice;
219 l = r = 0.0f;
220
221 for(v=0; v<activevoices; v++)
222 {
223 V->frac += V->delta; //integer-based linear interpolation
224 V->pos += V->frac >> 16;
225 V->frac &= 0xFFFF;
226 if(V->pos > V->end) V->pos -= V->loop;
227 //i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000; //not working on intel mac !?!
228 i = waves[V->pos] + ((V->frac * (waves[V->pos + 1] - waves[V->pos])) >> 16);
229 x = V->env * (float)i / 32768.0f;
230 //x = V->env * (*(float *)&i - 3.0f); //fast int->float
231
232 V->env = V->env * V->dec; //envelope
233 V->f0 += V->ff * (x + V->f1 - V->f0); //muffle filter
234 V->f1 = x;
235
236 l += V->outl * V->f0;
237 r += V->outr * V->f0;
238
239 if(!(l > -2.0f) || !(l < 2.0f))
240 {
241 printf("what is this shit? %d, %f, %f\n", i, x, V->f0);
242 l = 0.0f;
243 }
244 if(!(r > -2.0f) || !(r < 2.0f))
245 {
246 r = 0.0f;
247 }
248
249 V++;
250 }
251 comb[cpos] = l + r;
252 ++cpos &= cmax;
253 x = cdep * comb[cpos]; //stereo simulator
254
255 *out0++ = l + x;
256 *out1++ = r - x;
257 }
258
259 if(frame<sampleFrames)
260 {
261 VstInt32 note = notes[event++];
262 VstInt32 vel = notes[event++];
263 noteOn(note, vel);
264 }
265 }
266 for(v=0; v<activevoices; v++) if(voice[v].env < SILENCE) voice[v] = voice[--activevoices];
267 notes[0] = EVENTS_DONE; //mark events buffer as done
268 }
269
270
271 void mdaPiano::noteOn(VstInt32 note, VstInt32 velocity)
272 {
273 float * param = programs[curProgram].param;
274 float l=99.0f;
275 VstInt32 v, vl=0, k, s;
276
277 if(velocity>0)
278 {
279 if(activevoices < poly) //add a note
280 {
281 vl = activevoices;
282 activevoices++;
283 }
284 else //steal a note
285 {
286 for(v=0; v<poly; v++) //find quietest voice
287 {
288 if(voice[v].env < l) { l = voice[v].env; vl = v; }
289 }
290 }
291
292 k = (note - 60) * (note - 60);
293 l = fine + random * ((float)(k % 13) - 6.5f); //random & fine tune
294 if(note > 60) l += stretch * (float)k; //stretch
295
296 s = size;
297 if(velocity > 40) s += (VstInt32)(sizevel * (float)(velocity - 40));
298
299 k = 0;
300 while(note > (kgrp[k].high + s)) k++; //find keygroup
301
302 l += (float)(note - kgrp[k].root); //pitch
303 l = 22050.0f * iFs * (float)exp(0.05776226505 * l);
304 voice[vl].delta = (VstInt32)(65536.0f * l);
305 voice[vl].frac = 0;
306 voice[vl].pos = kgrp[k].pos;
307 voice[vl].end = kgrp[k].end;
308 voice[vl].loop = kgrp[k].loop;
309
310 voice[vl].env = (0.5f + velsens) * (float)pow(0.0078f * velocity, velsens); //velocity
311
312 l = 50.0f + param[4] * param[4] * muff + muffvel * (float)(velocity - 64); //muffle
313 if(l < (55.0f + 0.25f * (float)note)) l = 55.0f + 0.25f * (float)note;
314 if(l > 210.0f) l = 210.0f;
315 voice[vl].ff = l * l * iFs;
316 voice[vl].f0 = voice[vl].f1 = 0.0f;
317
318 voice[vl].note = note; //note->pan
319 if(note < 12) note = 12;
320 if(note > 108) note = 108;
321 l = volume * trim;
322 voice[vl].outr = l + l * width * (float)(note - 60);
323 voice[vl].outl = l + l - voice[vl].outr;
324
325 if(note < 44) note = 44; //limit max decay length
326 l = 2.0f * param[0];
327 if(l < 1.0f) l += 0.25f - 0.5f * param[0];
328 voice[vl].dec = (float)exp(-iFs * exp(-0.6 + 0.033 * (double)note - l));
329 }
330 else //note off
331 {
332 for(v=0; v<NVOICES; v++) if(voice[v].note==note) //any voices playing that note?
333 {
334 if(sustain==0)
335 {
336 if(note < 94 || note == SUSTAIN) //no release on highest notes
337 voice[v].dec = (float)exp(-iFs * exp(2.0 + 0.017 * (double)note - 2.0 * param[1]));
338 }
339 else voice[v].note = SUSTAIN;
340 }
341 }
342 }
343
344
345 VstInt32 mdaPiano::processEvents(VstEvents* ev)
346 {
347 VstInt32 npos=0;
348
349 for (VstInt32 i=0; i<ev->numEvents; i++)
350 {
351 if((ev->events[i])->type != kVstMidiType) continue;
352 VstMidiEvent* event = (VstMidiEvent*)ev->events[i];
353 char* midiData = event->midiData;
354
355 switch(midiData[0] & 0xf0) //status byte (all channels)
356 {
357 case 0x80: //note off
358 notes[npos++] = event->deltaFrames; //delta
359 notes[npos++] = midiData[1] & 0x7F; //note
360 notes[npos++] = 0; //vel
361 break;
362
363 case 0x90: //note on
364 notes[npos++] = event->deltaFrames; //delta
365 notes[npos++] = midiData[1] & 0x7F; //note
366 notes[npos++] = midiData[2] & 0x7F; //vel
367 break;
368
369 case 0xB0: //controller
370 switch(midiData[1])
371 {
372 case 0x01: //mod wheel
373 case 0x43: //soft pedal
374 muff = 0.01f * (float)((127 - midiData[2]) * (127 - midiData[2]));
375 break;
376
377 case 0x07: //volume
378 volume = 0.00002f * (float)(midiData[2] * midiData[2]);
379 break;
380
381 case 0x40: //sustain pedal
382 case 0x42: //sustenuto pedal
383 sustain = midiData[2] & 0x40;
384 if(sustain==0)
385 {
386 notes[npos++] = event->deltaFrames;
387 notes[npos++] = SUSTAIN; //end all sustained notes
388 notes[npos++] = 0;
389 }
390 break;
391
392 default: //all notes off
393 if(midiData[1]>0x7A)
394 {
395 for(VstInt32 v=0; v<NVOICES; v++) voice[v].dec=0.99f;
396 sustain = 0;
397 muff = 160.0f;
398 }
399 break;
400 }
401 break;
402
403 case 0xC0: //program change
404 if(midiData[1]<NPROGS) setProgram(midiData[1]);
405 break;
406
407 default: break;
408 }
409
410 if(npos>EVENTBUFFER) npos -= 3; //discard events if buffer full!!
411 event++; //?
412 }
413 notes[npos] = EVENTS_DONE;
414 return 1;
415 }
416
417
418 void mdaPiano::load_samples(short **buffer)
419 {
420 FILE *f;
421 long num, size;
422 char filepath[STRING_BUF];
423
424 strncpy(filepath, bundle_path(), STRING_BUF);
425 strncat(filepath,
426 sample_file,
427 STRING_BUF - strlen(filepath));
428 f = fopen(filepath, "rb");
429 if (f == NULL) {
430 fputs("File error", stderr);
431 exit(1);
432 }
433
434 // obtain file size
435 fseek(f, 0, SEEK_END);
436 size = ftell(f);
437 rewind(f);
438
439 // allocate memory to contain the whole file
440 *buffer = (short*) malloc (sizeof(short)*size);
441 if (*buffer == NULL) {
442 fputs("Memory error", stderr);
443 exit(2);
444 }
445
446 // copy the file into the buffer
447 num = fread(*buffer, 1, size, f);
448 if (num != size) {
449 fputs ("Reading error", stderr);
450 exit (3);
451 }
452 fclose (f);
453 return;
454 }