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