1 #include "mdaPianoVoice.h"
3 mdaPianoVoice::mdaPianoVoice(double rate
, short * samples
, KGRP
* master_kgrp
) {
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
;
29 void mdaPianoVoice::reset() {
36 m_key
= LV2::INVALID_KEY
;
40 float mdaPianoVoice::p_helper(unsigned short id
, Param d
) {
42 return default_preset
[p_offset(id
)];
48 void mdaPianoVoice::on(unsigned char note
, unsigned char velocity
)
50 // store key that turned this voice on (used in 'get_key')
59 k
= (note
- 60) * (note
- 60);
60 l
= fine
+ random
* ((float)(k
% 13) - 6.5f
); //random & fine tune
61 if(note
> 60) l
+= stretch
* (float)k
; //stretch
64 if(velocity
> 40) s
+= (uint32_t)(sizevel
* (float)(velocity
- 40));
67 while(note
> (kgrp
[k
].high
+ s
)) k
++; //find keygroup
69 l
+= (float)(note
- kgrp
[k
].root
); //pitch
70 l
= 22050.0f
* iFs
* (float)exp(0.05776226505 * l
);
71 delta
= (uint32_t)(65536.0f
* l
);
77 env
= (0.5f
+ velsens
) * (float)pow(0.0078f
* velocity
, velsens
); //velocity
79 l
= 50.0f
+ *p(p_muffling_filter
) * *p(p_muffling_filter
) * muff
+ muffvel
* (float)(velocity
- 64); //muffle
80 if(l
< (55.0f
+ 0.25f
* (float)note
)) l
= 55.0f
+ 0.25f
* (float)note
;
81 if(l
> 210.0f
) l
= 210.0f
;
85 if(note
< 12) note
= 12;
86 if(note
> 108) note
= 108;
88 outr
= l
+ l
* width
* (float)(note
- 60);
91 if(note
< 44) note
= 44; //limit max decay length
92 l
= 2.0f
* *p(p_envelope_decay
);
93 if(l
< 1.0f
) l
+= 0.25f
- 0.5f
* *p(p_envelope_decay
);
94 dec
= (float)exp(-iFs
* exp(-0.6 + 0.033 * (double)note
- l
));
103 void mdaPianoVoice::release(unsigned char velocity
)
106 //no release on highest notes
107 if(m_key
< 94 || m_key
== SUSTAIN
) {
108 dec
= (float)exp(-iFs
* exp(2.0 + 0.017 * (double)m_key
- 2.0 * *p(p_envelope_release
)));
114 //Mark the voice to be turned off later. It may not be set to
115 //INVALID_KEY yet, because the release sound still needs to be
116 //rendered. m_key is finally set to INVALID_KEY by 'render' when
122 void mdaPianoVoice::render(uint32_t from
, uint32_t to
)
124 // abort if no key is pressed
125 // initially m_key is INVALID_KEY, so no sound will be rendered
126 if (m_key
== LV2::INVALID_KEY
)
132 for (uint32_t frame
= from
; frame
< to
; ++frame
) {
135 frac
+= delta
; //integer-based linear interpolation
138 if(pos
> end
) pos
-= loop
;
141 i
= (i
<< 7) + (frac
>> 9) * (waves
[pos
+ 1] - i
) + 0x40400000;
142 x
= env
* (*(float *)&i
- 3.0f
); //fast int->float
144 /////////////////////
145 //TODO: This was used in processReplacing instead of the above
147 //i = (i << 7) + (frac >> 9) * (waves[pos + 1] - i) + 0x40400000; //not working on intel mac !?!
148 i = waves[pos] + ((frac * (waves[pos + 1] - waves[pos])) >> 16);
149 x = env * (float)i / 32768.0f;
150 //x = env * (*(float *)&i - 3.0f); //fast int->float
152 /////////////////////
154 env
= env
* dec
; //envelope
155 f0
+= ff
* (x
+ f1
- f0
); //muffle filter
161 //TODO: this was used in processReplacing
162 /////////////////////
164 if(!(l > -2.0f) || !(l < 2.0f))
166 printf("what is this shit? %d, %f, %f\n", i, x, f0);
169 if(!(r > -2.0f) || !(r < 2.0f))
174 /////////////////////
177 x
= cdep
* comb
[cpos
]; //stereo simulator
179 // TODO: processReplacing simply assigned instead of adding
181 p(p_left
)[frame
] += l
+ x
;
182 p(p_right
)[frame
] += r
- x
;
185 // turn off further processing when the envelope has rendered the voice silent
187 m_key
= LV2::INVALID_KEY
;
192 void mdaPianoVoice::update(Param par
)
194 size
= (uint32_t)(12.0f
* p_helper(p_hardness_offset
, par
) - 6.0f
);
195 sizevel
= 0.12f
* p_helper(p_velocity_to_hardness
, par
);
196 muffvel
= p_helper(p_velocity_to_muffling
, par
) * p_helper(p_velocity_to_muffling
, par
) * 5.0f
;
198 velsens
= 1.0f
+ p_helper(p_velocity_sensitivity
, par
) + p_helper(p_velocity_sensitivity
, par
);
199 if(p_helper(p_velocity_sensitivity
, par
) < 0.25f
) velsens
-= 0.75f
- 3.0f
* p_helper(p_velocity_sensitivity
, par
);
201 fine
= p_helper(p_fine_tuning
, par
) - 0.5f
;
202 random
= 0.077f
* p_helper(p_random_detuning
, par
) * p_helper(p_random_detuning
, par
);
203 stretch
= 0.000434f
* (p_helper(p_stretch_tuning
, par
) - 0.5f
);
205 cdep
= p_helper(p_stereo_width
, par
) * p_helper(p_stereo_width
, par
);
206 trim
= 1.50f
- 0.79f
* cdep
;
207 width
= 0.04f
* p_helper(p_stereo_width
, par
); if(width
> 0.03f
) width
= 0.03f
;
209 poly
= 8 + (uint32_t)(24.9f
* p_helper(p_polyphony
, par
));