/[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 2165 by persson, Sun Feb 20 14:20:22 2011 UTC revision 2614 by schoenebeck, Tue Jun 10 17:22:48 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-2011 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 59  namespace LinuxSampler { Line 60  namespace LinuxSampler {
60              typedef typename RTList<R*>::Iterator RTListRegionIterator;              typedef typename RTList<R*>::Iterator RTListRegionIterator;
61              typedef typename MidiKeyboardManager<V>::MidiKey MidiKey;              typedef typename MidiKeyboardManager<V>::MidiKey MidiKey;
62    
63                virtual MidiKeyboardManagerBase* GetMidiKeyboardManager() OVERRIDE {
64                    return this;
65                }
66    
67              virtual void HandBack(I* Instrument) {              virtual void HandBack(I* Instrument) {
68                  ResourceManager<InstrumentManager::instrument_id_t, I>* mgr =                  ResourceManager<InstrumentManager::instrument_id_t, I>* mgr =
69                      dynamic_cast<ResourceManager<InstrumentManager::instrument_id_t, I>*>(pEngine->GetInstrumentManager());                      dynamic_cast<ResourceManager<InstrumentManager::instrument_id_t, I>*>(pEngine->GetInstrumentManager());
# Line 84  namespace LinuxSampler { Line 89  namespace LinuxSampler {
89              }              }
90    
91              virtual void DeleteRegionsInUse() {              virtual void DeleteRegionsInUse() {
92                    RTList<R*>* previous = NULL; // prevent double free
93                  {                  {
94                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
95                      if (cmd.pRegionsInUse) {                      if (cmd.pRegionsInUse) {
96                            previous = cmd.pRegionsInUse;
97                          delete cmd.pRegionsInUse;                          delete cmd.pRegionsInUse;
98                          cmd.pRegionsInUse = NULL;                          cmd.pRegionsInUse = NULL;
99                      }                      }
# Line 95  namespace LinuxSampler { Line 102  namespace LinuxSampler {
102                  {                  {
103                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
104                      if (cmd.pRegionsInUse) {                      if (cmd.pRegionsInUse) {
105                          delete cmd.pRegionsInUse;                          if (cmd.pRegionsInUse != previous)
106                                delete cmd.pRegionsInUse;
107                          cmd.pRegionsInUse = NULL;                          cmd.pRegionsInUse = NULL;
108                      }                      }
109                      cmd.bChangeInstrument = false;                      cmd.bChangeInstrument = false;
# Line 120  namespace LinuxSampler { Line 128  namespace LinuxSampler {
128                      if (pEngine->pAudioOutputDevice == pAudioOut) return;                      if (pEngine->pAudioOutputDevice == pAudioOut) return;
129                      DisconnectAudioOutputDevice();                      DisconnectAudioOutputDevice();
130                  }                  }
131                  pEngine = AbstractEngine::AcquireEngine(this, pAudioOut);                  AbstractEngine* newEngine = AbstractEngine::AcquireEngine(this, pAudioOut);
132                    {
133                        LockGuard lock(EngineMutex);
134                        pEngine = newEngine;
135                    }
136                  ResetInternal();                  ResetInternal();
137                  pEvents = new RTList<Event>(pEngine->pEventPool);                  pEvents = new RTList<Event>(pEngine->pEventPool);
138    
# Line 175  namespace LinuxSampler { Line 187  namespace LinuxSampler {
187                      ResetInternal();                      ResetInternal();
188    
189                      DeleteRegionsInUse();                      DeleteRegionsInUse();
190                        UnloadScriptInUse();
191    
192                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
193                      if (cmd.pInstrument) {                      if (cmd.pInstrument) {
# Line 192  namespace LinuxSampler { Line 205  namespace LinuxSampler {
205                      DeleteGroupEventLists();                      DeleteGroupEventLists();
206    
207                      AudioOutputDevice* oldAudioDevice = pEngine->pAudioOutputDevice;                      AudioOutputDevice* oldAudioDevice = pEngine->pAudioOutputDevice;
208                      pEngine = NULL;                      {
209                            LockGuard lock(EngineMutex);
210                            pEngine = NULL;
211                        }
212                      AbstractEngine::FreeEngine(this, oldAudioDevice);                      AbstractEngine::FreeEngine(this, oldAudioDevice);
213                      AudioDeviceChannelLeft  = -1;                      AudioDeviceChannelLeft  = -1;
214                      AudioDeviceChannelRight = -1;                      AudioDeviceChannelRight = -1;
# Line 214  namespace LinuxSampler { Line 230  namespace LinuxSampler {
230                  pEvents->clear();                  pEvents->clear();
231                  // empty MIDI key specific event lists                  // empty MIDI key specific event lists
232                  ClearEventListsHandler handler;                  ClearEventListsHandler handler;
233                  ProcessActiveVoices(&handler);                  this->ProcessActiveVoices(&handler);
234    
235                  // empty exclusive group specific event lists                  // empty exclusive group specific event lists
236                  ClearGroupEventLists();                  // (pInstrument == 0 could mean that LoadInstrument is
237                    // building new group event lists, so we must check
238                    // for that)
239                    if (pInstrument) ClearGroupEventLists();
240              }              }
241    
242              // implementation of abstract methods derived from interface class 'InstrumentConsumer'              // implementation of abstract methods derived from interface class 'InstrumentConsumer'
# Line 227  namespace LinuxSampler { Line 246  namespace LinuxSampler {
246               * we are currently using on this EngineChannel is going to be updated,               * we are currently using on this EngineChannel is going to be updated,
247               * so we can stop playback before that happens.               * so we can stop playback before that happens.
248               */               */
249              virtual void ResourceToBeUpdated(I* pResource, void*& pUpdateArg) {              virtual void ResourceToBeUpdated(I* pResource, void*& pUpdateArg) OVERRIDE {
250                  dmsg(3,("EngineChannelBase: Received instrument update message.\n"));                  dmsg(3,("EngineChannelBase: Received instrument update message.\n"));
251                  if (pEngine) pEngine->DisableAndLock();                  if (pEngine) pEngine->DisableAndLock();
252                  ResetInternal();                  ResetInternal();
# Line 238  namespace LinuxSampler { Line 257  namespace LinuxSampler {
257               * Will be called by the InstrumentResourceManager when the instrument               * Will be called by the InstrumentResourceManager when the instrument
258               * update process was completed, so we can continue with playback.               * update process was completed, so we can continue with playback.
259               */               */
260              virtual void ResourceUpdated(I* pOldResource, I* pNewResource, void* pUpdateArg) {              virtual void ResourceUpdated(I* pOldResource, I* pNewResource, void* pUpdateArg) OVERRIDE {
261                  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())
262                  if (pEngine) pEngine->Enable();                  if (pEngine) pEngine->Enable();
263                  bStatusChanged = true; // status of engine has changed, so set notify flag                  bStatusChanged = true; // status of engine has changed, so set notify flag
# Line 250  namespace LinuxSampler { Line 269  namespace LinuxSampler {
269               *               *
270               * @param fProgress - current progress as value between 0.0 and 1.0               * @param fProgress - current progress as value between 0.0 and 1.0
271               */               */
272              virtual void OnResourceProgress(float fProgress) {              virtual void OnResourceProgress(float fProgress) OVERRIDE {
273                  this->InstrumentStat = int(fProgress * 100.0f);                  this->InstrumentStat = int(fProgress * 100.0f);
274                  dmsg(7,("EngineChannelBase: progress %d%", InstrumentStat));                  dmsg(7,("EngineChannelBase: progress %d%", InstrumentStat));
275                  bStatusChanged = true; // status of engine has changed, so set notify flag                  bStatusChanged = true; // status of engine has changed, so set notify flag
# Line 258  namespace LinuxSampler { Line 277  namespace LinuxSampler {
277    
278              void RenderActiveVoices(uint Samples) {              void RenderActiveVoices(uint Samples) {
279                  RenderVoicesHandler handler(this, Samples);                  RenderVoicesHandler handler(this, Samples);
280                  ProcessActiveVoices(&handler);                  this->ProcessActiveVoices(&handler);
281    
282                  SetVoiceCount(handler.VoiceCount);                  SetVoiceCount(handler.VoiceCount);
283                  SetDiskStreamCount(handler.StreamCount);                  SetDiskStreamCount(handler.StreamCount);
# Line 279  namespace LinuxSampler { Line 298  namespace LinuxSampler {
298                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
299                      cmd.pRegionsInUse = NULL;                      cmd.pRegionsInUse = NULL;
300                      cmd.pInstrument = NULL;                      cmd.pInstrument = NULL;
301                        cmd.pScript = new InstrumentScript(this);
302                      cmd.bChangeInstrument = false;                      cmd.bChangeInstrument = false;
303                  }                  }
304                  {                  {
305                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
306                      cmd.pRegionsInUse = NULL;                      cmd.pRegionsInUse = NULL;
307                      cmd.pInstrument = NULL;                      cmd.pInstrument = NULL;
308                        cmd.pScript = new InstrumentScript(this);
309                      cmd.bChangeInstrument = false;                      cmd.bChangeInstrument = false;
310                  }                  }
311              }              }
312    
313              virtual ~EngineChannelBase() { }              virtual ~EngineChannelBase() {
314                    InstrumentScript* previous = NULL; // prevent double free
315                    {
316                        InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
317                        if (cmd.pScript) {
318                            previous = cmd.pScript;
319                            delete cmd.pScript;
320                            cmd.pScript = NULL;
321                        }
322                    }
323                    {
324                        InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
325                        if (cmd.pScript) {
326                            if (previous != cmd.pScript)
327                                delete cmd.pScript;
328                            cmd.pScript = NULL;
329                        }
330                    }
331                }
332    
333              typedef typename RTList<V>::Iterator RTListVoiceIterator;              typedef typename RTList<V>::Iterator RTListVoiceIterator;
334    
# Line 316  namespace LinuxSampler { Line 355  namespace LinuxSampler {
355                                  if ((itVoice->DiskStreamRef).State != Stream::state_unused) StreamCount++;                                  if ((itVoice->DiskStreamRef).State != Stream::state_unused) StreamCount++;
356                              }                              }
357                          }  else { // voice reached end, is now inactive                          }  else { // voice reached end, is now inactive
358                                itVoice->VoiceFreed();
359                              pChannel->FreeVoice(itVoice); // remove voice from the list of active voices                              pChannel->FreeVoice(itVoice); // remove voice from the list of active voices
360                          }                          }
361                      }                      }
# Line 341  namespace LinuxSampler { Line 381  namespace LinuxSampler {
381              }              }
382    
383              /**              /**
384                 * Unload the currently used and loaded real-time instrument script.
385                 * The source code of the script is retained, so that it can still
386                 * be reloaded.
387                 */
388                void UnloadScriptInUse() {
389                    {
390                        InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
391                        if (cmd.pScript) pScript->unload();
392                    }
393                    {
394                        InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
395                        if (cmd.pScript) pScript->unload();
396                    }
397                    InstrumentChangeCommand.SwitchConfig(); // switch back to original one
398                }
399    
400                /**
401                 * Load real-time instrument script and all its resources required
402                 * for the upcoming instrument change.
403                 *
404                 * @param text - source code of script
405                 */
406                void LoadInstrumentScript(const String& text) {
407                    InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
408                    // load the new script
409                    cmd.pScript->load(text);
410                }
411    
412                /**
413               * Changes the instrument for an engine channel.               * Changes the instrument for an engine channel.
414               *               *
415               * @param pInstrument - new instrument               * @param pInstrument - new instrument

Legend:
Removed from v.2165  
changed lines
  Added in v.2614

  ViewVC Help
Powered by ViewVC