--- linuxsampler/trunk/src/engines/common/AbstractVoice.cpp 2011/07/28 08:05:57 2218 +++ linuxsampler/trunk/src/engines/common/AbstractVoice.cpp 2011/12/09 15:04:55 2297 @@ -100,6 +100,8 @@ Type = VoiceType; MIDIKey = itNoteOnEvent->Param.Note.Key; MIDIVelocity = itNoteOnEvent->Param.Note.Velocity; + MIDIPan = pEngineChannel->ControllerTable[10]; + if (MIDIPan == 0 && pEngineChannel->GlobalPanRight == 1) MIDIPan = 64; // workaround used to determine whether the MIDI pan has not been set PlaybackState = playback_state_init; // mark voice as triggered, but no audio rendered yet Delay = itNoteOnEvent->FragmentPos(); itTriggerEvent = itNoteOnEvent; @@ -310,14 +312,39 @@ * @param Skip - number of sample points to skip in output buffer */ void AbstractVoice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) { + bool delay = false; // Whether the voice playback should be delayed for this call + + if (pSignalUnitRack != NULL) { + uint delaySteps = pSignalUnitRack->GetEndpointUnit()->DelayTrigger(); + if (delaySteps > 0) { // delay on the endpoint unit means delay of the voice playback + if (delaySteps >= Samples) { + pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(Samples); + delay = true; + } else { + pSignalUnitRack->GetEndpointUnit()->DecreaseDelay(delaySteps); + Samples -= delaySteps; + Skip += delaySteps; + } + } + } + AbstractEngineChannel* pChannel = pEngineChannel; MidiKeyBase* pMidiKeyInfo = GetMidiKeyInfo(MIDIKey); const bool bVoiceRequiresDedicatedRouting = pEngineChannel->GetFxSendCount() > 0 && (pMidiKeyInfo->ReverbSend || pMidiKeyInfo->ChorusSend); + + const bool bEq = + pSignalUnitRack != NULL && pSignalUnitRack->HasEq() && GetEngine()->pEq->HasSupport(); - if (bVoiceRequiresDedicatedRouting) { + if (bEq) { + GetEngine()->pEq->GetInChannelLeft()->Clear(); + GetEngine()->pEq->GetInChannelRight()->Clear(); + finalSynthesisParameters.pOutLeft = &GetEngine()->pEq->GetInChannelLeft()->Buffer()[Skip]; + finalSynthesisParameters.pOutRight = &GetEngine()->pEq->GetInChannelRight()->Buffer()[Skip]; + pSignalUnitRack->UpdateEqSettings(GetEngine()->pEq); + } else if (bVoiceRequiresDedicatedRouting) { finalSynthesisParameters.pOutLeft = &GetEngine()->pDedicatedVoiceChannelLeft->Buffer()[Skip]; finalSynthesisParameters.pOutRight = &GetEngine()->pDedicatedVoiceChannelRight->Buffer()[Skip]; } else { @@ -378,6 +405,11 @@ // process MIDI control change and pitchbend events for this subfragment processCCEvents(itCCEvent, iSubFragmentEnd); + uint8_t pan = MIDIPan; + if (pSignalUnitRack != NULL) pan = pSignalUnitRack->GetEndpointUnit()->CaluclatePan(pan); + + PanLeftSmoother.update(AbstractEngine::PanCurve[128 - pan]); + PanRightSmoother.update(AbstractEngine::PanCurve[pan]); finalSynthesisParameters.fFinalPitch = Pitch.PitchBase * Pitch.PitchBend; float fFinalVolume = VolumeSmoother.render() * CrossfadeSmoother.render(); @@ -388,7 +420,7 @@ // process transition events (note on, note off & sustain pedal) processTransitionEvents(itNoteEvent, iSubFragmentEnd); processGroupEvents(itGroupEvent, iSubFragmentEnd); - + if (pSignalUnitRack == NULL) { // if the voice was killed in this subfragment, or if the // filter EG is finished, switch EG1 to fade out stage @@ -486,7 +518,7 @@ fFinalVolume * VolumeRight * PanRightSmoother.render(); #endif // render audio for one subfragment - RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop); + if (!delay) RunSynthesisFunction(SynthesisMode, &finalSynthesisParameters, &loop); if (pSignalUnitRack == NULL) { // stop the rendering if volume EG is finished @@ -523,19 +555,30 @@ }*/ // TODO: ^^^ - pSignalUnitRack->Increment(); + if (!delay) pSignalUnitRack->Increment(); } Pos = newPos; i = iSubFragmentEnd; } + + if (delay) return; if (bVoiceRequiresDedicatedRouting) { + if (bEq) { + GetEngine()->pEq->RenderAudio(Samples); + GetEngine()->pEq->GetOutChannelLeft()->CopyTo(GetEngine()->pDedicatedVoiceChannelLeft, Samples); + GetEngine()->pEq->GetOutChannelRight()->CopyTo(GetEngine()->pDedicatedVoiceChannelRight, Samples); + } optional effectSendLevels[2] = { pMidiKeyInfo->ReverbSend, pMidiKeyInfo->ChorusSend }; GetEngine()->RouteDedicatedVoiceChannels(pEngineChannel, effectSendLevels, Samples); + } else if (bEq) { + GetEngine()->pEq->RenderAudio(Samples); + GetEngine()->pEq->GetOutChannelLeft()->CopyTo(pChannel->pChannelLeft, Samples); + GetEngine()->pEq->GetOutChannelRight()->CopyTo(pChannel->pChannelRight, Samples); } } @@ -569,8 +612,7 @@ if (itEvent->Param.CC.Controller == 7) { // volume VolumeSmoother.update(AbstractEngine::VolumeCurve[itEvent->Param.CC.Value]); } else if (itEvent->Param.CC.Controller == 10) { // panpot - PanLeftSmoother.update(AbstractEngine::PanCurve[128 - itEvent->Param.CC.Value]); - PanRightSmoother.update(AbstractEngine::PanCurve[itEvent->Param.CC.Value]); + MIDIPan = itEvent->Param.CC.Value; } } else if (itEvent->Type == Event::type_pitchbend) { // if pitch bend event processPitchEvent(itEvent);