/[svn]/linuxsampler/trunk/src/engines/EngineChannelBase.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/EngineChannelBase.h

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

revision 2114 by persson, Tue Aug 10 12:05:19 2010 UTC revision 2612 by schoenebeck, Tue Jun 10 13:32:16 2014 UTC
# Line 4  Line 4 
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck    *   *   Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck    *
6   *   Copyright (C) 2005-2008 Christian Schoenebeck                         *   *   Copyright (C) 2005-2008 Christian Schoenebeck                         *
7   *   Copyright (C) 2009-2010 Christian Schoenebeck and Grigor Iliev        *   *   Copyright (C) 2009-2013 Christian Schoenebeck and Grigor Iliev        *
8   *                                                                         *   *                                                                         *
9   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
10   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 39  namespace LinuxSampler { Line 39  namespace LinuxSampler {
39              bool bChangeInstrument;       ///< Set to true by the loader when the channel should change instrument.              bool bChangeInstrument;       ///< Set to true by the loader when the channel should change instrument.
40              I* pInstrument;               ///< The new instrument. Also used by the loader to read the previously loaded instrument.              I* pInstrument;               ///< The new instrument. Also used by the loader to read the previously loaded instrument.
41              RTList<R*>* pRegionsInUse; ///< List of dimension regions in use by the currently loaded instrument. Continuously updated by the audio thread.              RTList<R*>* pRegionsInUse; ///< List of dimension regions in use by the currently loaded instrument. Continuously updated by the audio thread.
42                InstrumentScript* pScript; ///< Instrument script to be executed for this instrument, or NULL if instrument does not have a script.
43      };      };
44    
45      template<class R>      template<class R>
# Line 68  namespace LinuxSampler { Line 69  namespace LinuxSampler {
69              virtual void ClearRegionsInUse() {              virtual void ClearRegionsInUse() {
70                  {                  {
71                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
72                      if(cmd.pRegionsInUse != NULL) cmd.pRegionsInUse->clear();                      if (cmd.pRegionsInUse) cmd.pRegionsInUse->clear();
73                        cmd.bChangeInstrument = false;
74                  }                  }
75                  {                  {
76                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
77                      if(cmd.pRegionsInUse != NULL) cmd.pRegionsInUse->clear();                      if (cmd.pRegionsInUse) cmd.pRegionsInUse->clear();
78                        cmd.bChangeInstrument = false;
79                  }                  }
80              }              }
81    
# Line 82  namespace LinuxSampler { Line 85  namespace LinuxSampler {
85              }              }
86    
87              virtual void DeleteRegionsInUse() {              virtual void DeleteRegionsInUse() {
88                    RTList<R*>* previous = NULL; // prevent double free
89                  {                  {
90                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
91                      if(cmd.pRegionsInUse != NULL) {                      if (cmd.pRegionsInUse) {
92                            previous = cmd.pRegionsInUse;
93                          delete cmd.pRegionsInUse;                          delete cmd.pRegionsInUse;
94                          cmd.pRegionsInUse = NULL;                          cmd.pRegionsInUse = NULL;
95                      }                      }
96                        cmd.bChangeInstrument = false;
97                  }                  }
98                  {                  {
99                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
100                      if(cmd.pRegionsInUse != NULL) {                      if (cmd.pRegionsInUse) {
101                          delete cmd.pRegionsInUse;                          if (cmd.pRegionsInUse != previous)
102                                delete cmd.pRegionsInUse;
103                          cmd.pRegionsInUse = NULL;                          cmd.pRegionsInUse = NULL;
104                      }                      }
105                        cmd.bChangeInstrument = false;
106                  }                  }
107              }              }
108    
# Line 102  namespace LinuxSampler { Line 110  namespace LinuxSampler {
110                  {                  {
111                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
112                      cmd.pRegionsInUse = new RTList<R*>(pRegionPool[0]);                      cmd.pRegionsInUse = new RTList<R*>(pRegionPool[0]);
113                        cmd.bChangeInstrument = false;
114                  }                  }
115                  {                  {
116                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
117                      cmd.pRegionsInUse = new RTList<R*>(pRegionPool[1]);                      cmd.pRegionsInUse = new RTList<R*>(pRegionPool[1]);
118                        cmd.bChangeInstrument = false;
119                  }                  }
120              }              }
121    
# Line 114  namespace LinuxSampler { Line 124  namespace LinuxSampler {
124                      if (pEngine->pAudioOutputDevice == pAudioOut) return;                      if (pEngine->pAudioOutputDevice == pAudioOut) return;
125                      DisconnectAudioOutputDevice();                      DisconnectAudioOutputDevice();
126                  }                  }
127                  pEngine = AbstractEngine::AcquireEngine(this, pAudioOut);                  AbstractEngine* newEngine = AbstractEngine::AcquireEngine(this, pAudioOut);
128                    {
129                        LockGuard lock(EngineMutex);
130                        pEngine = newEngine;
131                    }
132                  ResetInternal();                  ResetInternal();
133                  pEvents = new RTList<Event>(pEngine->pEventPool);                  pEvents = new RTList<Event>(pEngine->pEventPool);
134    
# Line 169  namespace LinuxSampler { Line 183  namespace LinuxSampler {
183                      ResetInternal();                      ResetInternal();
184    
185                      DeleteRegionsInUse();                      DeleteRegionsInUse();
186                        UnloadScriptInUse();
187    
188                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
189                      if (cmd.pInstrument) {                      if (cmd.pInstrument) {
# Line 186  namespace LinuxSampler { Line 201  namespace LinuxSampler {
201                      DeleteGroupEventLists();                      DeleteGroupEventLists();
202    
203                      AudioOutputDevice* oldAudioDevice = pEngine->pAudioOutputDevice;                      AudioOutputDevice* oldAudioDevice = pEngine->pAudioOutputDevice;
204                      pEngine = NULL;                      {
205                            LockGuard lock(EngineMutex);
206                            pEngine = NULL;
207                        }
208                      AbstractEngine::FreeEngine(this, oldAudioDevice);                      AbstractEngine::FreeEngine(this, oldAudioDevice);
209                      AudioDeviceChannelLeft  = -1;                      AudioDeviceChannelLeft  = -1;
210                      AudioDeviceChannelRight = -1;                      AudioDeviceChannelRight = -1;
# Line 208  namespace LinuxSampler { Line 226  namespace LinuxSampler {
226                  pEvents->clear();                  pEvents->clear();
227                  // empty MIDI key specific event lists                  // empty MIDI key specific event lists
228                  ClearEventListsHandler handler;                  ClearEventListsHandler handler;
229                  ProcessActiveVoices(&handler);                  this->ProcessActiveVoices(&handler);
230    
231                  // empty exclusive group specific event lists                  // empty exclusive group specific event lists
232                  ClearGroupEventLists();                  // (pInstrument == 0 could mean that LoadInstrument is
233                    // building new group event lists, so we must check
234                    // for that)
235                    if (pInstrument) ClearGroupEventLists();
236              }              }
237    
238              // implementation of abstract methods derived from interface class 'InstrumentConsumer'              // implementation of abstract methods derived from interface class 'InstrumentConsumer'
# Line 221  namespace LinuxSampler { Line 242  namespace LinuxSampler {
242               * we are currently using on this EngineChannel is going to be updated,               * we are currently using on this EngineChannel is going to be updated,
243               * so we can stop playback before that happens.               * so we can stop playback before that happens.
244               */               */
245              virtual void ResourceToBeUpdated(I* pResource, void*& pUpdateArg) {              virtual void ResourceToBeUpdated(I* pResource, void*& pUpdateArg) OVERRIDE {
246                  dmsg(3,("EngineChannelBase: Received instrument update message.\n"));                  dmsg(3,("EngineChannelBase: Received instrument update message.\n"));
247                  if (pEngine) pEngine->DisableAndLock();                  if (pEngine) pEngine->DisableAndLock();
248                  ResetInternal();                  ResetInternal();
# Line 232  namespace LinuxSampler { Line 253  namespace LinuxSampler {
253               * Will be called by the InstrumentResourceManager when the instrument               * Will be called by the InstrumentResourceManager when the instrument
254               * update process was completed, so we can continue with playback.               * update process was completed, so we can continue with playback.
255               */               */
256              virtual void ResourceUpdated(I* pOldResource, I* pNewResource, void* pUpdateArg) {              virtual void ResourceUpdated(I* pOldResource, I* pNewResource, void* pUpdateArg) OVERRIDE {
257                  this->pInstrument = pNewResource; //TODO: there are couple of engine parameters we should update here as well if the instrument was updated (see LoadInstrument())                  this->pInstrument = pNewResource; //TODO: there are couple of engine parameters we should update here as well if the instrument was updated (see LoadInstrument())
258                  if (pEngine) pEngine->Enable();                  if (pEngine) pEngine->Enable();
259                  bStatusChanged = true; // status of engine has changed, so set notify flag                  bStatusChanged = true; // status of engine has changed, so set notify flag
# Line 244  namespace LinuxSampler { Line 265  namespace LinuxSampler {
265               *               *
266               * @param fProgress - current progress as value between 0.0 and 1.0               * @param fProgress - current progress as value between 0.0 and 1.0
267               */               */
268              virtual void OnResourceProgress(float fProgress) {              virtual void OnResourceProgress(float fProgress) OVERRIDE {
269                  this->InstrumentStat = int(fProgress * 100.0f);                  this->InstrumentStat = int(fProgress * 100.0f);
270                  dmsg(7,("EngineChannelBase: progress %d%", InstrumentStat));                  dmsg(7,("EngineChannelBase: progress %d%", InstrumentStat));
271                  bStatusChanged = true; // status of engine has changed, so set notify flag                  bStatusChanged = true; // status of engine has changed, so set notify flag
# Line 252  namespace LinuxSampler { Line 273  namespace LinuxSampler {
273    
274              void RenderActiveVoices(uint Samples) {              void RenderActiveVoices(uint Samples) {
275                  RenderVoicesHandler handler(this, Samples);                  RenderVoicesHandler handler(this, Samples);
276                  ProcessActiveVoices(&handler);                  this->ProcessActiveVoices(&handler);
277    
278                  SetVoiceCount(handler.VoiceCount);                  SetVoiceCount(handler.VoiceCount);
279                  SetDiskStreamCount(handler.StreamCount);                  SetDiskStreamCount(handler.StreamCount);
# Line 273  namespace LinuxSampler { Line 294  namespace LinuxSampler {
294                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
295                      cmd.pRegionsInUse = NULL;                      cmd.pRegionsInUse = NULL;
296                      cmd.pInstrument = NULL;                      cmd.pInstrument = NULL;
297                        cmd.pScript = new InstrumentScript(this);
298                      cmd.bChangeInstrument = false;                      cmd.bChangeInstrument = false;
299                  }                  }
300                  {                  {
301                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
302                      cmd.pRegionsInUse = NULL;                      cmd.pRegionsInUse = NULL;
303                      cmd.pInstrument = NULL;                      cmd.pInstrument = NULL;
304                        cmd.pScript = new InstrumentScript(this);
305                      cmd.bChangeInstrument = false;                      cmd.bChangeInstrument = false;
306                  }                  }
307              }              }
308    
309              virtual ~EngineChannelBase() { }              virtual ~EngineChannelBase() {
310                    InstrumentScript* previous = NULL; // prevent double free
311                    {
312                        InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
313                        if (cmd.pScript) {
314                            previous = cmd.pScript;
315                            delete cmd.pScript;
316                            cmd.pScript = NULL;
317                        }
318                    }
319                    {
320                        InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
321                        if (cmd.pScript) {
322                            if (previous != cmd.pScript)
323                                delete cmd.pScript;
324                            cmd.pScript = NULL;
325                        }
326                    }
327                }
328    
329              typedef typename RTList<V>::Iterator RTListVoiceIterator;              typedef typename RTList<V>::Iterator RTListVoiceIterator;
330    
# Line 310  namespace LinuxSampler { Line 351  namespace LinuxSampler {
351                                  if ((itVoice->DiskStreamRef).State != Stream::state_unused) StreamCount++;                                  if ((itVoice->DiskStreamRef).State != Stream::state_unused) StreamCount++;
352                              }                              }
353                          }  else { // voice reached end, is now inactive                          }  else { // voice reached end, is now inactive
354                                itVoice->VoiceFreed();
355                              pChannel->FreeVoice(itVoice); // remove voice from the list of active voices                              pChannel->FreeVoice(itVoice); // remove voice from the list of active voices
356                          }                          }
357                      }                      }
# Line 335  namespace LinuxSampler { Line 377  namespace LinuxSampler {
377              }              }
378    
379              /**              /**
380                 * Unload the currently used and loaded real-time instrument script.
381                 * The source code of the script is retained, so that it can still
382                 * be reloaded.
383                 */
384                void UnloadScriptInUse() {
385                    {
386                        InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
387                        if (cmd.pScript) pScript->unload();
388                    }
389                    {
390                        InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
391                        if (cmd.pScript) pScript->unload();
392                    }
393                }
394    
395                /**
396                 * Load real-time instrument script and all its resources required
397                 * for the upcoming instrument change.
398                 *
399                 * @param text - source code of script
400                 */
401                void LoadInstrumentScript(const String& text) {
402                    InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
403                    // load the new script
404                    cmd.pScript->load(text);
405                }
406    
407                /**
408               * Changes the instrument for an engine channel.               * Changes the instrument for an engine channel.
409               *               *
410               * @param pInstrument - new instrument               * @param pInstrument - new instrument

Legend:
Removed from v.2114  
changed lines
  Added in v.2612

  ViewVC Help
Powered by ViewVC