101 |
dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no")); |
dmsg(4,("RAM only voice launched (Looping: %s)\n", (RAMLoop) ? "yes" : "no")); |
102 |
} |
} |
103 |
|
|
104 |
// Pitch according to keyboard position (if keyrange > 1 key) |
|
105 |
CurrentPitch = (pRegion->KeyRange.high != pRegion->KeyRange.low) ? |
// Pitch according to keyboard position (if 'PitchTrack' is set) |
106 |
pow(2, (double) (MIDIKey - (int) pSample->MIDIUnityNote) / (double) 12) : 1.0; |
CurrentPitch = (pDimRgn->PitchTrack) ? pow(2, ((double) (MIDIKey - (int) pDimRgn->UnityNote) + (double) pDimRgn->FineTune / 100.0) / 12.0) |
107 |
Volume = pDimRgn->GetVelocityAttenuation(Velocity); |
: pow(2, ((double) pDimRgn->FineTune / 100.0) / 12.0); |
108 |
|
|
109 |
|
Volume = pDimRgn->GetVelocityAttenuation(Velocity); |
110 |
|
|
111 |
|
EG1.Trigger(pDimRgn->EG1PreAttack, pDimRgn->EG1Attack, pDimRgn->EG1Release); |
112 |
|
|
113 |
// ************************************************ |
// ************************************************ |
114 |
// TODO: ARTICULATION DATA HANDLING IS MISSING HERE |
// TODO: ARTICULATION DATA HANDLING IS MISSING HERE |
128 |
*/ |
*/ |
129 |
void Voice::RenderAudio() { |
void Voice::RenderAudio() { |
130 |
|
|
131 |
|
// Let all modulators throw their parameter changes for the current audio fragment |
132 |
|
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vca, this->Volume); |
133 |
|
EG1.ProcessFragment(); |
134 |
|
|
135 |
|
|
136 |
switch (this->PlaybackState) { |
switch (this->PlaybackState) { |
137 |
|
|
138 |
case playback_state_ram: { |
case playback_state_ram: { |
181 |
Kill(); // free voice |
Kill(); // free voice |
182 |
break; |
break; |
183 |
} |
} |
184 |
|
|
185 |
|
// If release stage finished, let the voice be killed |
186 |
|
if (EG1.GetStage() == EG_VCA::stage_end) this->PlaybackState = playback_state_end; |
187 |
} |
} |
188 |
|
|
189 |
/** |
/** |
192 |
* @param pSrc - pointer to input sample data |
* @param pSrc - pointer to input sample data |
193 |
*/ |
*/ |
194 |
void Voice::Interpolate(sample_t* pSrc) { |
void Voice::Interpolate(sample_t* pSrc) { |
195 |
float effective_volume = this->Volume; |
int i = 0; |
196 |
int i = 0; |
float e = 1.0; |
|
|
|
|
// ************************************************ |
|
|
// TODO: ARTICULATION DATA HANDLING IS MISSING HERE |
|
|
// ************************************************ |
|
197 |
|
|
198 |
// FIXME: assuming either mono or stereo |
// FIXME: assuming either mono or stereo |
199 |
if (this->pSample->Channels == 2) { // Stereo Sample |
if (this->pSample->Channels == 2) { // Stereo Sample |
200 |
while (i < this->OutputBufferSize) { |
while (i < this->OutputBufferSize) { |
201 |
InterpolateOneStep_Stereo(pSrc, i, effective_volume); |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
202 |
} |
} |
203 |
} |
} |
204 |
else { // Mono Sample |
else { // Mono Sample |
205 |
while (i < this->OutputBufferSize) { |
while (i < this->OutputBufferSize) { |
206 |
InterpolateOneStep_Mono(pSrc, i, effective_volume); |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
207 |
} |
} |
208 |
} |
} |
209 |
} |
} |
214 |
* @param pSrc - pointer to input sample data |
* @param pSrc - pointer to input sample data |
215 |
*/ |
*/ |
216 |
void Voice::InterpolateAndLoop(sample_t* pSrc) { |
void Voice::InterpolateAndLoop(sample_t* pSrc) { |
217 |
float effective_volume = this->Volume; |
int i = 0; |
|
int i = 0; |
|
|
|
|
|
// ************************************************ |
|
|
// TODO: ARTICULATION DATA HANDLING IS MISSING HERE |
|
|
// ************************************************ |
|
218 |
|
|
219 |
// FIXME: assuming either mono or stereo |
// FIXME: assuming either mono or stereo |
220 |
if (pSample->Channels == 2) { // Stereo Sample |
if (pSample->Channels == 2) { // Stereo Sample |
221 |
if (pSample->LoopPlayCount) { |
if (pSample->LoopPlayCount) { |
222 |
// render loop (loop count limited) |
// render loop (loop count limited) |
223 |
while (i < OutputBufferSize && LoopCyclesLeft) { |
while (i < OutputBufferSize && LoopCyclesLeft) { |
224 |
InterpolateOneStep_Stereo(pSrc, i, effective_volume); |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
225 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
226 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
227 |
LoopCyclesLeft--; |
LoopCyclesLeft--; |
229 |
} |
} |
230 |
// render on without loop |
// render on without loop |
231 |
while (i < OutputBufferSize) { |
while (i < OutputBufferSize) { |
232 |
InterpolateOneStep_Stereo(pSrc, i, effective_volume); |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
233 |
} |
} |
234 |
} |
} |
235 |
else { // render loop (endless loop) |
else { // render loop (endless loop) |
236 |
while (i < OutputBufferSize) { |
while (i < OutputBufferSize) { |
237 |
InterpolateOneStep_Stereo(pSrc, i, effective_volume); |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
238 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
239 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize); |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize); |
240 |
} |
} |
245 |
if (pSample->LoopPlayCount) { |
if (pSample->LoopPlayCount) { |
246 |
// render loop (loop count limited) |
// render loop (loop count limited) |
247 |
while (i < OutputBufferSize && LoopCyclesLeft) { |
while (i < OutputBufferSize && LoopCyclesLeft) { |
248 |
InterpolateOneStep_Mono(pSrc, i, effective_volume); |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
249 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
250 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
251 |
LoopCyclesLeft--; |
LoopCyclesLeft--; |
253 |
} |
} |
254 |
// render on without loop |
// render on without loop |
255 |
while (i < OutputBufferSize) { |
while (i < OutputBufferSize) { |
256 |
InterpolateOneStep_Mono(pSrc, i, effective_volume); |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
257 |
} |
} |
258 |
} |
} |
259 |
else { // render loop (endless loop) |
else { // render loop (endless loop) |
260 |
while (i < OutputBufferSize) { |
while (i < OutputBufferSize) { |
261 |
InterpolateOneStep_Mono(pSrc, i, effective_volume); |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
262 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
263 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
264 |
} |
} |
280 |
DiskStreamRef.OrderID = 0; |
DiskStreamRef.OrderID = 0; |
281 |
Active = false; |
Active = false; |
282 |
} |
} |
283 |
|
|
284 |
|
/** |
285 |
|
* Release the voice in an appropriate time range, the voice will go through |
286 |
|
* it's release stage before it will be killed. |
287 |
|
*/ |
288 |
|
void Voice::Release() { |
289 |
|
EG1.Release(); |
290 |
|
} |