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