29 |
|
|
30 |
namespace LinuxSampler { namespace gig { |
namespace LinuxSampler { namespace gig { |
31 |
|
|
|
const float Voice::FILTER_CUTOFF_COEFF(CalculateFilterCutoffCoeff()); |
|
|
|
|
|
float Voice::CalculateFilterCutoffCoeff() { |
|
|
return log(CONFIG_FILTER_CUTOFF_MAX / CONFIG_FILTER_CUTOFF_MIN); |
|
|
} |
|
|
|
|
32 |
Voice::Voice() { |
Voice::Voice() { |
33 |
pEngine = NULL; |
pEngine = NULL; |
34 |
pDiskThread = NULL; |
pDiskThread = NULL; |
98 |
// calculate volume |
// calculate volume |
99 |
const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity); |
const double velocityAttenuation = pDimRgn->GetVelocityAttenuation(itNoteOnEvent->Param.Note.Velocity); |
100 |
|
|
101 |
float volume = velocityAttenuation / 32768.0f; // we downscale by 32768 to convert from int16 value range to DSP value range (which is -1.0..1.0) |
// For 16 bit samples, we downscale by 32768 to convert from |
102 |
|
// int16 value range to DSP value range (which is |
103 |
|
// -1.0..1.0). For 24 bit, we downscale from int32. |
104 |
|
float volume = velocityAttenuation / (pSample->BitDepth == 16 ? 32768.0f : 32768.0f * 65536.0f); |
105 |
|
|
106 |
volume *= pDimRgn->SampleAttenuation; |
volume *= pDimRgn->SampleAttenuation; |
107 |
|
|
116 |
|
|
117 |
// select channel mode (mono or stereo) |
// select channel mode (mono or stereo) |
118 |
SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2); |
SYNTHESIS_MODE_SET_CHANNELS(SynthesisMode, pSample->Channels == 2); |
119 |
|
// select bit depth (16 or 24) |
120 |
|
SYNTHESIS_MODE_SET_BITDEPTH24(SynthesisMode, pSample->BitDepth == 24); |
121 |
|
|
122 |
// get starting crossfade volume level |
// get starting crossfade volume level |
123 |
float crossfadeVolume; |
float crossfadeVolume; |
124 |
switch (pDimRgn->AttenuationController.type) { |
switch (pDimRgn->AttenuationController.type) { |
125 |
case ::gig::attenuation_ctrl_t::type_channelaftertouch: |
case ::gig::attenuation_ctrl_t::type_channelaftertouch: |
126 |
crossfadeVolume = 1.0f; //TODO: aftertouch not supported yet |
crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(pEngineChannel->ControllerTable[128])]; |
127 |
break; |
break; |
128 |
case ::gig::attenuation_ctrl_t::type_velocity: |
case ::gig::attenuation_ctrl_t::type_velocity: |
129 |
crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity)]; |
crossfadeVolume = Engine::CrossfadeCurve[CrossfadeAttenuation(itNoteOnEvent->Param.Note.Velocity)]; |
141 |
|
|
142 |
float subfragmentRate = pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE; |
float subfragmentRate = pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE; |
143 |
CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate); |
CrossfadeSmoother.trigger(crossfadeVolume, subfragmentRate); |
144 |
VolumeSmoother.trigger(pEngineChannel->GlobalVolume, subfragmentRate); |
VolumeSmoother.trigger(pEngineChannel->GlobalVolume * GLOBAL_VOLUME * pEngineChannel->MidiVolume, subfragmentRate); |
145 |
PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate); |
PanLeftSmoother.trigger(pEngineChannel->GlobalPanLeft, subfragmentRate); |
146 |
PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate); |
PanRightSmoother.trigger(pEngineChannel->GlobalPanRight, subfragmentRate); |
147 |
|
|
200 |
eg1controllervalue = 0; |
eg1controllervalue = 0; |
201 |
break; |
break; |
202 |
case ::gig::eg1_ctrl_t::type_channelaftertouch: |
case ::gig::eg1_ctrl_t::type_channelaftertouch: |
203 |
eg1controllervalue = 0; // TODO: aftertouch not yet supported |
eg1controllervalue = pEngineChannel->ControllerTable[128]; |
204 |
break; |
break; |
205 |
case ::gig::eg1_ctrl_t::type_velocity: |
case ::gig::eg1_ctrl_t::type_velocity: |
206 |
eg1controllervalue = itNoteOnEvent->Param.Note.Velocity; |
eg1controllervalue = itNoteOnEvent->Param.Note.Velocity; |
241 |
else |
else |
242 |
#else |
#else |
243 |
{ |
{ |
244 |
float finalVolume = pEngineChannel->GlobalVolume * crossfadeVolume * EG1.getLevel(); |
float finalVolume = pEngineChannel->GlobalVolume * GLOBAL_VOLUME * pEngineChannel->MidiVolume * crossfadeVolume * EG1.getLevel(); |
245 |
|
|
246 |
finalSynthesisParameters.fFinalVolumeLeft = finalVolume * VolumeLeft * pEngineChannel->GlobalPanLeft; |
finalSynthesisParameters.fFinalVolumeLeft = finalVolume * VolumeLeft * pEngineChannel->GlobalPanLeft; |
247 |
finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight; |
finalSynthesisParameters.fFinalVolumeRight = finalVolume * VolumeRight * pEngineChannel->GlobalPanRight; |
258 |
eg2controllervalue = 0; |
eg2controllervalue = 0; |
259 |
break; |
break; |
260 |
case ::gig::eg2_ctrl_t::type_channelaftertouch: |
case ::gig::eg2_ctrl_t::type_channelaftertouch: |
261 |
eg2controllervalue = 0; // TODO: aftertouch not yet supported |
eg2controllervalue = pEngineChannel->ControllerTable[128]; |
262 |
break; |
break; |
263 |
case ::gig::eg2_ctrl_t::type_velocity: |
case ::gig::eg2_ctrl_t::type_velocity: |
264 |
eg2controllervalue = itNoteOnEvent->Param.Note.Velocity; |
eg2controllervalue = itNoteOnEvent->Param.Note.Velocity; |
338 |
} |
} |
339 |
if (bLFO1Enabled) { |
if (bLFO1Enabled) { |
340 |
pLFO1->trigger(pDimRgn->LFO1Frequency, |
pLFO1->trigger(pDimRgn->LFO1Frequency, |
341 |
start_level_max, |
start_level_min, |
342 |
lfo1_internal_depth, |
lfo1_internal_depth, |
343 |
pDimRgn->LFO1ControlDepth, |
pDimRgn->LFO1ControlDepth, |
344 |
pDimRgn->LFO1FlipPhase, |
pDimRgn->LFO1FlipPhase, |
410 |
break; |
break; |
411 |
case ::gig::lfo3_ctrl_aftertouch: |
case ::gig::lfo3_ctrl_aftertouch: |
412 |
lfo3_internal_depth = 0; |
lfo3_internal_depth = 0; |
413 |
pLFO3->ExtController = 0; // TODO: aftertouch not implemented yet |
pLFO3->ExtController = 128; |
414 |
bLFO3Enabled = false; // see TODO comment in line above |
bLFO3Enabled = true; |
415 |
break; |
break; |
416 |
case ::gig::lfo3_ctrl_internal_modwheel: |
case ::gig::lfo3_ctrl_internal_modwheel: |
417 |
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
420 |
break; |
break; |
421 |
case ::gig::lfo3_ctrl_internal_aftertouch: |
case ::gig::lfo3_ctrl_internal_aftertouch: |
422 |
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
lfo3_internal_depth = pDimRgn->LFO3InternalDepth; |
423 |
pLFO1->ExtController = 0; // TODO: aftertouch not implemented yet |
pLFO1->ExtController = 128; |
424 |
bLFO3Enabled = (lfo3_internal_depth > 0 /*|| pDimRgn->LFO3ControlDepth > 0*/); // see TODO comment in line above |
bLFO3Enabled = (lfo3_internal_depth > 0 || pDimRgn->LFO3ControlDepth > 0); |
425 |
break; |
break; |
426 |
default: |
default: |
427 |
lfo3_internal_depth = 0; |
lfo3_internal_depth = 0; |
478 |
case ::gig::vcf_cutoff_ctrl_genpurpose8: |
case ::gig::vcf_cutoff_ctrl_genpurpose8: |
479 |
VCFCutoffCtrl.controller = 83; |
VCFCutoffCtrl.controller = 83; |
480 |
break; |
break; |
481 |
case ::gig::vcf_cutoff_ctrl_aftertouch: //TODO: not implemented yet |
case ::gig::vcf_cutoff_ctrl_aftertouch: |
482 |
|
VCFCutoffCtrl.controller = 128; |
483 |
|
break; |
484 |
case ::gig::vcf_cutoff_ctrl_none: |
case ::gig::vcf_cutoff_ctrl_none: |
485 |
default: |
default: |
486 |
VCFCutoffCtrl.controller = 0; |
VCFCutoffCtrl.controller = 0; |
538 |
else { |
else { |
539 |
cvalue = pDimRgn->VCFCutoff; |
cvalue = pDimRgn->VCFCutoff; |
540 |
} |
} |
541 |
cutoff *= float(cvalue) * 0.00787402f; // (1 / 127) |
cutoff *= float(cvalue); |
542 |
if (cutoff > 1.0) cutoff = 1.0; |
if (cutoff > 127.0f) cutoff = 127.0f; |
|
cutoff = (cutoff < 0.5 ? cutoff * 4826 - 1 : cutoff * 5715 - 449); |
|
|
if (cutoff < 1.0) cutoff = 1.0; |
|
543 |
|
|
544 |
// calculate resonance |
// calculate resonance |
545 |
float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : pDimRgn->VCFResonance) * 0.00787f; // 0.0..1.0 |
float resonance = (float) (VCFResonanceCtrl.controller ? VCFResonanceCtrl.value : pDimRgn->VCFResonance); |
546 |
|
|
547 |
VCFCutoffCtrl.fvalue = cutoff - 1.0; |
VCFCutoffCtrl.fvalue = cutoff; |
548 |
VCFResonanceCtrl.fvalue = resonance; |
VCFResonanceCtrl.fvalue = resonance; |
549 |
} |
} |
550 |
else { |
else { |
621 |
} |
} |
622 |
} |
} |
623 |
|
|
624 |
sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from |
sample_t* ptr = (sample_t*)DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from |
625 |
|
|
626 |
// render current audio fragment |
// render current audio fragment |
627 |
Synthesize(Samples, ptr, Delay); |
Synthesize(Samples, ptr, Delay); |
719 |
CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]); |
CrossfadeSmoother.update(Engine::CrossfadeCurve[CrossfadeAttenuation(itEvent->Param.CC.Value)]); |
720 |
} |
} |
721 |
if (itEvent->Param.CC.Controller == 7) { // volume |
if (itEvent->Param.CC.Controller == 7) { // volume |
722 |
VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value] * CONFIG_GLOBAL_ATTENUATION); |
VolumeSmoother.update(Engine::VolumeCurve[itEvent->Param.CC.Value]); |
723 |
} else if (itEvent->Param.CC.Controller == 10) { // panpot |
} else if (itEvent->Param.CC.Controller == 10) { // panpot |
724 |
PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]); |
PanLeftSmoother.update(Engine::PanCurve[128 - itEvent->Param.CC.Value]); |
725 |
PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]); |
PanRightSmoother.update(Engine::PanCurve[itEvent->Param.CC.Value]); |
742 |
VCFCutoffCtrl.value == ccvalue; |
VCFCutoffCtrl.value == ccvalue; |
743 |
if (pDimRgn->VCFCutoffControllerInvert) ccvalue = 127 - ccvalue; |
if (pDimRgn->VCFCutoffControllerInvert) ccvalue = 127 - ccvalue; |
744 |
if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale; |
if (ccvalue < pDimRgn->VCFVelocityScale) ccvalue = pDimRgn->VCFVelocityScale; |
745 |
float cutoff = CutoffBase * float(ccvalue) * 0.00787402f; // (1 / 127) |
float cutoff = CutoffBase * float(ccvalue); |
746 |
if (cutoff > 1.0) cutoff = 1.0; |
if (cutoff > 127.0f) cutoff = 127.0f; |
|
cutoff = (cutoff < 0.5 ? cutoff * 4826 - 1 : cutoff * 5715 - 449); |
|
|
if (cutoff < 1.0) cutoff = 1.0; |
|
747 |
|
|
748 |
VCFCutoffCtrl.fvalue = cutoff - 1.0; // needed for initialization of fFinalCutoff next time |
VCFCutoffCtrl.fvalue = cutoff; // needed for initialization of fFinalCutoff next time |
749 |
fFinalCutoff = cutoff; |
fFinalCutoff = cutoff; |
750 |
} |
} |
751 |
|
|
753 |
// convert absolute controller value to differential |
// convert absolute controller value to differential |
754 |
const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value; |
const int ctrldelta = itEvent->Param.CC.Value - VCFResonanceCtrl.value; |
755 |
VCFResonanceCtrl.value = itEvent->Param.CC.Value; |
VCFResonanceCtrl.value = itEvent->Param.CC.Value; |
756 |
const float resonancedelta = (float) ctrldelta * 0.00787f; // 0.0..1.0 |
const float resonancedelta = (float) ctrldelta; |
757 |
fFinalResonance += resonancedelta; |
fFinalResonance += resonancedelta; |
758 |
// needed for initialization of parameter |
// needed for initialization of parameter |
759 |
VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value * 0.00787f; |
VCFResonanceCtrl.fvalue = itEvent->Param.CC.Value; |
760 |
} |
} |
761 |
|
|
762 |
/** |
/** |
768 |
* @param Skip - number of sample points to skip in output buffer |
* @param Skip - number of sample points to skip in output buffer |
769 |
*/ |
*/ |
770 |
void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) { |
void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) { |
771 |
finalSynthesisParameters.pOutLeft = &pEngineChannel->pOutputLeft[Skip]; |
finalSynthesisParameters.pOutLeft = &pEngineChannel->pChannelLeft->Buffer()[Skip]; |
772 |
finalSynthesisParameters.pOutRight = &pEngineChannel->pOutputRight[Skip]; |
finalSynthesisParameters.pOutRight = &pEngineChannel->pChannelRight->Buffer()[Skip]; |
773 |
finalSynthesisParameters.pSrc = pSrc; |
finalSynthesisParameters.pSrc = pSrc; |
774 |
|
|
775 |
RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first(); |
RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first(); |
803 |
// process transition events (note on, note off & sustain pedal) |
// process transition events (note on, note off & sustain pedal) |
804 |
processTransitionEvents(itNoteEvent, iSubFragmentEnd); |
processTransitionEvents(itNoteEvent, iSubFragmentEnd); |
805 |
|
|
806 |
// if the voice was killed in this subfragment switch EG1 to fade out stage |
// if the voice was killed in this subfragment, or if the |
807 |
if (itKillEvent && killPos <= iSubFragmentEnd) { |
// filter EG is finished, switch EG1 to fade out stage |
808 |
|
if ((itKillEvent && killPos <= iSubFragmentEnd) || |
809 |
|
(SYNTHESIS_MODE_GET_FILTER(SynthesisMode) && |
810 |
|
EG2.getSegmentType() == EGADSR::segment_end)) { |
811 |
EG1.enterFadeOutStage(); |
EG1.enterFadeOutStage(); |
812 |
itKillEvent = Pool<Event>::Iterator(); |
itKillEvent = Pool<Event>::Iterator(); |
813 |
} |
} |
838 |
if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render(); |
if (EG3.active()) finalSynthesisParameters.fFinalPitch *= EG3.render(); |
839 |
|
|
840 |
// process low frequency oscillators |
// process low frequency oscillators |
841 |
if (bLFO1Enabled) fFinalVolume *= pLFO1->render(); |
if (bLFO1Enabled) fFinalVolume *= (1.0f - pLFO1->render()); |
842 |
if (bLFO2Enabled) fFinalCutoff *= pLFO2->render(); |
if (bLFO2Enabled) fFinalCutoff *= pLFO2->render(); |
843 |
if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render()); |
if (bLFO3Enabled) finalSynthesisParameters.fFinalPitch *= RTMath::CentsToFreqRatio(pLFO3->render()); |
844 |
|
|
845 |
// if filter enabled then update filter coefficients |
// if filter enabled then update filter coefficients |
846 |
if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) { |
if (SYNTHESIS_MODE_GET_FILTER(SynthesisMode)) { |
847 |
finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff + 1.0, fFinalResonance, pEngine->SampleRate); |
finalSynthesisParameters.filterLeft.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate); |
848 |
finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff + 1.0, fFinalResonance, pEngine->SampleRate); |
finalSynthesisParameters.filterRight.SetParameters(fFinalCutoff, fFinalResonance, pEngine->SampleRate); |
849 |
} |
} |
850 |
|
|
851 |
// do we need resampling? |
// do we need resampling? |