]> git.elephly.net Git - software/lv2-mdametapiano.git/blob - src/mdaPiano.cpp
crudely merge mdaEPiano and mdaPiano
[software/lv2-mdametapiano.git] / src / mdaPiano.cpp
1 /* ======================================================
2 * LV2 port of the popular mda Piano and mda EPiano VSTi
3 * ======================================================
4 *
5 * Port
6 * Author: Ricardo Wurmus (rekado)
7 * Based on: mda-vst-src-2010-02-14.zip
8 *
9 * mda Piano / mda EPiano
10 * Copyright(c)1999-2000 Paul Kellett (maxim digital audio)
11 *
12 * ==================================================
13 */
14
15 #include "mdaPianoCommon.h"
16 #include "mdaPiano.h"
17 #include <cstdlib> //for exit
18
19 #define STRING_BUF 2048
20
21 mdaPiano::mdaPiano(double rate)
22 : lvtk::Synth<mdaPianoVoice, mdaPiano>(p_n_ports, p_midi) {
23
24 sustain = 0;
25
26 #ifdef PIANO
27 static const char* sample_names[] =
28 { "0c.raw", "0e.raw", "0g.raw"
29 , "1c.raw", "1e.raw", "1g.raw"
30 , "2c.raw", "2e.raw", "2g.raw"
31 , "3c.raw", "3e.raw", "3g.raw"
32 , "4c.raw", "4e.raw", "4a.raw"
33 };
34 #elif defined EPIANO
35 static const char* sample_names[] =
36 { "0c-0.raw", "0c-1.raw", "0c-2.raw"
37 , "0g-0.raw", "0g-1.raw", "0g-2.raw"
38 , "1c-0.raw", "1c-1.raw", "1c-2.raw"
39 , "1g-0.raw", "1g-1.raw", "1g-2.raw"
40 , "2c-0.raw", "2c-1.raw", "2c-2.raw"
41 , "2g-0.raw", "2g-1.raw", "2g-2.raw"
42 , "3c-0.raw", "3c-1.raw", "3c-2.raw"
43 , "3g-0.raw", "3g-1.raw", "3g-2.raw"
44 , "4c-0.raw", "4c-1.raw", "4c-2.raw"
45 , "4g-0.raw", "4g-1.raw", "4g-2.raw"
46 , "5c-0.raw", "5c-1.raw", "5c-2.raw"
47 };
48 #endif
49
50 for (unsigned char i=0; i<NSAMPLES; ++i) {
51 load_sample(&samples[i], sample_names[i]);
52 }
53
54 load_kgrp(kgrp);
55 #ifdef EPIANO
56 tweak_samples();
57 #endif
58
59 for(uint32_t i=0; i<NVOICES; ++i) {
60 voices[i] = new mdaPianoVoice(rate, samples, kgrp);
61 add_voices(voices[i]);
62 }
63
64 add_audio_outputs(p_left, p_right);
65 }
66
67
68 unsigned mdaPiano::find_free_voice(unsigned char key, unsigned char velocity) {
69 //is this a retriggered note during sustain?
70 if (sustain) {
71 for (unsigned i = 0; i < NVOICES; ++i) {
72 if ((voices[i]->get_key() == key) && (voices[i]->is_sustained())) {
73 return i;
74 }
75 }
76 }
77
78 //take the next free voice if
79 // ... notes are sustained but not this new one
80 // ... notes are not sustained
81 for (unsigned i = 0; i < NVOICES; ++i) {
82 if (voices[i]->get_key() == lvtk::INVALID_KEY)
83 {
84 return i;
85 }
86 }
87
88 //TODO: steal quietest note if all voices are used up
89 return 0;
90 }
91
92
93 void mdaPiano::setVolume(float value) {
94 for (uint32_t v=0; v<NVOICES; ++v)
95 voices[v]->set_volume(value);
96 }
97
98
99 //parameter change
100 void mdaPiano::update() {
101 for (uint32_t v=0; v<NVOICES; ++v) {
102 voices[v]->update(Current);
103 }
104 }
105
106
107 void mdaPiano::handle_midi(uint32_t size, unsigned char* data) {
108 #ifdef DEBUG
109 printf("%d\n", data[1]);
110 #endif
111
112 //discard invalid midi messages
113 if (size != 3)
114 return;
115
116 //receive on all channels
117 switch(data[0] & 0xf0)
118 {
119 case 0x80: //note off
120 for (unsigned i = 0; i < NVOICES; ++i) {
121 if (voices[i]->get_key() == data[1]) {
122 voices[i]->release(data[2]);
123 break;
124 }
125 }
126 break;
127
128 case 0x90: //note on
129 voices[ find_free_voice(data[1], data[2]) ]->on(data[1], data[2]);
130 break;
131
132 case 0xE0: break; //TODO: pitch bend
133
134 //controller
135 case 0xB0:
136 switch(data[1])
137 {
138 #ifdef PIANO
139 case 0x01: //mod wheel
140 case 0x43: //soft pedal
141 {
142 float muff = 0.01f * (float)((127 - data[2]) * (127 - data[2]));
143 for (unsigned i = 0; i < NVOICES; ++i) {
144 voices[i]->set_muff(muff);
145 }
146 break;
147 }
148 #elif defined EPIANO
149 case 0x01: //mod wheel
150 //scale the mod value to cover the range [0..1]
151 *p(p_modulation) = scale_midi_to_f(data[2]);
152 break;
153 #endif
154
155 case 0x07: //volume
156 setVolume(0.00002f * (float)(data[2] * data[2]));
157 break;
158
159 case 0x40: //sustain pedal
160 case 0x42: //sostenuto pedal
161 sustain = data[2] & 0x40;
162
163 for (unsigned i = 0; i < NVOICES; ++i) {
164 voices[i]->set_sustain(sustain);
165 //if pedal was released: dampen sustained notes
166 if((sustain==0) && (voices[i]->is_sustained())) {
167 voices[i]->release(0);
168 }
169 }
170 break;
171
172 //all sound off
173 case 0x78:
174 //all notes off
175 case 0x7b:
176 for(short v=0; v<NVOICES; v++) {
177 voices[v]->reset();
178 }
179 break;
180
181 default: break;
182 }
183 break;
184
185 default: break;
186 }
187 }
188
189
190 void mdaPiano::load_sample(Sample *s, const char* name) {
191 FILE *f;
192 long num, size;
193 char filepath[STRING_BUF];
194
195 strncpy(filepath, bundle_path(), STRING_BUF);
196 strncat(filepath,
197 name,
198 STRING_BUF - strlen(filepath));
199 f = fopen(filepath, "rb");
200 if (f == NULL) {
201 fputs("File error", stderr);
202 exit(1);
203 }
204
205 // obtain file size
206 fseek(f, 0, SEEK_END);
207 size = ftell(f);
208 rewind(f);
209
210 // allocate memory to contain the whole file
211 s->buffer = (short*) malloc (sizeof(short)*size);
212 if (s->buffer == NULL) {
213 fputs("Memory error", stderr);
214 exit(2);
215 }
216
217 // copy the file into the buffer
218 num = fread(s->buffer, 1, size, f);
219 if (num != size) {
220 fputs ("Reading error", stderr);
221 exit (3);
222 }
223 fclose (f);
224
225 // 16 bit
226 s->size = size / 2;
227
228 return;
229 }
230
231
232 // TODO: load keymapping from a file
233 void mdaPiano::load_kgrp(KGRP *kgrp) {
234 #ifdef PIANO
235 kgrp[ 0].root = 36; kgrp[ 0].high = 37; kgrp[ 0].loop = 14774;
236 kgrp[ 1].root = 40; kgrp[ 1].high = 41; kgrp[ 1].loop = 16268;
237 kgrp[ 2].root = 43; kgrp[ 2].high = 45; kgrp[ 2].loop = 33541;
238 kgrp[ 3].root = 48; kgrp[ 3].high = 49; kgrp[ 3].loop = 21156;
239 kgrp[ 4].root = 52; kgrp[ 4].high = 53; kgrp[ 4].loop = 17191;
240 kgrp[ 5].root = 55; kgrp[ 5].high = 57; kgrp[ 5].loop = 23286;
241 kgrp[ 6].root = 60; kgrp[ 6].high = 61; kgrp[ 6].loop = 18002;
242 kgrp[ 7].root = 64; kgrp[ 7].high = 65; kgrp[ 7].loop = 19746;
243 kgrp[ 8].root = 67; kgrp[ 8].high = 69; kgrp[ 8].loop = 22253;
244 kgrp[ 9].root = 72; kgrp[ 9].high = 73; kgrp[ 9].loop = 8852;
245 kgrp[10].root = 76; kgrp[10].high = 77; kgrp[10].loop = 9693;
246 kgrp[11].root = 79; kgrp[11].high = 81; kgrp[11].loop = 10596;
247 kgrp[12].root = 84; kgrp[12].high = 85; kgrp[12].loop = 6011;
248 kgrp[13].root = 88; kgrp[13].high = 89; kgrp[13].loop = 3414;
249 kgrp[14].root = 93; kgrp[14].high = 999; kgrp[14].loop = 2399;
250 #elif defined EPIANO
251 kgrp[ 0].root = 36; kgrp[ 0].high = 39; //C1
252 kgrp[ 3].root = 43; kgrp[ 3].high = 45; //G1
253 kgrp[ 6].root = 48; kgrp[ 6].high = 51; //C2
254 kgrp[ 9].root = 55; kgrp[ 9].high = 57; //G2
255 kgrp[12].root = 60; kgrp[12].high = 63; //C3
256 kgrp[15].root = 67; kgrp[15].high = 69; //G3
257 kgrp[18].root = 72; kgrp[18].high = 75; //C4
258 kgrp[21].root = 79; kgrp[21].high = 81; //G4
259 kgrp[24].root = 84; kgrp[24].high = 87; //C5
260 kgrp[27].root = 91; kgrp[27].high = 93; //G5
261 kgrp[30].root = 96; kgrp[30].high =999; //C6
262
263 kgrp[0].loop = 4400;
264 kgrp[1].loop = 4903;
265 kgrp[2].loop = 6398;
266 kgrp[3].loop = 3938;
267 kgrp[4].loop = 1633; //was 1636
268 kgrp[5].loop = 5245;
269 kgrp[6].loop = 2937;
270 kgrp[7].loop = 2203; //was 2204
271 kgrp[8].loop = 6368;
272 kgrp[9].loop = 10452;
273 kgrp[10].loop = 5217; //was 5220
274 kgrp[11].loop = 3099;
275 kgrp[12].loop = 4284;
276 kgrp[13].loop = 3916;
277 kgrp[14].loop = 2937;
278 kgrp[15].loop = 4732;
279 kgrp[16].loop = 4733;
280 kgrp[17].loop = 2285;
281 kgrp[18].loop = 4098;
282 kgrp[19].loop = 4099;
283 kgrp[20].loop = 3609;
284 kgrp[21].loop = 2446;
285 kgrp[22].loop = 6278;
286 kgrp[23].loop = 2283;
287 kgrp[24].loop = 2689;
288 kgrp[25].loop = 4370;
289 kgrp[26].loop = 5225;
290 kgrp[27].loop = 2811;
291 kgrp[28].loop = 2811; //ghost
292 kgrp[29].loop = 4522;
293 kgrp[30].loop = 2306;
294 kgrp[31].loop = 2306; //ghost
295 kgrp[32].loop = 2169;
296 #endif
297 }
298
299
300 #ifdef EPIANO
301 void mdaPiano::tweak_samples() {
302 //extra xfade looping...
303 for(uint32_t k=0; k<28; k++)
304 {
305 long p0 = samples[k].size;
306 long p1 = samples[k].size - kgrp[k].loop;
307
308 float xf = 1.0f;
309 float dxf = -0.02f;
310
311 while(xf > 0.0f)
312 {
313 samples[k].buffer[p0] = (short)((1.0f - xf) * (float)samples[k].buffer[p0] + xf * (float)samples[k].buffer[p1]);
314 p0--;
315 p1--;
316 xf += dxf;
317 }
318 }
319 }
320 #endif
321
322 static int _ = mdaPiano::register_class(p_uri);