load individual samples
[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 #include <cstdlib> //for exit
19
20 #include <stdio.h>
21 #include <math.h>
22
23 #define STRING_BUF 2048
24
25 mdaPiano::mdaPiano(double rate)
26 : LV2::Synth<mdaPianoVoice, mdaPiano>(p_n_ports, p_midi) {
27
28 static const char* sample_names[] =
29 { "0c.raw", "0e.raw", "0g.raw"
30 , "1c.raw", "1e.raw", "1g.raw"
31 , "2c.raw", "2e.raw", "2g.raw"
32 , "3c.raw", "3e.raw", "3g.raw"
33 , "4c.raw", "4e.raw", "4a.raw"
34 };
35
36 for (unsigned char i=0; i<15; ++i) {
37 load_sample(&samples[i], sample_names[i]);
38 }
39
40 load_kgrp(kgrp);
41
42 for(uint32_t i=0; i<NVOICES; ++i) {
43 voices[i] = new mdaPianoVoice(rate, samples, kgrp);
44 add_voices(voices[i]);
45 }
46
47 sustain = 0;
48
49 add_audio_outputs(p_left, p_right);
50 }
51
52 //parameter change
53 void mdaPiano::update() {
54 for (uint32_t v=0; v<NVOICES; ++v) {
55 voices[v]->update(Current);
56 }
57 }
58
59
60 unsigned mdaPiano::find_free_voice(unsigned char key, unsigned char velocity) {
61 //is this a retriggered note during sustain?
62 if (sustain) {
63 for (unsigned i = 0; i < NVOICES; ++i) {
64 if ((voices[i]->get_key() == key) && (voices[i]->is_sustained())) {
65 return i;
66 }
67 }
68 }
69
70 //take the next free voice if
71 // ... notes are sustained but not this new one
72 // ... notes are not sustained
73 for (unsigned i = 0; i < NVOICES; ++i) {
74 if (voices[i]->get_key() == LV2::INVALID_KEY)
75 {
76 return i;
77 }
78 }
79
80 //TODO: steal quietest note if all voices are used up
81 return 0;
82 }
83
84
85 void mdaPiano::setVolume(float value)
86 {
87 for (uint32_t v=0; v<NVOICES; ++v)
88 voices[v]->set_volume(value);
89 }
90
91
92 void mdaPiano::setParameter(unsigned char id, float value)
93 {
94 if(id>=NPARAMS)
95 return;
96 *p(id+PARAM_OFFSET) = value;
97 update();
98 #ifdef DEBUG
99 printf("changed %i to %f\n", id, value);
100 #endif
101 }
102
103
104 void mdaPiano::handle_midi(uint32_t size, unsigned char* data) {
105 #ifdef DEBUG
106 printf("%d\n", data[1]);
107 #endif
108
109 //discard invalid midi messages
110 if (size != 3)
111 return;
112
113 //receive on all channels
114 switch(data[0] & 0xf0)
115 {
116 case 0x80: //note off
117 for (unsigned i = 0; i < NVOICES; ++i) {
118 if (voices[i]->get_key() == data[1]) {
119 voices[i]->release(data[2]);
120 break;
121 }
122 }
123 break;
124
125 case 0x90: //note on
126 {
127 unsigned int v = find_free_voice(data[1], data[2]);
128 if (v < NVOICES) {
129 voices[v]->on(data[1], data[2]);
130 }
131 break;
132 }
133
134 case 0xB0: //controller
135 switch(data[1])
136 {
137 case 0x01: //mod wheel
138 case 0x43: //soft pedal
139 {
140 float muff = 0.01f * (float)((127 - data[2]) * (127 - data[2]));
141 for (unsigned i = 0; i < NVOICES; ++i) {
142 voices[i]->set_muff(muff);
143 }
144 break;
145 }
146
147 case 0x07: //volume
148 setVolume(0.00002f * (float)(data[2] * data[2]));
149 break;
150
151 case 0x40: //sustain pedal
152 case 0x42: //sustenuto pedal
153 sustain = data[2] & 0x40;
154
155 for (unsigned i = 0; i < NVOICES; ++i) {
156 voices[i]->set_sustain(sustain);
157 //if pedal was released: dampen sustained notes
158 if((sustain==0) && (voices[i]->is_sustained())) {
159 voices[i]->release(0);
160 }
161 }
162 break;
163
164 //all sound off
165 case 0x78:
166 //all notes off
167 case 0x7b:
168 default:
169 for(short v=0; v<NVOICES; v++) {
170 voices[v]->reset();
171 }
172 break;
173 }
174 break;
175
176 default: break;
177 }
178 }
179
180
181 // TODO: load keymapping from a file
182 void mdaPiano::load_kgrp(KGRP *kgrp)
183 {
184 kgrp[ 0].root = 36; kgrp[ 0].high = 37; kgrp[ 0].loop = 14774;
185 kgrp[ 1].root = 40; kgrp[ 1].high = 41; kgrp[ 1].loop = 16268;
186 kgrp[ 2].root = 43; kgrp[ 2].high = 45; kgrp[ 2].loop = 33541;
187 kgrp[ 3].root = 48; kgrp[ 3].high = 49; kgrp[ 3].loop = 21156;
188 kgrp[ 4].root = 52; kgrp[ 4].high = 53; kgrp[ 4].loop = 17191;
189 kgrp[ 5].root = 55; kgrp[ 5].high = 57; kgrp[ 5].loop = 23286;
190 kgrp[ 6].root = 60; kgrp[ 6].high = 61; kgrp[ 6].loop = 18002;
191 kgrp[ 7].root = 64; kgrp[ 7].high = 65; kgrp[ 7].loop = 19746;
192 kgrp[ 8].root = 67; kgrp[ 8].high = 69; kgrp[ 8].loop = 22253;
193 kgrp[ 9].root = 72; kgrp[ 9].high = 73; kgrp[ 9].loop = 8852;
194 kgrp[10].root = 76; kgrp[10].high = 77; kgrp[10].loop = 9693;
195 kgrp[11].root = 79; kgrp[11].high = 81; kgrp[11].loop = 10596;
196 kgrp[12].root = 84; kgrp[12].high = 85; kgrp[12].loop = 6011;
197 kgrp[13].root = 88; kgrp[13].high = 89; kgrp[13].loop = 3414;
198 kgrp[14].root = 93; kgrp[14].high = 999; kgrp[14].loop = 2399;
199 }
200
201
202 void mdaPiano::load_sample(Sample *s, const char* name)
203 {
204 FILE *f;
205 long num, size;
206 char filepath[STRING_BUF];
207
208 strncpy(filepath, bundle_path(), STRING_BUF);
209 strncat(filepath,
210 name,
211 STRING_BUF - strlen(filepath));
212 f = fopen(filepath, "rb");
213 if (f == NULL) {
214 fputs("File error", stderr);
215 exit(1);
216 }
217
218 // obtain file size
219 fseek(f, 0, SEEK_END);
220 size = ftell(f);
221 rewind(f);
222
223 // allocate memory to contain the whole file
224 s->buffer = (short*) malloc (sizeof(short)*size);
225 if (s->buffer == NULL) {
226 fputs("Memory error", stderr);
227 exit(2);
228 }
229
230 // copy the file into the buffer
231 num = fread(s->buffer, 1, size, f);
232 if (num != size) {
233 fputs ("Reading error", stderr);
234 exit (3);
235 }
236 fclose (f);
237
238 // 16 bit
239 s->size = size / 2;
240
241 return;
242 }
243
244 static int _ = mdaPiano::register_class(p_uri);