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