load samples from file
[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 AudioEffect *createEffectInstance(audioMasterCallback audioMaster)
25 {
26 return new mdaPiano(audioMaster);
27 }
28
29 mdaPianoProgram::mdaPianoProgram()
30 {
31 param[0] = 0.50f; //Decay
32 param[1] = 0.50f; //Release
33 param[2] = 0.50f; //Hardness
34
35 param[3] = 0.50f; //Vel>Hard
36 param[4] = 1.00f; //Muffle
37 param[5] = 0.50f; //Vel>Muff
38
39 param[6] = 0.33f; //Vel Curve
40 param[7] = 0.50f; //Stereo
41 param[8] = 0.33f; //Max Poly
42
43 param[9] = 0.50f; //Tune
44 param[10] = 0.00f; //Random
45 param[11] = 0.50f; //Stretch
46
47 strcpy (name, "mda Piano");
48 }
49
50
51 mdaPiano::mdaPiano(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, NPROGS, NPARAMS)
52 {
53 Fs = 44100.0f; iFs = 1.0f/Fs; cmax = 0x7F; //just in case...
54
55 programs = new mdaPianoProgram[NPROGS];
56 if(programs)
57 {
58 //fill patches...
59 VstInt32 i=0;
60 //TODO: load initial values from default preset
61 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);
62 setProgram(0);
63 }
64
65 if(audioMaster)
66 {
67 setNumInputs(0);
68 setNumOutputs(NOUTS);
69 canProcessReplacing();
70 isSynth();
71 setUniqueID('MDAp'); ///
72 }
73
74 //Waveform data and keymapping is hard-wired in *this* version
75 kgrp[ 0].root = 36; kgrp[ 0].high = 37; kgrp[ 0].pos = 0; kgrp[ 0].end = 36275; kgrp[ 0].loop = 14774;
76 kgrp[ 1].root = 40; kgrp[ 1].high = 41; kgrp[ 1].pos = 36278; kgrp[ 1].end = 83135; kgrp[ 1].loop = 16268;
77 kgrp[ 2].root = 43; kgrp[ 2].high = 45; kgrp[ 2].pos = 83137; kgrp[ 2].end = 146756; kgrp[ 2].loop = 33541;
78 kgrp[ 3].root = 48; kgrp[ 3].high = 49; kgrp[ 3].pos = 146758; kgrp[ 3].end = 204997; kgrp[ 3].loop = 21156;
79 kgrp[ 4].root = 52; kgrp[ 4].high = 53; kgrp[ 4].pos = 204999; kgrp[ 4].end = 244908; kgrp[ 4].loop = 17191;
80 kgrp[ 5].root = 55; kgrp[ 5].high = 57; kgrp[ 5].pos = 244910; kgrp[ 5].end = 290978; kgrp[ 5].loop = 23286;
81 kgrp[ 6].root = 60; kgrp[ 6].high = 61; kgrp[ 6].pos = 290980; kgrp[ 6].end = 342948; kgrp[ 6].loop = 18002;
82 kgrp[ 7].root = 64; kgrp[ 7].high = 65; kgrp[ 7].pos = 342950; kgrp[ 7].end = 391750; kgrp[ 7].loop = 19746;
83 kgrp[ 8].root = 67; kgrp[ 8].high = 69; kgrp[ 8].pos = 391752; kgrp[ 8].end = 436915; kgrp[ 8].loop = 22253;
84 kgrp[ 9].root = 72; kgrp[ 9].high = 73; kgrp[ 9].pos = 436917; kgrp[ 9].end = 468807; kgrp[ 9].loop = 8852;
85 kgrp[10].root = 76; kgrp[10].high = 77; kgrp[10].pos = 468809; kgrp[10].end = 492772; kgrp[10].loop = 9693;
86 kgrp[11].root = 79; kgrp[11].high = 81; kgrp[11].pos = 492774; kgrp[11].end = 532293; kgrp[11].loop = 10596;
87 kgrp[12].root = 84; kgrp[12].high = 85; kgrp[12].pos = 532295; kgrp[12].end = 560192; kgrp[12].loop = 6011;
88 kgrp[13].root = 88; kgrp[13].high = 89; kgrp[13].pos = 560194; kgrp[13].end = 574121; kgrp[13].loop = 3414;
89 kgrp[14].root = 93; kgrp[14].high = 999; kgrp[14].pos = 574123; kgrp[14].end = 586343; kgrp[14].loop = 2399;
90 load_samples(&waves);
91
92 //initialise...
93 for(VstInt32 v=0; v<NVOICES; v++)
94 {
95 voice[v].env = 0.0f;
96 voice[v].dec = 0.99f; //all notes off
97 }
98 notes[0] = EVENTS_DONE;
99 volume = 0.2f;
100 muff = 160.0f;
101 cpos = sustain = activevoices = 0;
102 comb = new float[256];
103
104 update();
105 suspend();
106 }
107
108
109 void mdaPiano::update() //parameter change
110 {
111 float * param = programs[curProgram].param;
112 size = (VstInt32)(12.0f * param[2] - 6.0f);
113 sizevel = 0.12f * param[3];
114 muffvel = param[5] * param[5] * 5.0f;
115
116 velsens = 1.0f + param[6] + param[6];
117 if(param[6] < 0.25f) velsens -= 0.75f - 3.0f * param[6];
118
119 fine = param[9] - 0.5f;
120 random = 0.077f * param[10] * param[10];
121 stretch = 0.000434f * (param[11] - 0.5f);
122
123 cdep = param[7] * param[7];
124 trim = 1.50f - 0.79f * cdep;
125 width = 0.04f * param[7]; if(width > 0.03f) width = 0.03f;
126
127 poly = 8 + (VstInt32)(24.9f * param[8]);
128 }
129
130
131 void mdaPiano::resume()
132 {
133 Fs = getSampleRate();
134 iFs = 1.0f / Fs;
135 if(Fs > 64000.0f) cmax = 0xFF; else cmax = 0x7F;
136 memset(comb, 0, sizeof(float) * 256);
137
138 DECLARE_VST_DEPRECATED (wantEvents) ();
139 }
140
141
142 mdaPiano::~mdaPiano () //destroy any buffers...
143 {
144 if(programs) delete [] programs;
145 if(comb) delete[] comb;
146 }
147
148
149 void mdaPiano::setProgram(VstInt32 program)
150 {
151 curProgram = program;
152 update();
153 }
154
155
156 void mdaPiano::setParameter(VstInt32 index, float value)
157 {
158 programs[curProgram].param[index] = value;
159 update();
160 }
161
162
163 void mdaPiano::fillpatch(VstInt32 p, char *name, float p0, float p1, float p2, float p3, float p4,
164 float p5, float p6, float p7, float p8, float p9, float p10,float p11)
165 {
166 strcpy(programs[p].name, name);
167 programs[p].param[0] = p0; programs[p].param[1] = p1;
168 programs[p].param[2] = p2; programs[p].param[3] = p3;
169 programs[p].param[4] = p4; programs[p].param[5] = p5;
170 programs[p].param[6] = p6; programs[p].param[7] = p7;
171 programs[p].param[8] = p8; programs[p].param[9] = p9;
172 programs[p].param[10]= p10; programs[p].param[11] = p11;
173 }
174
175
176 float mdaPiano::getParameter(VstInt32 index) { return programs[curProgram].param[index]; }
177 void mdaPiano::setProgramName(char *name) { strcpy(programs[curProgram].name, name); }
178 void mdaPiano::getProgramName(char *name) { strcpy(name, programs[curProgram].name); }
179 void mdaPiano::setBlockSize(VstInt32 blockSize) { AudioEffectX::setBlockSize(blockSize); }
180
181
182 bool mdaPiano::copyProgram(VstInt32 destination)
183 {
184 if(destination<NPROGS)
185 {
186 programs[destination] = programs[curProgram];
187 return true;
188 }
189 return false;
190 }
191
192
193 void mdaPiano::getParameterName(VstInt32 index, char *label)
194 {
195 switch (index)
196 {
197 case 0: strcpy(label, "Envelope Decay"); break;
198 case 1: strcpy(label, "Envelope Release"); break;
199 case 2: strcpy(label, "Hardness Offset"); break;
200
201 case 3: strcpy(label, "Velocity to Hardness"); break;
202 case 4: strcpy(label, "Muffling Filter"); break;
203 case 5: strcpy(label, "Velocity to Muffling"); break;
204
205 case 6: strcpy(label, "Velocity Sensitivity"); break;
206 case 7: strcpy(label, "Stereo Width"); break;
207 case 8: strcpy(label, "Polyphony"); break;
208
209 case 9: strcpy(label, "Fine Tuning"); break;
210 case 10: strcpy(label, "Random Detuning"); break;
211 default: strcpy(label, "Stretch Tuning"); break;
212 }
213 }
214
215
216 void mdaPiano::getParameterDisplay(VstInt32 index, char *text)
217 {
218 char string[16];
219 float * param = programs[curProgram].param;
220
221 switch(index)
222 {
223 case 4: sprintf(string, "%.0f", 100.0f - 100.0f * param[index]); break;
224 case 7: sprintf(string, "%.0f", 200.0f * param[index]); break;
225 case 8: sprintf(string, "%d", poly); break;
226 case 10: sprintf(string, "%.1f", 50.0f * param[index] * param[index]); break;
227 case 2:
228 case 9:
229 case 11: sprintf(string, "%+.1f", 100.0f * param[index] - 50.0f); break;
230 default: sprintf(string, "%.0f", 100.0f * param[index]);
231 }
232 string[8] = 0;
233 strcpy(text, (char *)string);
234 }
235
236
237 void mdaPiano::getParameterLabel(VstInt32 index, char *label)
238 {
239 switch(index)
240 {
241 case 8: strcpy(label, "voices"); break;
242 case 9:
243 case 10:
244 case 11: strcpy(label, "cents"); break;
245 default: strcpy(label, "%");
246 }
247 }
248
249
250 void mdaPiano::process(float **inputs, float **outputs, VstInt32 sampleFrames)
251 {
252 float* out0 = outputs[0];
253 float* out1 = outputs[1];
254 VstInt32 event=0, frame=0, frames, v;
255 float x, l, r;
256 VstInt32 i;
257
258 while(frame<sampleFrames)
259 {
260 frames = notes[event++];
261 if(frames>sampleFrames) frames = sampleFrames;
262 frames -= frame;
263 frame += frames;
264
265 while(--frames>=0)
266 {
267 VOICE *V = voice;
268 l = r = 0.0f;
269
270 for(v=0; v<activevoices; v++)
271 {
272 V->frac += V->delta; //integer-based linear interpolation
273 V->pos += V->frac >> 16;
274 V->frac &= 0xFFFF;
275 if(V->pos > V->end) V->pos -= V->loop;
276 i = waves[V->pos];
277 i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000;
278 x = V->env * (*(float *)&i - 3.0f); //fast int->float
279
280 V->env = V->env * V->dec; //envelope
281 V->f0 += V->ff * (x + V->f1 - V->f0); //muffle filter
282 V->f1 = x;
283
284 l += V->outl * V->f0;
285 r += V->outr * V->f0;
286
287 V++;
288 }
289 comb[cpos] = l + r;
290 ++cpos &= cmax;
291 x = cdep * comb[cpos]; //stereo simulator
292
293 *out0++ += l + x;
294 *out1++ += r - x;
295 }
296
297 if(frame<sampleFrames)
298 {
299 VstInt32 note = notes[event++];
300 VstInt32 vel = notes[event++];
301 noteOn(note, vel);
302 }
303 }
304 for(v=0; v<activevoices; v++) if(voice[v].env < SILENCE) voice[v] = voice[--activevoices];
305 notes[0] = EVENTS_DONE; //mark events buffer as done
306 }
307
308
309 void mdaPiano::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames)
310 {
311 float* out0 = outputs[0];
312 float* out1 = outputs[1];
313 VstInt32 event=0, frame=0, frames, v;
314 float x, l, r;
315 VstInt32 i;
316
317 while(frame<sampleFrames)
318 {
319 frames = notes[event++];
320 if(frames>sampleFrames) frames = sampleFrames;
321 frames -= frame;
322 frame += frames;
323
324 while(--frames>=0)
325 {
326 VOICE *V = voice;
327 l = r = 0.0f;
328
329 for(v=0; v<activevoices; v++)
330 {
331 V->frac += V->delta; //integer-based linear interpolation
332 V->pos += V->frac >> 16;
333 V->frac &= 0xFFFF;
334 if(V->pos > V->end) V->pos -= V->loop;
335 //i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000; //not working on intel mac !?!
336 i = waves[V->pos] + ((V->frac * (waves[V->pos + 1] - waves[V->pos])) >> 16);
337 x = V->env * (float)i / 32768.0f;
338 //x = V->env * (*(float *)&i - 3.0f); //fast int->float
339
340 V->env = V->env * V->dec; //envelope
341 V->f0 += V->ff * (x + V->f1 - V->f0); //muffle filter
342 V->f1 = x;
343
344 l += V->outl * V->f0;
345 r += V->outr * V->f0;
346
347 if(!(l > -2.0f) || !(l < 2.0f))
348 {
349 printf("what is this shit? %d, %f, %f\n", i, x, V->f0);
350 l = 0.0f;
351 }
352 if(!(r > -2.0f) || !(r < 2.0f))
353 {
354 r = 0.0f;
355 }
356
357 V++;
358 }
359 comb[cpos] = l + r;
360 ++cpos &= cmax;
361 x = cdep * comb[cpos]; //stereo simulator
362
363 *out0++ = l + x;
364 *out1++ = r - x;
365 }
366
367 if(frame<sampleFrames)
368 {
369 VstInt32 note = notes[event++];
370 VstInt32 vel = notes[event++];
371 noteOn(note, vel);
372 }
373 }
374 for(v=0; v<activevoices; v++) if(voice[v].env < SILENCE) voice[v] = voice[--activevoices];
375 notes[0] = EVENTS_DONE; //mark events buffer as done
376 }
377
378
379 void mdaPiano::noteOn(VstInt32 note, VstInt32 velocity)
380 {
381 float * param = programs[curProgram].param;
382 float l=99.0f;
383 VstInt32 v, vl=0, k, s;
384
385 if(velocity>0)
386 {
387 if(activevoices < poly) //add a note
388 {
389 vl = activevoices;
390 activevoices++;
391 }
392 else //steal a note
393 {
394 for(v=0; v<poly; v++) //find quietest voice
395 {
396 if(voice[v].env < l) { l = voice[v].env; vl = v; }
397 }
398 }
399
400 k = (note - 60) * (note - 60);
401 l = fine + random * ((float)(k % 13) - 6.5f); //random & fine tune
402 if(note > 60) l += stretch * (float)k; //stretch
403
404 s = size;
405 if(velocity > 40) s += (VstInt32)(sizevel * (float)(velocity - 40));
406
407 k = 0;
408 while(note > (kgrp[k].high + s)) k++; //find keygroup
409
410 l += (float)(note - kgrp[k].root); //pitch
411 l = 22050.0f * iFs * (float)exp(0.05776226505 * l);
412 voice[vl].delta = (VstInt32)(65536.0f * l);
413 voice[vl].frac = 0;
414 voice[vl].pos = kgrp[k].pos;
415 voice[vl].end = kgrp[k].end;
416 voice[vl].loop = kgrp[k].loop;
417
418 voice[vl].env = (0.5f + velsens) * (float)pow(0.0078f * velocity, velsens); //velocity
419
420 l = 50.0f + param[4] * param[4] * muff + muffvel * (float)(velocity - 64); //muffle
421 if(l < (55.0f + 0.25f * (float)note)) l = 55.0f + 0.25f * (float)note;
422 if(l > 210.0f) l = 210.0f;
423 voice[vl].ff = l * l * iFs;
424 voice[vl].f0 = voice[vl].f1 = 0.0f;
425
426 voice[vl].note = note; //note->pan
427 if(note < 12) note = 12;
428 if(note > 108) note = 108;
429 l = volume * trim;
430 voice[vl].outr = l + l * width * (float)(note - 60);
431 voice[vl].outl = l + l - voice[vl].outr;
432
433 if(note < 44) note = 44; //limit max decay length
434 l = 2.0f * param[0];
435 if(l < 1.0f) l += 0.25f - 0.5f * param[0];
436 voice[vl].dec = (float)exp(-iFs * exp(-0.6 + 0.033 * (double)note - l));
437 }
438 else //note off
439 {
440 for(v=0; v<NVOICES; v++) if(voice[v].note==note) //any voices playing that note?
441 {
442 if(sustain==0)
443 {
444 if(note < 94 || note == SUSTAIN) //no release on highest notes
445 voice[v].dec = (float)exp(-iFs * exp(2.0 + 0.017 * (double)note - 2.0 * param[1]));
446 }
447 else voice[v].note = SUSTAIN;
448 }
449 }
450 }
451
452
453 VstInt32 mdaPiano::processEvents(VstEvents* ev)
454 {
455 VstInt32 npos=0;
456
457 for (VstInt32 i=0; i<ev->numEvents; i++)
458 {
459 if((ev->events[i])->type != kVstMidiType) continue;
460 VstMidiEvent* event = (VstMidiEvent*)ev->events[i];
461 char* midiData = event->midiData;
462
463 switch(midiData[0] & 0xf0) //status byte (all channels)
464 {
465 case 0x80: //note off
466 notes[npos++] = event->deltaFrames; //delta
467 notes[npos++] = midiData[1] & 0x7F; //note
468 notes[npos++] = 0; //vel
469 break;
470
471 case 0x90: //note on
472 notes[npos++] = event->deltaFrames; //delta
473 notes[npos++] = midiData[1] & 0x7F; //note
474 notes[npos++] = midiData[2] & 0x7F; //vel
475 break;
476
477 case 0xB0: //controller
478 switch(midiData[1])
479 {
480 case 0x01: //mod wheel
481 case 0x43: //soft pedal
482 muff = 0.01f * (float)((127 - midiData[2]) * (127 - midiData[2]));
483 break;
484
485 case 0x07: //volume
486 volume = 0.00002f * (float)(midiData[2] * midiData[2]);
487 break;
488
489 case 0x40: //sustain pedal
490 case 0x42: //sustenuto pedal
491 sustain = midiData[2] & 0x40;
492 if(sustain==0)
493 {
494 notes[npos++] = event->deltaFrames;
495 notes[npos++] = SUSTAIN; //end all sustained notes
496 notes[npos++] = 0;
497 }
498 break;
499
500 default: //all notes off
501 if(midiData[1]>0x7A)
502 {
503 for(VstInt32 v=0; v<NVOICES; v++) voice[v].dec=0.99f;
504 sustain = 0;
505 muff = 160.0f;
506 }
507 break;
508 }
509 break;
510
511 case 0xC0: //program change
512 if(midiData[1]<NPROGS) setProgram(midiData[1]);
513 break;
514
515 default: break;
516 }
517
518 if(npos>EVENTBUFFER) npos -= 3; //discard events if buffer full!!
519 event++; //?
520 }
521 notes[npos] = EVENTS_DONE;
522 return 1;
523 }
524
525
526 void mdaPiano::load_samples(short **buffer)
527 {
528 FILE *f;
529 long num, size;
530 char filepath[STRING_BUF];
531
532 strncpy(filepath, bundle_path(), STRING_BUF);
533 strncat(filepath,
534 sample_file,
535 STRING_BUF - strlen(filepath));
536 f = fopen(filepath, "rb");
537 if (f == NULL) {
538 fputs("File error", stderr);
539 exit(1);
540 }
541
542 // obtain file size
543 fseek(f, 0, SEEK_END);
544 size = ftell(f);
545 rewind(f);
546
547 // allocate memory to contain the whole file
548 *buffer = (short*) malloc (sizeof(short)*size);
549 if (*buffer == NULL) {
550 fputs("Memory error", stderr);
551 exit(2);
552 }
553
554 // copy the file into the buffer
555 num = fread(*buffer, 1, size, f);
556 if (num != size) {
557 fputs ("Reading error", stderr);
558 exit (3);
559 }
560 fclose (f);
561 return;
562 }