/[svn]/linuxsampler/trunk/src/engines/AbstractEngine.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/AbstractEngine.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2091 by persson, Sat May 15 09:02:31 2010 UTC revision 2121 by schoenebeck, Tue Sep 14 17:09:08 2010 UTC
# Line 79  namespace LinuxSampler { Line 79  namespace LinuxSampler {
79          pGlobalEvents      = new RTList<Event>(pEventPool);          pGlobalEvents      = new RTList<Event>(pEventPool);
80          FrameTime          = 0;          FrameTime          = 0;
81          RandomSeed         = 0;          RandomSeed         = 0;
82            pDedicatedVoiceChannelLeft = pDedicatedVoiceChannelRight = NULL;
83      }      }
84    
85      AbstractEngine::~AbstractEngine() {      AbstractEngine::~AbstractEngine() {
# Line 87  namespace LinuxSampler { Line 88  namespace LinuxSampler {
88          if (pEventGenerator) delete pEventGenerator;          if (pEventGenerator) delete pEventGenerator;
89          if (pGlobalEvents) delete pGlobalEvents;          if (pGlobalEvents) delete pGlobalEvents;
90          if (pSysexBuffer) delete pSysexBuffer;          if (pSysexBuffer) delete pSysexBuffer;
91            if (pDedicatedVoiceChannelLeft) delete pDedicatedVoiceChannelLeft;
92            if (pDedicatedVoiceChannelRight) delete pDedicatedVoiceChannelRight;
93          Unregister();          Unregister();
94      }      }
95    
# Line 221  namespace LinuxSampler { Line 224  namespace LinuxSampler {
224       */       */
225      void AbstractEngine::RouteAudio(EngineChannel* pEngineChannel, uint Samples) {      void AbstractEngine::RouteAudio(EngineChannel* pEngineChannel, uint Samples) {
226          AbstractEngineChannel* pChannel = static_cast<AbstractEngineChannel*>(pEngineChannel);          AbstractEngineChannel* pChannel = static_cast<AbstractEngineChannel*>(pEngineChannel);
227            AudioChannel* ppSource[2] = {
228                pChannel->pChannelLeft,
229                pChannel->pChannelRight
230            };
231          // route dry signal          // route dry signal
232          {          {
233              AudioChannel* pDstL = pAudioOutputDevice->Channel(pChannel->AudioDeviceChannelLeft);              AudioChannel* pDstL = pAudioOutputDevice->Channel(pChannel->AudioDeviceChannelLeft);
234              AudioChannel* pDstR = pAudioOutputDevice->Channel(pChannel->AudioDeviceChannelRight);              AudioChannel* pDstR = pAudioOutputDevice->Channel(pChannel->AudioDeviceChannelRight);
235              pChannel->pChannelLeft->MixTo(pDstL, Samples);              ppSource[0]->MixTo(pDstL, Samples);
236              pChannel->pChannelRight->MixTo(pDstR, Samples);              ppSource[1]->MixTo(pDstR, Samples);
237          }          }
238          // route FX send signal          // route FX send signal (wet)
239          {          {
240              for (int iFxSend = 0; iFxSend < pChannel->GetFxSendCount(); iFxSend++) {              for (int iFxSend = 0; iFxSend < pChannel->GetFxSendCount(); iFxSend++) {
241                  FxSend* pFxSend = pChannel->GetFxSend(iFxSend);                  FxSend* pFxSend = pChannel->GetFxSend(iFxSend);
242                  for (int iChan = 0; iChan < 2; ++iChan) {                  const bool success = RouteFxSend(pFxSend, ppSource, pFxSend->Level(), Samples);
243                      AudioChannel* pSource =                  if (!success) goto channel_cleanup;
                         (iChan)  
                             ? pChannel->pChannelRight  
                             : pChannel->pChannelLeft;  
                     const int iDstChan = pFxSend->DestinationChannel(iChan);  
                     if (iDstChan < 0) {  
                         dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination channel (%d->%d)", ((iChan) ? "R" : "L"), iChan, iDstChan));  
                         goto channel_cleanup;  
                     }  
                     AudioChannel* pDstChan = NULL;  
                     if (pFxSend->DestinationMasterEffectChain() >= 0) { // fx send routed to an internal master effect  
                         EffectChain* pEffectChain =  
                             pAudioOutputDevice->MasterEffectChain(  
                                 pFxSend->DestinationMasterEffectChain()  
                             );  
                         if (!pEffectChain) {  
                             dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination effect chain %d", ((iChan) ? "R" : "L"), pFxSend->DestinationMasterEffectChain()));  
                             goto channel_cleanup;  
                         }  
                         Effect* pEffect =  
                             pEffectChain->GetEffect(  
                                 pFxSend->DestinationMasterEffect()  
                             );  
                         if (!pEffect) {  
                             dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination effect %d of effect chain %d", ((iChan) ? "R" : "L"), pFxSend->DestinationMasterEffect(), pFxSend->DestinationMasterEffectChain()));  
                             goto channel_cleanup;  
                         }  
                         pDstChan = pEffect->InputChannel(iDstChan);  
                     } else { // FX send routed directly to an audio output channel  
                         pDstChan = pAudioOutputDevice->Channel(iDstChan);  
                     }  
                     if (!pDstChan) {  
                         dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination channel (%d->%d)", ((iChan) ? "R" : "L"), iChan, iDstChan));  
                         goto channel_cleanup;  
                     }  
                     pSource->MixTo(pDstChan, Samples, pFxSend->Level());  
                 }  
244              }              }
245          }          }
246          channel_cleanup:          channel_cleanup:
247          // reset buffers with silence (zero out) for the next audio cycle          // reset buffers with silence (zero out) for the next audio cycle
248          pChannel->pChannelLeft->Clear();          ppSource[0]->Clear();
249          pChannel->pChannelRight->Clear();          ppSource[1]->Clear();
250        }
251        
252        /**
253         * Similar to RouteAudio(), but this method is even more special. It is
254         * only called by voices which have dedicated effect send(s) level(s). So
255         * such voices have to be routed separately apart from the other voices
256         * which can just be mixed together and routed afterwards in one turn.
257         */
258        void AbstractEngine::RouteDedicatedVoiceChannels(EngineChannel* pEngineChannel, optional<float> FxSendLevels[2], uint Samples) {
259            AbstractEngineChannel* pChannel = static_cast<AbstractEngineChannel*>(pEngineChannel);
260            AudioChannel* ppSource[2] = {
261                pDedicatedVoiceChannelLeft,
262                pDedicatedVoiceChannelRight
263            };
264            // route dry signal
265            {
266                AudioChannel* pDstL = pAudioOutputDevice->Channel(pChannel->AudioDeviceChannelLeft);
267                AudioChannel* pDstR = pAudioOutputDevice->Channel(pChannel->AudioDeviceChannelRight);
268                ppSource[0]->MixTo(pDstL, Samples);
269                ppSource[1]->MixTo(pDstR, Samples);
270            }
271            // route FX send signals (wet)
272            // (we simply hard code the voices 'reverb send' to the 1st effect
273            // send bus, and the voioces 'chorus send' to the 2nd effect send bus)
274            {
275                for (int iFxSend = 0; iFxSend < 2 && iFxSend < pChannel->GetFxSendCount(); iFxSend++) {
276                    // no voice specific FX send level defined for this effect?
277                    if (!FxSendLevels[iFxSend]) continue; // ignore this effect then
278                    
279                    FxSend* pFxSend = pChannel->GetFxSend(iFxSend);
280                    const bool success = RouteFxSend(pFxSend, ppSource, *FxSendLevels[iFxSend], Samples);
281                    if (!success) goto channel_cleanup;
282                }
283            }
284            channel_cleanup:
285            // reset buffers with silence (zero out) for the next dedicated voice rendering/routing process
286            ppSource[0]->Clear();
287            ppSource[1]->Clear();
288        }
289        
290        /**
291         * Route the audio signal given by @a ppSource to the effect send bus
292         * defined by @a pFxSend (wet signal only).
293         *
294         * @param pFxSend - definition of effect send bus
295         * @param ppSource - the 2 channels of the audio signal to be routed
296         * @param FxSendLevel - the effect send level to by applied
297         * @param Samples - amount of sample points to be processed
298         * @returns true if signal was routed successfully, false on error
299         */
300        bool AbstractEngine::RouteFxSend(FxSend* pFxSend, AudioChannel* ppSource[2], float FxSendLevel, uint Samples) {
301            for (int iChan = 0; iChan < 2; ++iChan) {
302                const int iDstChan = pFxSend->DestinationChannel(iChan);
303                if (iDstChan < 0) {
304                    dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination channel (%d->%d)", ((iChan) ? "R" : "L"), iChan, iDstChan));
305                    return false; // error
306                }
307                AudioChannel* pDstChan = NULL;
308                if (pFxSend->DestinationMasterEffectChain() >= 0) { // fx send routed to an internal master effect
309                    EffectChain* pEffectChain =
310                        pAudioOutputDevice->MasterEffectChain(
311                            pFxSend->DestinationMasterEffectChain()
312                        );
313                    if (!pEffectChain) {
314                        dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination effect chain %d", ((iChan) ? "R" : "L"), pFxSend->DestinationMasterEffectChain()));
315                        return false; // error
316                    }
317                    Effect* pEffect =
318                        pEffectChain->GetEffect(
319                            pFxSend->DestinationMasterEffect()
320                        );
321                    if (!pEffect) {
322                        dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination effect %d of effect chain %d", ((iChan) ? "R" : "L"), pFxSend->DestinationMasterEffect(), pFxSend->DestinationMasterEffectChain()));
323                        return false; // error
324                    }
325                    pDstChan = pEffect->InputChannel(iDstChan);
326                } else { // FX send routed directly to an audio output channel
327                    pDstChan = pAudioOutputDevice->Channel(iDstChan);
328                }
329                if (!pDstChan) {
330                    dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination channel (%d->%d)", ((iChan) ? "R" : "L"), iChan, iDstChan));
331                    return false; // error
332                }
333                ppSource[iChan]->MixTo(pDstChan, Samples, FxSendLevel);
334            }
335            return true; // success
336      }      }
337    
338      /**      /**

Legend:
Removed from v.2091  
changed lines
  Added in v.2121

  ViewVC Help
Powered by ViewVC