61 |
KeyGroup = 0; |
KeyGroup = 0; |
62 |
SynthesisMode = 0; // set all mode bits to 0 first |
SynthesisMode = 0; // set all mode bits to 0 first |
63 |
// select synthesis implementation (currently either pure C++ or MMX+SSE(1)) |
// select synthesis implementation (currently either pure C++ or MMX+SSE(1)) |
64 |
#if ARCH_X86 |
#if CONFIG_ASM && ARCH_X86 |
65 |
SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE()); |
SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE()); |
66 |
#else |
#else |
67 |
SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false); |
SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, false); |
134 |
dmsg(1,("voice::trigger: !pInstrument\n")); |
dmsg(1,("voice::trigger: !pInstrument\n")); |
135 |
exit(EXIT_FAILURE); |
exit(EXIT_FAILURE); |
136 |
} |
} |
137 |
if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // FIXME: should be removed before the final release (purpose: just a sanity check for debugging) |
#if CONFIG_DEVMODE |
138 |
|
if (itNoteOnEvent->FragmentPos() > pEngine->MaxSamplesPerCycle) { // just a sanity check for debugging |
139 |
dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n")); |
dmsg(1,("Voice::Trigger(): ERROR, TriggerDelay > Totalsamples\n")); |
140 |
} |
} |
141 |
|
#endif // CONFIG_DEVMODE |
142 |
|
|
143 |
Type = type_normal; |
Type = type_normal; |
144 |
MIDIKey = itNoteOnEvent->Param.Note.Key; |
MIDIKey = itNoteOnEvent->Param.Note.Key; |
145 |
pRegion = pInstrument->GetRegion(MIDIKey); |
pRegion = pInstrument->GetRegion(MIDIKey); |
146 |
PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed |
PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet |
147 |
Delay = itNoteOnEvent->FragmentPos(); |
Delay = itNoteOnEvent->FragmentPos(); |
148 |
itTriggerEvent = itNoteOnEvent; |
itTriggerEvent = itNoteOnEvent; |
149 |
itKillEvent = Pool<Event>::Iterator(); |
itKillEvent = Pool<Event>::Iterator(); |
269 |
pSample = pDimRgn->pSample; // sample won't change until the voice is finished |
pSample = pDimRgn->pSample; // sample won't change until the voice is finished |
270 |
if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent |
if (!pSample || !pSample->SamplesTotal) return -1; // no need to continue if sample is silent |
271 |
|
|
272 |
|
// calculate volume |
273 |
|
const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity); |
274 |
|
|
275 |
|
Volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0) |
276 |
|
|
277 |
|
Volume *= pDimRgn->SampleAttenuation; |
278 |
|
|
279 |
|
// the volume of release triggered samples depends on note length |
280 |
|
if (ReleaseTriggerVoice) { |
281 |
|
float noteLength = float(pEngine->FrameTime + Delay - |
282 |
|
pEngineChannel->pMIDIKeyInfo[MIDIKey].NoteOnTime) / pEngine->SampleRate; |
283 |
|
float attenuation = 1 - 0.01053 * (256 >> pDimRgn->ReleaseTriggerDecay) * noteLength; |
284 |
|
if (attenuation <= 0) return -1; |
285 |
|
Volume *= attenuation; |
286 |
|
} |
287 |
|
|
288 |
// select channel mode (mono or stereo) |
// select channel mode (mono or stereo) |
289 |
SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2); |
SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2); |
290 |
|
|
349 |
this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents |
this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents |
350 |
} |
} |
351 |
|
|
352 |
Volume = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity) / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0) |
// the length of the decay and release curves are dependent on the velocity |
353 |
|
const double velrelease = 1 / pDimRgn->GetVelocityRelease(itNoteOnEvent->Param.Note.Velocity); |
|
Volume *= pDimRgn->SampleAttenuation; |
|
354 |
|
|
355 |
// setup EG 1 (VCA EG) |
// setup EG 1 (VCA EG) |
356 |
{ |
{ |
381 |
pDimRgn->EG1Attack + eg1attack, |
pDimRgn->EG1Attack + eg1attack, |
382 |
pDimRgn->EG1Hold, |
pDimRgn->EG1Hold, |
383 |
pSample->LoopStart, |
pSample->LoopStart, |
384 |
pDimRgn->EG1Decay1 + eg1decay, |
(pDimRgn->EG1Decay1 + eg1decay) * velrelease, |
385 |
pDimRgn->EG1Decay2 + eg1decay, |
(pDimRgn->EG1Decay2 + eg1decay) * velrelease, |
386 |
pDimRgn->EG1InfiniteSustain, |
pDimRgn->EG1InfiniteSustain, |
387 |
pDimRgn->EG1Sustain, |
pDimRgn->EG1Sustain, |
388 |
pDimRgn->EG1Release + eg1release, |
(pDimRgn->EG1Release + eg1release) * velrelease, |
389 |
// the SSE synthesis implementation requires |
// the SSE synthesis implementation requires |
390 |
// the vca start to be 16 byte aligned |
// the vca start to be 16 byte aligned |
391 |
SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ? |
SYNTHESIS_MODE_GET_IMPLEMENTATION(SynthesisMode) ? |
392 |
Delay & 0xfffffffc : Delay); |
Delay & 0xfffffffc : Delay, |
393 |
|
velocityAttenuation); |
394 |
} |
} |
395 |
|
|
396 |
|
|
423 |
pDimRgn->EG2Attack + eg2attack, |
pDimRgn->EG2Attack + eg2attack, |
424 |
false, |
false, |
425 |
pSample->LoopStart, |
pSample->LoopStart, |
426 |
pDimRgn->EG2Decay1 + eg2decay, |
(pDimRgn->EG2Decay1 + eg2decay) * velrelease, |
427 |
pDimRgn->EG2Decay2 + eg2decay, |
(pDimRgn->EG2Decay2 + eg2decay) * velrelease, |
428 |
pDimRgn->EG2InfiniteSustain, |
pDimRgn->EG2InfiniteSustain, |
429 |
pDimRgn->EG2Sustain, |
pDimRgn->EG2Sustain, |
430 |
pDimRgn->EG2Release + eg2release, |
(pDimRgn->EG2Release + eg2release) * velrelease, |
431 |
Delay); |
Delay, |
432 |
|
velocityAttenuation); |
433 |
} |
} |
434 |
|
|
435 |
|
|
705 |
|
|
706 |
switch (this->PlaybackState) { |
switch (this->PlaybackState) { |
707 |
|
|
708 |
|
case playback_state_init: |
709 |
|
this->PlaybackState = playback_state_ram; // we always start playback from RAM cache and switch then to disk if needed |
710 |
|
// no break - continue with playback_state_ram |
711 |
|
|
712 |
case playback_state_ram: { |
case playback_state_ram: { |
713 |
if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping |
if (RAMLoop) SYNTHESIS_MODE_SET_LOOP(SynthesisMode, true); // enable looping |
714 |
|
|