739 |
void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) { |
void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) { |
740 |
RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first(); |
RTList<Event>::Iterator itCCEvent = pEngineChannel->pEvents->first(); |
741 |
RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first(); |
RTList<Event>::Iterator itNoteEvent = pEngineChannel->pMIDIKeyInfo[MIDIKey].pEvents->first(); |
742 |
|
|
743 |
if (Skip) { // skip events that happened before this voice was triggered |
if (Skip) { // skip events that happened before this voice was triggered |
744 |
while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent; |
while (itCCEvent && itCCEvent->FragmentPos() <= Skip) ++itCCEvent; |
745 |
while (itNoteEvent && itNoteEvent->FragmentPos() <= Skip) ++itNoteEvent; |
while (itNoteEvent && itNoteEvent->FragmentPos() <= Skip) ++itNoteEvent; |
746 |
} |
} |
747 |
|
|
748 |
uint i = Skip; |
uint i = Skip; |
749 |
while (i < Samples) { |
while (i < Samples) { |
750 |
int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples); |
int iSubFragmentEnd = RTMath::Min(i + CONFIG_DEFAULT_SUBFRAGMENT_SIZE, Samples); |
751 |
|
|
752 |
// initialize all final synthesis parameters |
// initialize all final synthesis parameters |
753 |
fFinalPitch = PitchBase * PitchBend; |
fFinalPitch = PitchBase * PitchBend; |
754 |
#if CONFIG_PROCESS_MUTED_CHANNELS |
#if CONFIG_PROCESS_MUTED_CHANNELS |
755 |
fFinalVolume = this->Volume * this->CrossfadeVolume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume)); |
fFinalVolume = this->Volume * this->CrossfadeVolume * (pEngineChannel->GetMute() ? 0 : pEngineChannel->GlobalVolume); |
756 |
#else |
#else |
757 |
fFinalVolume = this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume; |
fFinalVolume = this->Volume * this->CrossfadeVolume * pEngineChannel->GlobalVolume; |
758 |
#endif |
#endif |
759 |
fFinalCutoff = VCFCutoffCtrl.fvalue; |
fFinalCutoff = VCFCutoffCtrl.fvalue; |
760 |
fFinalResonance = VCFResonanceCtrl.fvalue; |
fFinalResonance = VCFResonanceCtrl.fvalue; |
761 |
|
|
762 |
// process MIDI control change and pitchbend events for this subfragment |
// process MIDI control change and pitchbend events for this subfragment |
763 |
processCCEvents(itCCEvent, iSubFragmentEnd); |
processCCEvents(itCCEvent, iSubFragmentEnd); |
764 |
|
|
765 |
// process transition events (note on, note off & sustain pedal) |
// process transition events (note on, note off & sustain pedal) |
766 |
processTransitionEvents(itNoteEvent, iSubFragmentEnd); |
processTransitionEvents(itNoteEvent, iSubFragmentEnd); |
767 |
|
|
768 |
// process envelope generators |
// process envelope generators |
769 |
switch (EG1.getSegmentType()) { |
switch (EG1.getSegmentType()) { |
770 |
case EGADSR::segment_lin: |
case EGADSR::segment_lin: |
789 |
break; // noop |
break; // noop |
790 |
} |
} |
791 |
fFinalPitch *= RTMath::CentsToFreqRatio(EG3.render()); |
fFinalPitch *= RTMath::CentsToFreqRatio(EG3.render()); |
792 |
|
|
793 |
// process low frequency oscillators |
// process low frequency oscillators |
794 |
if (bLFO1Enabled) fFinalVolume *= pLFO1->render(); |
if (bLFO1Enabled) fFinalVolume *= pLFO1->render(); |
795 |
if (bLFO2Enabled) fFinalCutoff *= pLFO2->render(); |
if (bLFO2Enabled) fFinalCutoff *= pLFO2->render(); |
803 |
|
|
804 |
// how many steps do we calculate for this next subfragment |
// how many steps do we calculate for this next subfragment |
805 |
const int steps = iSubFragmentEnd - i; |
const int steps = iSubFragmentEnd - i; |
806 |
|
|
807 |
// select the appropriate synthesis mode |
// select the appropriate synthesis mode |
808 |
SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, fFinalPitch != 1.0f); |
SYNTHESIS_MODE_SET_INTERPOLATE(SynthesisMode, fFinalPitch != 1.0f); |
809 |
|
|
810 |
// render audio for one subfragment |
// render audio for one subfragment |
811 |
RunSynthesisFunction(SynthesisMode, *this, iSubFragmentEnd, pSrc, i); |
RunSynthesisFunction(SynthesisMode, *this, iSubFragmentEnd, pSrc, i); |
812 |
|
|
813 |
// increment envelopes' positions |
// increment envelopes' positions |
814 |
if (EG1.active()) { |
if (EG1.active()) { |
815 |
EG1.increment(steps); |
EG1.increment(1); |
816 |
if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); |
if (!EG1.toStageEndLeft()) EG1.update(EGADSR::event_stage_end, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); |
817 |
} |
} |
818 |
if (EG2.active()) { |
if (EG2.active()) { |
819 |
EG2.increment(steps); |
EG2.increment(1); |
820 |
if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); |
if (!EG2.toStageEndLeft()) EG2.update(EGADSR::event_stage_end, this->Pos, fFinalPitch, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); |
821 |
} |
} |
822 |
EG3.increment(steps); |
EG3.increment(1); |
823 |
if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached |
if (!EG3.toEndLeft()) EG3.update(); // neutralize envelope coefficient if end reached |
824 |
|
|
825 |
|
i = iSubFragmentEnd; |
826 |
} |
} |
827 |
} |
} |
828 |
|
|