move mdaPiano::noteOn to mdaPianoVoice::on
[software/lv2-mdametapiano.git] / src / mdaPianoVoice.cpp
1 #include "mdaPianoVoice.h"
2
3 mdaPianoVoice::mdaPianoVoice(double rate, short * samples, KGRP * master_kgrp) {
4 //set tuning
5 Fs = rate;
6 iFs = 1.0f/Fs;
7
8 waves = samples;
9 kgrp = master_kgrp;
10
11 default_preset[p_offset(p_envelope_decay)] = 0.500f;
12 default_preset[p_offset(p_envelope_release)] = 0.500f;
13 default_preset[p_offset(p_hardness_offset)] = 0.500f;
14 default_preset[p_offset(p_velocity_to_hardness)] = 0.500f;
15 default_preset[p_offset(p_muffling_filter)] = 0.803f;
16 default_preset[p_offset(p_velocity_to_muffling)] = 0.251f;
17 default_preset[p_offset(p_velocity_sensitivity)] = 0.376f;
18 default_preset[p_offset(p_stereo_width)] = 0.500f;
19 default_preset[p_offset(p_polyphony)] = 0.330f;
20 default_preset[p_offset(p_fine_tuning)] = 0.500f;
21 default_preset[p_offset(p_random_detuning)] = 0.246f;
22 default_preset[p_offset(p_stretch_tuning)] = 0.500f;
23
24 reset();
25 }
26
27
28 void mdaPianoVoice::reset() {
29 env = 0.0f;
30 dec = 0.99f;
31 muff = 160.0f;
32 volume = 0.2f;
33 }
34
35
36 float mdaPianoVoice::p_helper(unsigned short id, Param d) {
37 if (d == Default)
38 return default_preset[p_offset(id)];
39 else
40 return *p(id);
41 }
42
43
44 mdaPianoVoice::on(unsigned char note, unsigned char velocity)
45 {
46 // TODO: replace with this voice's local copy
47 float * param = programs[curProgram].param;
48 float l=99.0f;
49 uint32_t v, vl=0, k, s;
50
51 if(velocity>0)
52 {
53 // TODO: move this to mdaPiano.cpp
54 /*
55 if(activevoices < poly) //add a note
56 {
57 vl = activevoices;
58 activevoices++;
59 }
60 else //steal a note
61 {
62 for(v=0; v<poly; v++) //find quietest voice
63 {
64 if(voice[v].env < l) { l = voice[v].env; vl = v; }
65 }
66 }
67 */
68
69 k = (note - 60) * (note - 60);
70 l = fine + random * ((float)(k % 13) - 6.5f); //random & fine tune
71 if(note > 60) l += stretch * (float)k; //stretch
72
73 s = size;
74 if(velocity > 40) s += (uint32_t)(sizevel * (float)(velocity - 40));
75
76 k = 0;
77 while(note > (kgrp[k].high + s)) k++; //find keygroup
78
79 l += (float)(note - kgrp[k].root); //pitch
80 l = 22050.0f * iFs * (float)exp(0.05776226505 * l);
81 voice[vl].delta = (uint32_t)(65536.0f * l);
82 voice[vl].frac = 0;
83 voice[vl].pos = kgrp[k].pos;
84 voice[vl].end = kgrp[k].end;
85 voice[vl].loop = kgrp[k].loop;
86
87 voice[vl].env = (0.5f + velsens) * (float)pow(0.0078f * velocity, velsens); //velocity
88
89 l = 50.0f + param[4] * param[4] * muff + muffvel * (float)(velocity - 64); //muffle
90 if(l < (55.0f + 0.25f * (float)note)) l = 55.0f + 0.25f * (float)note;
91 if(l > 210.0f) l = 210.0f;
92 voice[vl].ff = l * l * iFs;
93 voice[vl].f0 = voice[vl].f1 = 0.0f;
94
95 voice[vl].note = note; //note->pan
96 if(note < 12) note = 12;
97 if(note > 108) note = 108;
98 l = volume * trim;
99 voice[vl].outr = l + l * width * (float)(note - 60);
100 voice[vl].outl = l + l - voice[vl].outr;
101
102 if(note < 44) note = 44; //limit max decay length
103 l = 2.0f * param[0];
104 if(l < 1.0f) l += 0.25f - 0.5f * param[0];
105 voice[vl].dec = (float)exp(-iFs * exp(-0.6 + 0.033 * (double)note - l));
106 }
107 else //note off
108 {
109 // TODO: move the loop to mdaPiano.cpp
110 for(v=0; v<NVOICES; v++) if(voice[v].note==note) //any voices playing that note?
111 {
112 if(sustain==0)
113 {
114 if(note < 94 || note == SUSTAIN) //no release on highest notes
115 voice[v].dec = (float)exp(-iFs * exp(2.0 + 0.017 * (double)note - 2.0 * param[1]));
116 }
117 else voice[v].note = SUSTAIN;
118 }
119 }
120 }