move `process` to voice
[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 "mdaPianoCommon.h"
17 #include "mdaPiano.h"
18
19 #include <stdio.h>
20 #include <math.h>
21
22 #define STRING_BUF 2048
23 static const char* sample_file = "samples.raw";
24
25
26 mdaPiano::mdaPiano(double rate)
27 : LV2::Synth<mdaPianoVoice, mdaPiano>(p_n_ports, p_midi) {
28
29 cmax = 0x7F; //just in case...
30
31 load_samples(&waves);
32 load_kgrp(kgrp);
33
34 for(uint32_t i=0; i<NVOICES; ++i) {
35 voices[i] = new mdaPianoVoice(rate, waves, kgrp);
36 add_voices(voices[i]);
37 }
38
39 notes[0] = EVENTS_DONE;
40 cpos = sustain = activevoices = 0;
41 comb = new float[256];
42
43 update();
44 suspend();
45 }
46
47
48 void mdaPiano::update() //parameter change
49 {
50 float * param = programs[curProgram].param;
51 size = (uint32_t)(12.0f * param[2] - 6.0f);
52 sizevel = 0.12f * param[3];
53 muffvel = param[5] * param[5] * 5.0f;
54
55 velsens = 1.0f + param[6] + param[6];
56 if(param[6] < 0.25f) velsens -= 0.75f - 3.0f * param[6];
57
58 fine = param[9] - 0.5f;
59 random = 0.077f * param[10] * param[10];
60 stretch = 0.000434f * (param[11] - 0.5f);
61
62 cdep = param[7] * param[7];
63 trim = 1.50f - 0.79f * cdep;
64 width = 0.04f * param[7]; if(width > 0.03f) width = 0.03f;
65
66 poly = 8 + (uint32_t)(24.9f * param[8]);
67 }
68
69
70 void mdaPiano::resume()
71 {
72 Fs = getSampleRate();
73 iFs = 1.0f / Fs;
74 if(Fs > 64000.0f) cmax = 0xFF; else cmax = 0x7F;
75 memset(comb, 0, sizeof(float) * 256);
76 }
77
78
79 void mdaPiano::setParameter(uint32_t index, float value)
80 {
81 programs[curProgram].param[index] = value;
82 update();
83 }
84
85
86 uint32_t mdaPiano::processEvents(VstEvents* ev)
87 {
88 uint32_t npos=0;
89
90 for (uint32_t i=0; i<ev->numEvents; i++)
91 {
92 if((ev->events[i])->type != kVstMidiType) continue;
93 VstMidiEvent* event = (VstMidiEvent*)ev->events[i];
94 char* midiData = event->midiData;
95
96 switch(midiData[0] & 0xf0) //status byte (all channels)
97 {
98 case 0x80: //note off
99 notes[npos++] = event->deltaFrames; //delta
100 notes[npos++] = midiData[1] & 0x7F; //note
101 notes[npos++] = 0; //vel
102 break;
103
104 case 0x90: //note on
105 notes[npos++] = event->deltaFrames; //delta
106 notes[npos++] = midiData[1] & 0x7F; //note
107 notes[npos++] = midiData[2] & 0x7F; //vel
108 break;
109
110 case 0xB0: //controller
111 switch(midiData[1])
112 {
113 case 0x01: //mod wheel
114 case 0x43: //soft pedal
115 muff = 0.01f * (float)((127 - midiData[2]) * (127 - midiData[2]));
116 break;
117
118 case 0x07: //volume
119 volume = 0.00002f * (float)(midiData[2] * midiData[2]);
120 break;
121
122 case 0x40: //sustain pedal
123 case 0x42: //sustenuto pedal
124 sustain = midiData[2] & 0x40;
125 if(sustain==0)
126 {
127 notes[npos++] = event->deltaFrames;
128 notes[npos++] = SUSTAIN; //end all sustained notes
129 notes[npos++] = 0;
130 }
131 break;
132
133 //all sound off
134 case 0x78:
135 //all notes off
136 case 0x7b:
137 default:
138 for(short v=0; v<NVOICES; v++) {
139 voices[v]->reset();
140 }
141 break;
142 }
143 break;
144
145 default: break;
146 }
147
148 if(npos>EVENTBUFFER) npos -= 3; //discard events if buffer full!!
149 event++; //?
150 }
151 notes[npos] = EVENTS_DONE;
152 return 1;
153 }
154
155
156 // TODO: load this from a file
157 void mdaPiano::load_kgrp(KGRP *kgrp)
158 {
159 //Waveform data and keymapping is hard-wired in *this* version
160 kgrp[ 0].root = 36; kgrp[ 0].high = 37; kgrp[ 0].pos = 0; kgrp[ 0].end = 36275; kgrp[ 0].loop = 14774;
161 kgrp[ 1].root = 40; kgrp[ 1].high = 41; kgrp[ 1].pos = 36278; kgrp[ 1].end = 83135; kgrp[ 1].loop = 16268;
162 kgrp[ 2].root = 43; kgrp[ 2].high = 45; kgrp[ 2].pos = 83137; kgrp[ 2].end = 146756; kgrp[ 2].loop = 33541;
163 kgrp[ 3].root = 48; kgrp[ 3].high = 49; kgrp[ 3].pos = 146758; kgrp[ 3].end = 204997; kgrp[ 3].loop = 21156;
164 kgrp[ 4].root = 52; kgrp[ 4].high = 53; kgrp[ 4].pos = 204999; kgrp[ 4].end = 244908; kgrp[ 4].loop = 17191;
165 kgrp[ 5].root = 55; kgrp[ 5].high = 57; kgrp[ 5].pos = 244910; kgrp[ 5].end = 290978; kgrp[ 5].loop = 23286;
166 kgrp[ 6].root = 60; kgrp[ 6].high = 61; kgrp[ 6].pos = 290980; kgrp[ 6].end = 342948; kgrp[ 6].loop = 18002;
167 kgrp[ 7].root = 64; kgrp[ 7].high = 65; kgrp[ 7].pos = 342950; kgrp[ 7].end = 391750; kgrp[ 7].loop = 19746;
168 kgrp[ 8].root = 67; kgrp[ 8].high = 69; kgrp[ 8].pos = 391752; kgrp[ 8].end = 436915; kgrp[ 8].loop = 22253;
169 kgrp[ 9].root = 72; kgrp[ 9].high = 73; kgrp[ 9].pos = 436917; kgrp[ 9].end = 468807; kgrp[ 9].loop = 8852;
170 kgrp[10].root = 76; kgrp[10].high = 77; kgrp[10].pos = 468809; kgrp[10].end = 492772; kgrp[10].loop = 9693;
171 kgrp[11].root = 79; kgrp[11].high = 81; kgrp[11].pos = 492774; kgrp[11].end = 532293; kgrp[11].loop = 10596;
172 kgrp[12].root = 84; kgrp[12].high = 85; kgrp[12].pos = 532295; kgrp[12].end = 560192; kgrp[12].loop = 6011;
173 kgrp[13].root = 88; kgrp[13].high = 89; kgrp[13].pos = 560194; kgrp[13].end = 574121; kgrp[13].loop = 3414;
174 kgrp[14].root = 93; kgrp[14].high = 999; kgrp[14].pos = 574123; kgrp[14].end = 586343; kgrp[14].loop = 2399;
175 }
176
177
178 void mdaPiano::load_samples(short **buffer)
179 {
180 FILE *f;
181 long num, size;
182 char filepath[STRING_BUF];
183
184 strncpy(filepath, bundle_path(), STRING_BUF);
185 strncat(filepath,
186 sample_file,
187 STRING_BUF - strlen(filepath));
188 f = fopen(filepath, "rb");
189 if (f == NULL) {
190 fputs("File error", stderr);
191 exit(1);
192 }
193
194 // obtain file size
195 fseek(f, 0, SEEK_END);
196 size = ftell(f);
197 rewind(f);
198
199 // allocate memory to contain the whole file
200 *buffer = (short*) malloc (sizeof(short)*size);
201 if (*buffer == NULL) {
202 fputs("Memory error", stderr);
203 exit(2);
204 }
205
206 // copy the file into the buffer
207 num = fread(*buffer, 1, size, f);
208 if (num != size) {
209 fputs ("Reading error", stderr);
210 exit (3);
211 }
212 fclose (f);
213 return;
214 }