/[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 2613 by schoenebeck, Tue Jun 10 15:17:01 2014 UTC revision 2879 by schoenebeck, Tue Apr 19 14:07:53 2016 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-2013 Christian Schoenebeck and Grigor Iliev        *   *   Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev        *
8     *   Copyright (C) 2012-2016 Christian Schoenebeck and Andreas Persson     *
9   *                                                                         *   *                                                                         *
10   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
11   *   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 40  namespace LinuxSampler {
40              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.
41              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.
42              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.
43              InstrumentScript* pScript; ///< Instrument script to be executed for this instrument, or NULL if instrument does not have a script.              InstrumentScript* pScript; ///< Instrument script to be executed for this instrument. This is never NULL, it is always a valid InstrumentScript pointer. Use InstrumentScript::bHasValidScript whether it reflects a valid instrument script to be executed.
44      };      };
45    
46      template<class R>      template<class R>
# Line 49  namespace LinuxSampler { Line 50  namespace LinuxSampler {
50      };      };
51    
52      template<class V>      template<class V>
53      class VoicePool {      class NotePool {
54          public:          public:
55              virtual Pool<V>* GetVoicePool() = 0;              virtual Pool<V>* GetVoicePool() = 0;
56                virtual Pool< Note<V> >* GetNotePool() = 0;
57                virtual Pool<note_id_t>* GetNodeIDPool() = 0;
58      };      };
59    
60      template <class V /* Voice */, class R /* Region */, class I /* Instrument */>      template <class V /* Voice */, class R /* Region */, class I /* Instrument */>
# Line 133  namespace LinuxSampler { Line 136  namespace LinuxSampler {
136                      LockGuard lock(EngineMutex);                      LockGuard lock(EngineMutex);
137                      pEngine = newEngine;                      pEngine = newEngine;
138                  }                  }
139                  ResetInternal();                  ResetInternal(false/*don't reset engine*/); // 'false' is error prone here, but the danger of recursion with 'true' would be worse, there could be a better solution though
140                  pEvents = new RTList<Event>(pEngine->pEventPool);                  pEvents = new RTList<Event>(pEngine->pEventPool);
141                    delayedEvents.pList = new RTList<Event>(pEngine->pEventPool);
142    
143                  RegionPools<R>* pRegionPool = dynamic_cast<RegionPools<R>*>(pEngine);                  RegionPools<R>* pRegionPool = dynamic_cast<RegionPools<R>*>(pEngine);
144                  // reset the instrument change command struct (need to be done                  // reset the instrument change command struct (need to be done
# Line 161  namespace LinuxSampler { Line 165  namespace LinuxSampler {
165                      bStatusChanged = true;                      bStatusChanged = true;
166                  }                  }
167    
168                  VoicePool<V>* pVoicePool = dynamic_cast<VoicePool<V>*>(pEngine);                  NotePool<V>* pNotePool = dynamic_cast<NotePool<V>*>(pEngine);
169                  MidiKeyboardManager<V>::AllocateActiveVoices(pVoicePool->GetVoicePool());                  MidiKeyboardManager<V>::AllocateActiveNotesLists(
170                  MidiKeyboardManager<V>::AllocateEvents(pEngine->pEventPool);                      pNotePool->GetNotePool(),
171                        pNotePool->GetVoicePool()
172                    );
173                    MidiKeyboardManager<V>::AllocateEventsLists(pEngine->pEventPool);
174    
175                  AudioDeviceChannelLeft  = 0;                  AudioDeviceChannelLeft  = 0;
176                  AudioDeviceChannelRight = 1;                  AudioDeviceChannelRight = 1;
# Line 184  namespace LinuxSampler { Line 191  namespace LinuxSampler {
191              virtual void DisconnectAudioOutputDevice() {              virtual void DisconnectAudioOutputDevice() {
192                  if (pEngine) { // if clause to prevent disconnect loops                  if (pEngine) { // if clause to prevent disconnect loops
193    
194                      ResetInternal();                      ResetInternal(false/*don't reset engine*/); // 'false' is error prone here, but the danger of recursion with 'true' would be worse, there could be a better solution though
195    
196                      DeleteRegionsInUse();                      DeleteRegionsInUse();
197                      UnloadScriptInUse();                      UnloadScriptInUse();
# Line 199  namespace LinuxSampler { Line 206  namespace LinuxSampler {
206                          delete pEvents;                          delete pEvents;
207                          pEvents = NULL;                          pEvents = NULL;
208                      }                      }
209                        if (delayedEvents.pList) {
210                            delete delayedEvents.pList;
211                            delayedEvents.pList = NULL;
212                        }
213    
214                      MidiKeyboardManager<V>::DeleteActiveVoices();                      MidiKeyboardManager<V>::DeleteActiveNotesLists();
215                      MidiKeyboardManager<V>::DeleteEvents();                      MidiKeyboardManager<V>::DeleteEventsLists();
216                      DeleteGroupEventLists();                      DeleteGroupEventLists();
217    
218                      AudioOutputDevice* oldAudioDevice = pEngine->pAudioOutputDevice;                      AudioOutputDevice* oldAudioDevice = pEngine->pAudioOutputDevice;
# Line 226  namespace LinuxSampler { Line 237  namespace LinuxSampler {
237                      virtual bool Process(MidiKey* pMidiKey) { pMidiKey->pEvents->clear(); return false; }                      virtual bool Process(MidiKey* pMidiKey) { pMidiKey->pEvents->clear(); return false; }
238              };              };
239    
240              void ClearEventLists() {              /**
241                 * Free all events of the current audio fragment cycle. Calling
242                 * this method will @b NOT free events scheduled past the current
243                 * fragment's boundary! (@see AbstractEngineChannel::delayedEvents).
244                 */
245                void ClearEventListsOfCurrentFragment() {
246                  pEvents->clear();                  pEvents->clear();
247                  // empty MIDI key specific event lists                  // empty MIDI key specific event lists
248                  ClearEventListsHandler handler;                  ClearEventListsHandler handler;
# Line 249  namespace LinuxSampler { Line 265  namespace LinuxSampler {
265              virtual void ResourceToBeUpdated(I* pResource, void*& pUpdateArg) OVERRIDE {              virtual void ResourceToBeUpdated(I* pResource, void*& pUpdateArg) OVERRIDE {
266                  dmsg(3,("EngineChannelBase: Received instrument update message.\n"));                  dmsg(3,("EngineChannelBase: Received instrument update message.\n"));
267                  if (pEngine) pEngine->DisableAndLock();                  if (pEngine) pEngine->DisableAndLock();
268                  ResetInternal();                  ResetInternal(false/*don't reset engine*/);
269                  this->pInstrument = NULL;                  this->pInstrument = NULL;
270              }              }
271    
# Line 271  namespace LinuxSampler { Line 287  namespace LinuxSampler {
287               */               */
288              virtual void OnResourceProgress(float fProgress) OVERRIDE {              virtual void OnResourceProgress(float fProgress) OVERRIDE {
289                  this->InstrumentStat = int(fProgress * 100.0f);                  this->InstrumentStat = int(fProgress * 100.0f);
290                  dmsg(7,("EngineChannelBase: progress %d%", InstrumentStat));                  dmsg(7,("EngineChannelBase: progress %d%%", InstrumentStat));
291                  bStatusChanged = true; // status of engine has changed, so set notify flag                  bStatusChanged = true; // status of engine has changed, so set notify flag
292              }              }
293    
# Line 283  namespace LinuxSampler { Line 299  namespace LinuxSampler {
299                  SetDiskStreamCount(handler.StreamCount);                  SetDiskStreamCount(handler.StreamCount);
300              }              }
301    
302                /**
303                 * Called by real-time instrument script functions to schedule a
304                 * new note (new note-on event and a new @c Note object linked to it)
305                 * @a delay microseconds in future.
306                 *
307                 * @b IMPORTANT: for the supplied @a delay to be scheduled
308                 * correctly, the passed @a pEvent must be assigned a valid
309                 * fragment time within the current audio fragment boundaries. That
310                 * fragment time will be used by this method as basis for
311                 * interpreting what "now" acutally is, and thus it will be used as
312                 * basis for calculating the precise scheduling time for @a delay.
313                 * The easiest way to achieve this is by copying a recent event
314                 * which happened within the current audio fragment cycle: i.e. the
315                 * original event which caused calling this method here, or by using
316                 * Event::copyTimefrom() method to only copy the time, without any
317                 * other event data.
318                 *
319                 * @param pEvent - note-on event to be scheduled in future (event
320                 *                 data will be copied)
321                 * @param delay - amount of microseconds in future (from now) when
322                 *                event shall be processed
323                 * @returns unique note ID of scheduled new note, or NULL on error
324                 */
325                note_id_t ScheduleNoteMicroSec(const Event* pEvent, int delay) OVERRIDE {
326                    // add (copied) note-on event into scheduler queue
327                    const event_id_t noteOnEventID = ScheduleEventMicroSec(pEvent, delay);
328                    if (!noteOnEventID) return 0; // error
329                    // get access to (copied) event on the scheduler queue
330                    RTList<Event>::Iterator itEvent = pEvents->fromID(noteOnEventID);
331                    // stick a new note to the (copied) event on the queue
332                    const note_id_t noteID = pEngine->LaunchNewNote(this, &*itEvent);
333                    return noteID;
334                }
335    
336              RTList<R*>* pRegionsInUse;     ///< temporary pointer into the instrument change command, used by the audio thread              RTList<R*>* pRegionsInUse;     ///< temporary pointer into the instrument change command, used by the audio thread
337              I* pInstrument;              I* pInstrument;
338    
339              template<class TV, class TRR, class TR, class TD, class TIM, class TI> friend class EngineBase;              template<class TV, class TRR, class TR, class TD, class TIM, class TI> friend class EngineBase;
340    
341          protected:          protected:
342              EngineChannelBase() : InstrumentChangeCommandReader(InstrumentChangeCommand) {              EngineChannelBase() :
343                    MidiKeyboardManager<V>(this),
344                    InstrumentChangeCommandReader(InstrumentChangeCommand)
345                {
346                  pInstrument = NULL;                  pInstrument = NULL;
347    
348                  // reset the instrument change command struct (need to be done                  // reset the instrument change command struct (need to be done
# Line 367  namespace LinuxSampler { Line 420  namespace LinuxSampler {
420              SyncConfInstrChangeCmdReader InstrumentChangeCommandReader;              SyncConfInstrChangeCmdReader InstrumentChangeCommandReader;
421    
422              /** This method is not thread safe! */              /** This method is not thread safe! */
423              virtual void ResetInternal() {              virtual void ResetInternal(bool bResetEngine) OVERRIDE {
424                  AbstractEngineChannel::ResetInternal();                  AbstractEngineChannel::ResetInternal(bResetEngine);
425    
426                  MidiKeyboardManager<V>::Reset();                  MidiKeyboardManager<V>::Reset();
427              }              }
# Line 388  namespace LinuxSampler { Line 441  namespace LinuxSampler {
441              void UnloadScriptInUse() {              void UnloadScriptInUse() {
442                  {                  {
443                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.GetConfigForUpdate();
444                      if (cmd.pScript) pScript->unload();                      if (cmd.pScript) cmd.pScript->unload();
445                  }                  }
446                  {                  {
447                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();                      InstrumentChangeCmd<R, I>& cmd = InstrumentChangeCommand.SwitchConfig();
448                      if (cmd.pScript) pScript->unload();                      if (cmd.pScript) cmd.pScript->unload();
449                  }                  }
450                    InstrumentChangeCommand.SwitchConfig(); // switch back to original one
451              }              }
452    
453              /**              /**

Legend:
Removed from v.2613  
changed lines
  Added in v.2879

  ViewVC Help
Powered by ViewVC