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

Diff of /linuxsampler/trunk/src/engines/gig/Engine.cpp

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

revision 56 by schoenebeck, Tue Apr 27 09:21:58 2004 UTC revision 1700 by persson, Sun Feb 17 12:40:59 2008 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
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                         *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   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 23  Line 24 
24  #include <sstream>  #include <sstream>
25  #include "DiskThread.h"  #include "DiskThread.h"
26  #include "Voice.h"  #include "Voice.h"
27    #include "EGADSR.h"
28    #include "../EngineFactory.h"
29    
30  #include "Engine.h"  #include "Engine.h"
31    
32    #include "../../common/global_private.h"
33    
34  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
35    
36      InstrumentResourceManager Engine::Instruments;      InstrumentResourceManager Engine::instruments;
37    
38        std::map<AudioOutputDevice*,Engine*> Engine::engines;
39    
40        /**
41         * Get a gig::Engine object for the given gig::EngineChannel and the
42         * given AudioOutputDevice. All engine channels which are connected to
43         * the same audio output device will use the same engine instance. This
44         * method will be called by a gig::EngineChannel whenever it's
45         * connecting to a audio output device.
46         *
47         * @param pChannel - engine channel which acquires an engine object
48         * @param pDevice  - the audio output device \a pChannel is connected to
49         */
50        Engine* Engine::AcquireEngine(LinuxSampler::gig::EngineChannel* pChannel, AudioOutputDevice* pDevice) {
51            Engine* pEngine = NULL;
52            // check if there's already an engine for the given audio output device
53            if (engines.count(pDevice)) {
54                dmsg(4,("Using existing gig::Engine.\n"));
55                pEngine = engines[pDevice];
56    
57                // Disable the engine while the new engine channel is
58                // added and initialized. The engine will be enabled again
59                // in EngineChannel::Connect.
60                pEngine->DisableAndLock();
61            } else { // create a new engine (and disk thread) instance for the given audio output device
62                dmsg(4,("Creating new gig::Engine.\n"));
63                pEngine = (Engine*) EngineFactory::Create("gig");
64                pEngine->Connect(pDevice);
65                engines[pDevice] = pEngine;
66            }
67            // register engine channel to the engine instance
68            pEngine->engineChannels.add(pChannel);
69            // remember index in the ArrayList
70            pChannel->iEngineIndexSelf = pEngine->engineChannels.size() - 1;
71            dmsg(4,("This gig::Engine has now %d EngineChannels.\n",pEngine->engineChannels.size()));
72            return pEngine;
73        }
74    
75        /**
76         * Once an engine channel is disconnected from an audio output device,
77         * it will immediately call this method to unregister itself from the
78         * engine instance and if that engine instance is not used by any other
79         * engine channel anymore, then that engine instance will be destroyed.
80         *
81         * @param pChannel - engine channel which wants to disconnect from it's
82         *                   engine instance
83         * @param pDevice  - audio output device \a pChannel was connected to
84         */
85        void Engine::FreeEngine(LinuxSampler::gig::EngineChannel* pChannel, AudioOutputDevice* pDevice) {
86            dmsg(4,("Disconnecting EngineChannel from gig::Engine.\n"));
87            Engine* pEngine = engines[pDevice];
88            // unregister EngineChannel from the Engine instance
89            pEngine->engineChannels.remove(pChannel);
90            // if the used Engine instance is not used anymore, then destroy it
91            if (pEngine->engineChannels.empty()) {
92                pDevice->Disconnect(pEngine);
93                engines.erase(pDevice);
94                delete pEngine;
95                dmsg(4,("Destroying gig::Engine.\n"));
96            }
97            else dmsg(4,("This gig::Engine has now %d EngineChannels.\n",pEngine->engineChannels.size()));
98        }
99    
100      Engine::Engine() {      /**
101          pRIFF              = NULL;       * Constructor
102          pGig               = NULL;       */
103          pInstrument        = NULL;      Engine::Engine() : SuspendedRegions(128) {
104          pAudioOutputDevice = NULL;          pAudioOutputDevice = NULL;
105          pDiskThread        = NULL;          pDiskThread        = NULL;
106          pEventGenerator    = NULL;          pEventGenerator    = NULL;
107          pEventQueue        = new RingBuffer<Event>(MAX_EVENTS_PER_FRAGMENT);          pSysexBuffer       = new RingBuffer<uint8_t,false>(CONFIG_SYSEX_BUFFER_SIZE, 0);
108          pEventPool         = new RTELMemoryPool<Event>(MAX_EVENTS_PER_FRAGMENT);          pEventQueue        = new RingBuffer<Event,false>(CONFIG_MAX_EVENTS_PER_FRAGMENT, 0);
109          pVoicePool         = new RTELMemoryPool<Voice>(MAX_AUDIO_VOICES);          pEventPool         = new Pool<Event>(CONFIG_MAX_EVENTS_PER_FRAGMENT);
110          pActiveKeys        = new RTELMemoryPool<uint>(128);          pVoicePool         = new Pool<Voice>(CONFIG_MAX_VOICES);
111          pEvents            = new RTEList<Event>(pEventPool);          pDimRegionPool[0]  = new Pool< ::gig::DimensionRegion*>(CONFIG_MAX_VOICES);
112          pCCEvents          = new RTEList<Event>(pEventPool);          pDimRegionPool[1]  = new Pool< ::gig::DimensionRegion*>(CONFIG_MAX_VOICES);
113          for (uint i = 0; i < Event::destination_count; i++) {          pVoiceStealingQueue = new RTList<Event>(pEventPool);
114              pSynthesisEvents[i] = new RTEList<Event>(pEventPool);          pGlobalEvents      = new RTList<Event>(pEventPool);
115          }  
116          for (uint i = 0; i < 128; i++) {          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
117              pMIDIKeyInfo[i].pActiveVoices = new RTEList<Voice>(pVoicePool);              iterVoice->SetEngine(this);
             pMIDIKeyInfo[i].KeyPressed    = false;  
             pMIDIKeyInfo[i].Active        = false;  
             pMIDIKeyInfo[i].pSelf         = NULL;  
             pMIDIKeyInfo[i].pEvents       = new RTEList<Event>(pEventPool);  
         }  
         for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) {  
             pVoice->SetEngine(this);  
118          }          }
119          pVoicePool->clear();          pVoicePool->clear();
120    
         pSynthesisParameters[0] = NULL; // we allocate when an audio device is connected  
   
121          ResetInternal();          ResetInternal();
122            ResetScaleTuning();
123            ResetSuspendedRegions();
124      }      }
125    
126        /**
127         * Destructor
128         */
129      Engine::~Engine() {      Engine::~Engine() {
130            MidiInputPort::RemoveSysexListener(this);
131          if (pDiskThread) {          if (pDiskThread) {
132                dmsg(1,("Stopping disk thread..."));
133              pDiskThread->StopThread();              pDiskThread->StopThread();
134              delete pDiskThread;              delete pDiskThread;
135                dmsg(1,("OK\n"));
136          }          }
         if (pGig)  delete pGig;  
         if (pRIFF) delete pRIFF;  
         for (uint i = 0; i < 128; i++) {  
             if (pMIDIKeyInfo[i].pActiveVoices) delete pMIDIKeyInfo[i].pActiveVoices;  
             if (pMIDIKeyInfo[i].pEvents)       delete pMIDIKeyInfo[i].pEvents;  
         }  
         for (uint i = 0; i < Event::destination_count; i++) {  
             if (pSynthesisEvents[i]) delete pSynthesisEvents[i];  
         }  
         delete[] pSynthesisEvents;  
         if (pEvents)     delete pEvents;  
         if (pCCEvents)   delete pCCEvents;  
137          if (pEventQueue) delete pEventQueue;          if (pEventQueue) delete pEventQueue;
138          if (pEventPool)  delete pEventPool;          if (pEventPool)  delete pEventPool;
139          if (pVoicePool)  delete pVoicePool;          if (pVoicePool) {
140          if (pActiveKeys) delete pActiveKeys;              pVoicePool->clear();
141                delete pVoicePool;
142            }
143          if (pEventGenerator) delete pEventGenerator;          if (pEventGenerator) delete pEventGenerator;
144          if (pSynthesisParameters[0]) delete[] pSynthesisParameters[0];          if (pVoiceStealingQueue) delete pVoiceStealingQueue;
145            if (pSysexBuffer) delete pSysexBuffer;
146            if (pGlobalEvents) delete pGlobalEvents;
147            if (pDimRegionPool[0]) delete pDimRegionPool[0];
148            if (pDimRegionPool[1]) delete pDimRegionPool[1];
149            ResetSuspendedRegions();
150            Unregister();
151      }      }
152    
153      void Engine::Enable() {      void Engine::Enable() {
154          dmsg(3,("gig::Engine: enabling\n"));          dmsg(3,("gig::Engine: enabling\n"));
155          EngineDisabled.PushAndUnlock(false, 2); // set condition object 'EngineDisabled' to false (wait max. 2s)          EngineDisabled.PushAndUnlock(false, 2); // set condition object 'EngineDisabled' to false (wait max. 2s)
156          dmsg(1,("gig::Engine: enabled (val=%d)\n", EngineDisabled.GetUnsafe()));          dmsg(3,("gig::Engine: enabled (val=%d)\n", EngineDisabled.GetUnsafe()));
157      }      }
158    
159        /**
160         * Temporarily stop the engine to not do anything. The engine will just be
161         * frozen during that time, that means after enabling it again it will
162         * continue where it was, with all its voices and playback state it had at
163         * the point of disabling. Notice that the engine's (audio) thread will
164         * continue to run, it just remains in an inactive loop during that time.
165         *
166         * If you need to be sure that all voices and disk streams are killed as
167         * well, use @c SuspendAll() instead.
168         *
169         * @see Enable(), SuspendAll()
170         */
171      void Engine::Disable() {      void Engine::Disable() {
172          dmsg(3,("gig::Engine: disabling\n"));          dmsg(3,("gig::Engine: disabling\n"));
173          bool* pWasDisabled = EngineDisabled.PushAndUnlock(true, 2); // wait max. 2s          bool* pWasDisabled = EngineDisabled.PushAndUnlock(true, 2); // wait max. 2s
# Line 107  namespace LinuxSampler { namespace gig { Line 181  namespace LinuxSampler { namespace gig {
181      }      }
182    
183      /**      /**
184       *  Reset all voices and disk thread and clear input event queue and all       * Similar to @c Disable() but this method additionally kills all voices
185       *  control and status variables.       * and disk streams and blocks until all voices and disk streams are actually
186         * killed / deleted.
187         *
188         * @e Note: only the original calling thread is able to re-enable the
189         * engine afterwards by calling @c ResumeAll() later on!
190       */       */
191      void Engine::Reset() {      void Engine::SuspendAll() {
192            dmsg(2,("gig::Engine: Suspending all ...\n"));
193            // stop the engine, so we can safely modify the engine's
194            // data structures from this foreign thread
195          DisableAndLock();          DisableAndLock();
196            // we could also use the respective class member variable here,
197            // but this is probably safer and cleaner
198            int iPendingStreamDeletions = 0;
199            // kill all voices on all engine channels the *die hard* way
200            for (int iChannel = 0; iChannel < engineChannels.size(); iChannel++) {
201                EngineChannel* pEngineChannel = engineChannels[iChannel];
202                RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
203                RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
204                for (; iuiKey != end; ++iuiKey) { // iterate through all active keys
205                    midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
206                    RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
207                    RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
208                    for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
209                        // request a notification from disk thread side for stream deletion
210                        const Stream::Handle hStream = itVoice->KillImmediately(true);
211                        if (hStream != Stream::INVALID_HANDLE) { // voice actually used a stream
212                            iPendingStreamDeletions++;
213                        }
214                    }
215                }
216            }
217            // wait until all streams were actually deleted by the disk thread
218            while (iPendingStreamDeletions) {
219                while (
220                    iPendingStreamDeletions &&
221                    pDiskThread->AskForDeletedStream() != Stream::INVALID_HANDLE
222                ) iPendingStreamDeletions--;
223                if (!iPendingStreamDeletions) break;
224                usleep(10000); // sleep for 10ms
225            }
226            dmsg(2,("gig::Engine: Everything suspended.\n"));
227        }
228    
229          //if (pAudioOutputDevice->IsPlaying()) { // if already running      /**
230              /*       * At the moment same as calling @c Enable() directly, but this might
231              // signal audio thread not to enter render part anymore       * change in future, so better call this method as counterpart to
232              SuspensionRequested = true;       * @c SuspendAll() instead of @c Enable() !
233              // sleep until wakened by audio thread       */
234              pthread_mutex_lock(&__render_state_mutex);      void Engine::ResumeAll() {
235              pthread_cond_wait(&__render_exit_condition, &__render_state_mutex);          Enable();
236              pthread_mutex_unlock(&__render_state_mutex);      }
             */  
         //}  
237    
238          //if (wasplaying) pAudioOutputDevice->Stop();      /**
239         * Order the engine to stop rendering audio for the given region.
240         * Additionally this method will block until all voices and their disk
241         * streams associated with that region are actually killed / deleted, so
242         * one can i.e. safely modify the region with an instrument editor after
243         * returning from this method.
244         *
245         * @param pRegion - region the engine shall stop using
246         */
247        void Engine::Suspend(::gig::Region* pRegion) {
248            dmsg(2,("gig::Engine: Suspending Region %x ...\n",pRegion));
249            SuspendedRegionsMutex.Lock();
250            SuspensionChangeOngoing.Set(true);
251            pPendingRegionSuspension = pRegion;
252            SuspensionChangeOngoing.WaitAndUnlockIf(true);
253            SuspendedRegionsMutex.Unlock();
254            dmsg(2,("gig::Engine: Region %x suspended.",pRegion));
255        }
256    
257          ResetInternal();      /**
258         * Orders the engine to resume playing back the given region, previously
259         * suspended with @c Suspend() .
260         *
261         * @param pRegion - region the engine shall be allowed to use again
262         */
263        void Engine::Resume(::gig::Region* pRegion) {
264            dmsg(2,("gig::Engine: Resuming Region %x ...\n",pRegion));
265            SuspendedRegionsMutex.Lock();
266            SuspensionChangeOngoing.Set(true);
267            pPendingRegionResumption = pRegion;
268            SuspensionChangeOngoing.WaitAndUnlockIf(true);
269            SuspendedRegionsMutex.Unlock();
270            dmsg(2,("gig::Engine: Region %x resumed.\n",pRegion));
271        }
272    
273          // signal audio thread to continue with rendering      /**
274          //SuspensionRequested = false;       *  Reset all voices and disk thread and clear input event queue and all
275         *  control and status variables.
276         */
277        void Engine::Reset() {
278            DisableAndLock();
279            ResetInternal();
280            ResetScaleTuning();
281          Enable();          Enable();
282      }      }
283    
284      /**      /**
285       *  Reset all voices and disk thread and clear input event queue and all       *  Reset all voices and disk thread and clear input event queue and all
286       *  control and status variables. This method is not thread safe!       *  control and status variables. This method is protected by a mutex.
287       */       */
288      void Engine::ResetInternal() {      void Engine::ResetInternal() {
289          Pitch               = 0;          ResetInternalMutex.Lock();
290          SustainPedal        = false;  
291            // make sure that the engine does not get any sysex messages
292            // while it's reseting
293            bool sysexDisabled = MidiInputPort::RemoveSysexListener(this);
294          ActiveVoiceCount    = 0;          ActiveVoiceCount    = 0;
295          ActiveVoiceCountMax = 0;          ActiveVoiceCountMax = 0;
296    
297          // set all MIDI controller values to zero          // reset voice stealing parameters
298          memset(ControllerTable, 0x00, 128);          pVoiceStealingQueue->clear();
299            itLastStolenVoice          = RTList<Voice>::Iterator();
300          // reset key info          itLastStolenVoiceGlobally  = RTList<Voice>::Iterator();
301          for (uint i = 0; i < 128; i++) {          iuiLastStolenKey           = RTList<uint>::Iterator();
302              pMIDIKeyInfo[i].pActiveVoices->clear();          iuiLastStolenKeyGlobally   = RTList<uint>::Iterator();
303              pMIDIKeyInfo[i].pEvents->clear();          pLastStolenChannel         = NULL;
             pMIDIKeyInfo[i].KeyPressed = false;  
             pMIDIKeyInfo[i].Active     = false;  
             pMIDIKeyInfo[i].pSelf      = NULL;  
         }  
304    
305          // reset all voices          // reset all voices
306          for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) {          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
307              pVoice->Reset();              iterVoice->Reset();
308          }          }
309          pVoicePool->clear();          pVoicePool->clear();
310    
         // free all active keys  
         pActiveKeys->clear();  
   
311          // reset disk thread          // reset disk thread
312          if (pDiskThread) pDiskThread->Reset();          if (pDiskThread) pDiskThread->Reset();
313    
314          // delete all input events          // delete all input events
315          pEventQueue->init();          pEventQueue->init();
316            pSysexBuffer->init();
317            if (sysexDisabled) MidiInputPort::AddSysexListener(this);
318            ResetInternalMutex.Unlock();
319      }      }
320    
321      /**      /**
322       *  Load an instrument from a .gig file.       * Reset to normal, chromatic scale (means equal tempered).
      *  
      *  @param FileName   - file name of the Gigasampler instrument file  
      *  @param Instrument - index of the instrument in the .gig file  
      *  @throws LinuxSamplerException  on error  
      *  @returns          detailed description of the method call result  
323       */       */
324      void Engine::LoadInstrument(const char* FileName, uint Instrument) {      void Engine::ResetScaleTuning() {
325            memset(&ScaleTuning[0], 0x00, 12);
         DisableAndLock();  
   
         ResetInternal(); // reset engine  
   
         // free old instrument  
         if (pInstrument) {  
             // give old instrument back to instrument manager  
             Instruments.HandBack(pInstrument, this);  
         }  
   
         // request gig instrument from instrument manager  
         try {  
             instrument_id_t instrid;  
             instrid.FileName    = FileName;  
             instrid.iInstrument = Instrument;  
             pInstrument = Instruments.Borrow(instrid, this);  
             if (!pInstrument) {  
                 dmsg(1,("no instrument loaded!!!\n"));  
                 exit(EXIT_FAILURE);  
             }  
         }  
         catch (RIFF::Exception e) {  
             String msg = "gig::Engine error: Failed to load instrument, cause: " + e.Message;  
             throw LinuxSamplerException(msg);  
         }  
         catch (InstrumentResourceManagerException e) {  
             String msg = "gig::Engine error: Failed to load instrument, cause: " + e.Message();  
             throw LinuxSamplerException(msg);  
         }  
         catch (...) {  
             throw LinuxSamplerException("gig::Engine error: Failed to load instrument, cause: Unknown exception while trying to parse gig file.");  
         }  
   
         // inform audio driver for the need of two channels  
         try {  
             if (pAudioOutputDevice) pAudioOutputDevice->AcquireChannels(2); // gig Engine only stereo  
         }  
         catch (AudioOutputException e) {  
             String msg = "Audio output device unable to provide 2 audio channels, cause: " + e.Message();  
             throw LinuxSamplerException(msg);  
         }  
   
         Enable();  
326      }      }
327    
328      /**      void Engine::ResetSuspendedRegions() {
329       * Will be called by the InstrumentResourceManager when the instrument          SuspendedRegions.clear();
330       * we are currently using in this engine is going to be updated, so we          iPendingStreamDeletions = 0;
331       * can stop playback before that happens.          pPendingRegionSuspension = pPendingRegionResumption = NULL;
332       */          SuspensionChangeOngoing.Set(false);
     void Engine::ResourceToBeUpdated(::gig::Instrument* pResource, void*& pUpdateArg) {  
         dmsg(3,("gig::Engine: Received instrument update message.\n"));  
         DisableAndLock();  
         ResetInternal();  
         this->pInstrument = NULL;  
333      }      }
334    
335      /**      /**
336       * Will be called by the InstrumentResourceManager when the instrument       * Connect this engine instance with the given audio output device.
337       * update process was completed, so we can continue with playback.       * This method will be called when an Engine instance is created.
338         * All of the engine's data structures which are dependant to the used
339         * audio output device / driver will be (re)allocated and / or
340         * adjusted appropriately.
341         *
342         * @param pAudioOut - audio output device to connect to
343       */       */
     void Engine::ResourceUpdated(::gig::Instrument* pOldResource, ::gig::Instrument* pNewResource, void* pUpdateArg) {  
         this->pInstrument = pNewResource;  
         Enable();  
     }  
   
344      void Engine::Connect(AudioOutputDevice* pAudioOut) {      void Engine::Connect(AudioOutputDevice* pAudioOut) {
345          pAudioOutputDevice = pAudioOut;          pAudioOutputDevice = pAudioOut;
346    
# Line 258  namespace LinuxSampler { namespace gig { Line 352  namespace LinuxSampler { namespace gig {
352          }          }
353          catch (AudioOutputException e) {          catch (AudioOutputException e) {
354              String msg = "Audio output device unable to provide 2 audio channels, cause: " + e.Message();              String msg = "Audio output device unable to provide 2 audio channels, cause: " + e.Message();
355              throw LinuxSamplerException(msg);              throw Exception(msg);
356            }
357    
358            this->MaxSamplesPerCycle = pAudioOutputDevice->MaxSamplesPerCycle();
359            this->SampleRate         = pAudioOutputDevice->SampleRate();
360    
361            // FIXME: audio drivers with varying fragment sizes might be a problem here
362            MaxFadeOutPos = MaxSamplesPerCycle - int(double(SampleRate) * CONFIG_EG_MIN_RELEASE_TIME) - 1;
363            if (MaxFadeOutPos < 0) {
364                std::cerr << "gig::Engine: WARNING, CONFIG_EG_MIN_RELEASE_TIME "
365                          << "too big for current audio fragment size & sampling rate! "
366                          << "May lead to click sounds if voice stealing chimes in!\n" << std::flush;
367                // force volume ramp downs at the beginning of each fragment
368                MaxFadeOutPos = 0;
369                // lower minimum release time
370                const float minReleaseTime = (float) MaxSamplesPerCycle / (float) SampleRate;
371                for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
372                    iterVoice->EG1.CalculateFadeOutCoeff(minReleaseTime, SampleRate);
373                }
374                pVoicePool->clear();
375          }          }
376    
377          // (re)create disk thread          // (re)create disk thread
378          if (this->pDiskThread) {          if (this->pDiskThread) {
379                dmsg(1,("Stopping disk thread..."));
380              this->pDiskThread->StopThread();              this->pDiskThread->StopThread();
381              delete this->pDiskThread;              delete this->pDiskThread;
382                dmsg(1,("OK\n"));
383          }          }
384          this->pDiskThread = new DiskThread(((pAudioOut->MaxSamplesPerCycle() << MAX_PITCH) << 1) + 6); //FIXME: assuming stereo          this->pDiskThread = new DiskThread(((pAudioOut->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6, //FIXME: assuming stereo
385                                               &instruments);
386          if (!pDiskThread) {          if (!pDiskThread) {
387              dmsg(0,("gig::Engine  new diskthread = NULL\n"));              dmsg(0,("gig::Engine  new diskthread = NULL\n"));
388              exit(EXIT_FAILURE);              exit(EXIT_FAILURE);
389          }          }
390    
391          for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) {          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
392              pVoice->pDiskThread = this->pDiskThread;              iterVoice->pDiskThread = this->pDiskThread;
             pVoice->SetOutput(pAudioOut);  
393              dmsg(3,("d"));              dmsg(3,("d"));
394          }          }
395          pVoicePool->clear();          pVoicePool->clear();
# Line 283  namespace LinuxSampler { namespace gig { Line 398  namespace LinuxSampler { namespace gig {
398          if (pEventGenerator) delete pEventGenerator;          if (pEventGenerator) delete pEventGenerator;
399          pEventGenerator = new EventGenerator(pAudioOut->SampleRate());          pEventGenerator = new EventGenerator(pAudioOut->SampleRate());
400    
         // (re)allocate synthesis parameter matrix  
         if (pSynthesisParameters[0]) delete[] pSynthesisParameters[0];  
         pSynthesisParameters[0] = new float[Event::destination_count * pAudioOut->MaxSamplesPerCycle()];  
         for (int dst = 1; dst < Event::destination_count; dst++)  
             pSynthesisParameters[dst] = pSynthesisParameters[dst - 1] + pAudioOut->MaxSamplesPerCycle();  
   
401          dmsg(1,("Starting disk thread..."));          dmsg(1,("Starting disk thread..."));
402          pDiskThread->StartThread();          pDiskThread->StartThread();
403          dmsg(1,("OK\n"));          dmsg(1,("OK\n"));
404    
405          for (Voice* pVoice = pVoicePool->first(); pVoice; pVoice = pVoicePool->next()) {          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
406              if (!pVoice->pDiskThread) {              if (!iterVoice->pDiskThread) {
407                  dmsg(0,("Engine -> voice::trigger: !pDiskThread\n"));                  dmsg(0,("Engine -> voice::trigger: !pDiskThread\n"));
408                  exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
409              }              }
410          }          }
411      }      }
412    
413      void Engine::DisconnectAudioOutputDevice() {      /**
414          if (pAudioOutputDevice) { // if clause to prevent disconnect loops       * Called by the engine's (audio) thread once per cycle to process requests
415              AudioOutputDevice* olddevice = pAudioOutputDevice;       * from the outer world to suspend or resume a given @c gig::Region .
416              pAudioOutputDevice = NULL;       */
417              olddevice->Disconnect(this);      void Engine::ProcessSuspensionsChanges() {
418            // process request for suspending one region
419            if (pPendingRegionSuspension) {
420                // kill all voices on all engine channels that use this region
421                for (int iChannel = 0; iChannel < engineChannels.size(); iChannel++) {
422                    EngineChannel* pEngineChannel = engineChannels[iChannel];
423                    RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
424                    RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
425                    for (; iuiKey != end; ++iuiKey) { // iterate through all active keys
426                        midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
427                        RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
428                        // if current key is not associated with this region, skip this key
429                        if (itVoice->pDimRgn->GetParent() != pPendingRegionSuspension) continue;
430                        RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
431                        for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
432                            // request a notification from disk thread side for stream deletion
433                            const Stream::Handle hStream = itVoice->KillImmediately(true);
434                            if (hStream != Stream::INVALID_HANDLE) { // voice actually used a stream
435                                iPendingStreamDeletions++;
436                            }
437                        }
438                    }
439                }
440                // make sure the region is not yet on the list
441                bool bAlreadySuspended = false;
442                RTList< ::gig::Region*>::Iterator iter = SuspendedRegions.first();
443                RTList< ::gig::Region*>::Iterator end  = SuspendedRegions.end();
444                for (; iter != end; ++iter) { // iterate through all suspended regions
445                    if (*iter == pPendingRegionSuspension) { // found
446                        bAlreadySuspended = true;
447                        dmsg(1,("gig::Engine: attempt to suspend an already suspended region !!!\n"));
448                        break;
449                    }
450                }
451                if (!bAlreadySuspended) {
452                    // put the region on the list of suspended regions
453                    RTList< ::gig::Region*>::Iterator iter = SuspendedRegions.allocAppend();
454                    if (iter) {
455                        *iter = pPendingRegionSuspension;
456                    } else std::cerr << "gig::Engine: Could not suspend Region, list is full. This is a bug!!!\n" << std::flush;
457                }
458                // free request slot for next caller (and to make sure that
459                // we're not going to process the same request in the next cycle)
460                pPendingRegionSuspension = NULL;
461                // if no disk stream deletions are pending, awaken other side, as
462                // we're done in this case
463                if (!iPendingStreamDeletions) SuspensionChangeOngoing.Set(false);
464            }
465    
466            // process request for resuming one region
467            if (pPendingRegionResumption) {
468                // remove region from the list of suspended regions
469                RTList< ::gig::Region*>::Iterator iter = SuspendedRegions.first();
470                RTList< ::gig::Region*>::Iterator end  = SuspendedRegions.end();
471                for (; iter != end; ++iter) { // iterate through all suspended regions
472                    if (*iter == pPendingRegionResumption) { // found
473                        SuspendedRegions.free(iter);
474                        break; // done
475                    }
476                }
477                // free request slot for next caller
478                pPendingRegionResumption = NULL;
479                // awake other side as we're done
480                SuspensionChangeOngoing.Set(false);
481            }
482        }
483    
484        /**
485         * Called by the engine's (audio) thread once per cycle to check if
486         * streams of voices that were killed due to suspension request have
487         * finally really been deleted by the disk thread.
488         */
489        void Engine::ProcessPendingStreamDeletions() {
490            if (!iPendingStreamDeletions) return;
491            //TODO: or shall we better store a list with stream handles instead of a scalar amount of streams to be deleted? might be safer
492            while (
493                iPendingStreamDeletions &&
494                pDiskThread->AskForDeletedStream() != Stream::INVALID_HANDLE
495            ) iPendingStreamDeletions--;
496            // just for safety ...
497            while (pDiskThread->AskForDeletedStream() != Stream::INVALID_HANDLE);
498            // now that all disk streams are deleted, awake other side as
499            // we're finally done with suspending the requested region
500            if (!iPendingStreamDeletions) SuspensionChangeOngoing.Set(false);
501        }
502    
503        /**
504         * Returns @c true if the given region is currently set to be suspended
505         * from being used, @c false otherwise.
506         */
507        bool Engine::RegionSuspended(::gig::Region* pRegion) {
508            if (SuspendedRegions.isEmpty()) return false;
509            //TODO: or shall we use a sorted container instead of the RTList? might be faster ... or trivial ;-)
510            RTList< ::gig::Region*>::Iterator iter = SuspendedRegions.first();
511            RTList< ::gig::Region*>::Iterator end  = SuspendedRegions.end();
512            for (; iter != end; ++iter)  // iterate through all suspended regions
513                if (*iter == pRegion) return true;
514            return false;
515        }
516    
517        /**
518         * Clear all engine global event lists.
519         */
520        void Engine::ClearEventLists() {
521            pGlobalEvents->clear();
522        }
523    
524        /**
525         * Copy all events from the engine's global input queue buffer to the
526         * engine's internal event list. This will be done at the beginning of
527         * each audio cycle (that is each RenderAudio() call) to distinguish
528         * all global events which have to be processed in the current audio
529         * cycle. These events are usually just SysEx messages. Every
530         * EngineChannel has it's own input event queue buffer and event list
531         * to handle common events like NoteOn, NoteOff and ControlChange
532         * events.
533         *
534         * @param Samples - number of sample points to be processed in the
535         *                  current audio cycle
536         */
537        void Engine::ImportEvents(uint Samples) {
538            RingBuffer<Event,false>::NonVolatileReader eventQueueReader = pEventQueue->get_non_volatile_reader();
539            Event* pEvent;
540            while (true) {
541                // get next event from input event queue
542                if (!(pEvent = eventQueueReader.pop())) break;
543                // if younger event reached, ignore that and all subsequent ones for now
544                if (pEvent->FragmentPos() >= Samples) {
545                    eventQueueReader--;
546                    dmsg(2,("Younger Event, pos=%d ,Samples=%d!\n",pEvent->FragmentPos(),Samples));
547                    pEvent->ResetFragmentPos();
548                    break;
549                }
550                // copy event to internal event list
551                if (pGlobalEvents->poolIsEmpty()) {
552                    dmsg(1,("Event pool emtpy!\n"));
553                    break;
554                }
555                *pGlobalEvents->allocAppend() = *pEvent;
556          }          }
557            eventQueueReader.free(); // free all copied events from input queue
558      }      }
559    
560      /**      /**
561       *  Let this engine proceed to render the given amount of sample points. The       * Let this engine proceed to render the given amount of sample points.
562       *  calculated audio data of all voices of this engine will be placed into       * The engine will iterate through all engine channels and render audio
563       *  the engine's audio sum buffer which has to be copied and eventually be       * for each engine channel independently. The calculated audio data of
564       *  converted to the appropriate value range by the audio output class (e.g.       * all voices of each engine channel will be placed into the audio sum
565       *  AlsaIO or JackIO) right after.       * buffers of the respective audio output device, connected to the
566         * respective engine channel.
567       *       *
568       *  @param Samples - number of sample points to be rendered       *  @param Samples - number of sample points to be rendered
569       *  @returns       0 on success       *  @returns       0 on success
570       */       */
571      int Engine::RenderAudio(uint Samples) {      int Engine::RenderAudio(uint Samples) {
572          dmsg(5,("RenderAudio(Samples=%d)\n", Samples));          dmsg(8,("RenderAudio(Samples=%d)\n", Samples));
573    
574          // return if no instrument loaded or engine disabled          // return if engine disabled
575          if (EngineDisabled.Pop()) {          if (EngineDisabled.Pop()) {
576              dmsg(5,("gig::Engine: engine disabled (val=%d)\n",EngineDisabled.GetUnsafe()));              dmsg(5,("gig::Engine: engine disabled (val=%d)\n",EngineDisabled.GetUnsafe()));
577              return 0;              return 0;
578          }          }
579          if (!pInstrument) {  
580              dmsg(5,("gig::Engine: no instrument loaded\n"));          // process requests for suspending / resuming regions (i.e. to avoid
581              return 0;          // crashes while these regions are modified by an instrument editor)
582            ProcessSuspensionsChanges();
583    
584            // update time of start and end of this audio fragment (as events' time stamps relate to this)
585            pEventGenerator->UpdateFragmentTime(Samples);
586    
587            // We only allow a maximum of CONFIG_MAX_VOICES voices to be spawned
588            // in each audio fragment. All subsequent request for spawning new
589            // voices in the same audio fragment will be ignored.
590            VoiceSpawnsLeft = CONFIG_MAX_VOICES;
591    
592            // get all events from the engine's global input event queue which belong to the current fragment
593            // (these are usually just SysEx messages)
594            ImportEvents(Samples);
595    
596            // process engine global events (these are currently only MIDI System Exclusive messages)
597            {
598                RTList<Event>::Iterator itEvent = pGlobalEvents->first();
599                RTList<Event>::Iterator end     = pGlobalEvents->end();
600                for (; itEvent != end; ++itEvent) {
601                    switch (itEvent->Type) {
602                        case Event::type_sysex:
603                            dmsg(5,("Engine: Sysex received\n"));
604                            ProcessSysex(itEvent);
605                            break;
606                    }
607                }
608          }          }
609    
610            // reset internal voice counter (just for statistic of active voices)
611            ActiveVoiceCountTemp = 0;
612    
613          // empty the event lists for the new fragment          // handle instrument change commands
614          pEvents->clear();          bool instrumentChanged = false;
615          pCCEvents->clear();          for (int i = 0; i < engineChannels.size(); i++) {
616          for (uint i = 0; i < Event::destination_count; i++) {              EngineChannel* pEngineChannel = engineChannels[i];
617              pSynthesisEvents[i]->clear();  
618                // as we're going to (carefully) write some status to the
619                // synchronized struct, we cast away the const
620                EngineChannel::instrument_change_command_t& cmd =
621                    const_cast<EngineChannel::instrument_change_command_t&>(pEngineChannel->InstrumentChangeCommandReader.Lock());
622    
623                pEngineChannel->pDimRegionsInUse = cmd.pDimRegionsInUse;
624                pEngineChannel->pDimRegionsInUse->clear();
625    
626                if (cmd.bChangeInstrument) {
627                    // change instrument
628                    dmsg(5,("Engine: instrument change command received\n"));
629                    cmd.bChangeInstrument = false;
630                    pEngineChannel->pInstrument = cmd.pInstrument;
631                    instrumentChanged = true;
632    
633                    // Iterate through all active voices and mark them as
634                    // "orphans", which means that the dimension regions
635                    // and samples they use should be released to the
636                    // instrument resource manager when the voices die.
637                    int i = 0;
638                    RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
639                    RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
640                    while (iuiKey != end) { // iterate through all active keys
641                        midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
642                        ++iuiKey;
643    
644                        RTList<Voice>::Iterator itVoice     = pKey->pActiveVoices->first();
645                        RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
646                        for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
647                            itVoice->Orphan = true;
648                        }
649                    }
650                }
651            }
652            if (instrumentChanged) {
653                //TODO: this is a lazy solution ATM and not safe in case somebody is currently editing the instrument we're currently switching to (we should store all suspended regions on instrument manager side and when switching to another instrument copy that list to the engine's local list of suspensions
654                ResetSuspendedRegions();
655          }          }
656    
657          // read and copy events from input queue          // handle events on all engine channels
658          Event event = pEventGenerator->CreateEvent();          for (int i = 0; i < engineChannels.size(); i++) {
659          while (true) {              ProcessEvents(engineChannels[i], Samples);
             if (!pEventQueue->pop(&event)) break;  
             pEvents->alloc_assign(event);  
660          }          }
661    
662            // render all 'normal', active voices on all engine channels
663            for (int i = 0; i < engineChannels.size(); i++) {
664                RenderActiveVoices(engineChannels[i], Samples);
665            }
666    
667          // update time of start and end of this audio fragment (as events' time stamps relate to this)          // now that all ordinary voices on ALL engine channels are rendered, render new stolen voices
668          pEventGenerator->UpdateFragmentTime(Samples);          RenderStolenVoices(Samples);
669    
670            // handle audio routing for engine channels with FX sends
671            for (int i = 0; i < engineChannels.size(); i++) {
672                if (engineChannels[i]->fxSends.empty()) continue; // ignore if no FX sends
673                RouteAudio(engineChannels[i], Samples);
674            }
675    
676          // process events          // handle cleanup on all engine channels for the next audio fragment
677          Event* pNextEvent = pEvents->first();          for (int i = 0; i < engineChannels.size(); i++) {
678          while (pNextEvent) {              PostProcess(engineChannels[i]);
             Event* pEvent = pNextEvent;  
             pEvents->set_current(pEvent);  
             pNextEvent = pEvents->next();  
             switch (pEvent->Type) {  
                 case Event::type_note_on:  
                     dmsg(5,("Audio Thread: Note on received\n"));  
                     ProcessNoteOn(pEvent);  
                     break;  
                 case Event::type_note_off:  
                     dmsg(5,("Audio Thread: Note off received\n"));  
                     ProcessNoteOff(pEvent);  
                     break;  
                 case Event::type_control_change:  
                     dmsg(5,("Audio Thread: MIDI CC received\n"));  
                     ProcessControlChange(pEvent);  
                     break;  
                 case Event::type_pitchbend:  
                     dmsg(5,("Audio Thread: Pitchbend received\n"));  
                     ProcessPitchbend(pEvent);  
                     break;  
             }  
679          }          }
680    
681    
682          // render audio from all active voices          // empty the engine's event list for the next audio fragment
683          int active_voices = 0;          ClearEventLists();
         uint* piKey = pActiveKeys->first();  
         while (piKey) { // iterate through all active keys  
             midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];  
             pActiveKeys->set_current(piKey);  
             piKey = pActiveKeys->next();  
   
             Voice* pVoiceNext = pKey->pActiveVoices->first();  
             while (pVoiceNext) { // iterate through all voices on this key  
                 // already get next voice on key  
                 Voice* pVoice = pVoiceNext;  
                 pKey->pActiveVoices->set_current(pVoice);  
                 pVoiceNext = pKey->pActiveVoices->next();  
684    
685                  // now render current voice          // reset voice stealing for the next audio fragment
686                  pVoice->Render(Samples);          pVoiceStealingQueue->clear();
687                  if (pVoice->IsActive()) active_voices++; // still active  
688                  else { // voice reached end, is now inactive          // just some statistics about this engine instance
689                      KillVoice(pVoice); // remove voice from the list of active voices          ActiveVoiceCount = ActiveVoiceCountTemp;
690            if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;
691    
692            // in case regions were previously suspended and we killed voices
693            // with disk streams due to that, check if those streams have finally
694            // been deleted by the disk thread
695            if (iPendingStreamDeletions) ProcessPendingStreamDeletions();
696    
697            for (int i = 0; i < engineChannels.size(); i++) {
698                engineChannels[i]->InstrumentChangeCommandReader.Unlock();
699            }
700            FrameTime += Samples;
701    
702            return 0;
703        }
704    
705        /**
706         * Dispatch and handle all events in this audio fragment for the given
707         * engine channel.
708         *
709         * @param pEngineChannel - engine channel on which events should be
710         *                         processed
711         * @param Samples        - amount of sample points to be processed in
712         *                         this audio fragment cycle
713         */
714        void Engine::ProcessEvents(EngineChannel* pEngineChannel, uint Samples) {
715            // get all events from the engine channels's input event queue which belong to the current fragment
716            // (these are the common events like NoteOn, NoteOff, ControlChange, etc.)
717            pEngineChannel->ImportEvents(Samples);
718    
719            // process events
720            {
721                RTList<Event>::Iterator itEvent = pEngineChannel->pEvents->first();
722                RTList<Event>::Iterator end     = pEngineChannel->pEvents->end();
723                for (; itEvent != end; ++itEvent) {
724                    switch (itEvent->Type) {
725                        case Event::type_note_on:
726                            dmsg(5,("Engine: Note on received\n"));
727                            ProcessNoteOn((EngineChannel*)itEvent->pEngineChannel, itEvent);
728                            break;
729                        case Event::type_note_off:
730                            dmsg(5,("Engine: Note off received\n"));
731                            ProcessNoteOff((EngineChannel*)itEvent->pEngineChannel, itEvent);
732                            break;
733                        case Event::type_control_change:
734                            dmsg(5,("Engine: MIDI CC received\n"));
735                            ProcessControlChange((EngineChannel*)itEvent->pEngineChannel, itEvent);
736                            break;
737                        case Event::type_pitchbend:
738                            dmsg(5,("Engine: Pitchbend received\n"));
739                            ProcessPitchbend((EngineChannel*)itEvent->pEngineChannel, itEvent);
740                            break;
741                  }                  }
742              }              }
             pKey->pEvents->clear(); // free all events on the key  
743          }          }
744    
745            // reset voice stealing for the next engine channel (or next audio fragment)
746            itLastStolenVoice         = RTList<Voice>::Iterator();
747            itLastStolenVoiceGlobally = RTList<Voice>::Iterator();
748            iuiLastStolenKey          = RTList<uint>::Iterator();
749            iuiLastStolenKeyGlobally  = RTList<uint>::Iterator();
750            pLastStolenChannel        = NULL;
751        }
752    
753          // write that to the disk thread class so that it can print it      /**
754          // on the console for debugging purposes       * Render all 'normal' voices (that is voices which were not stolen in
755          ActiveVoiceCount = active_voices;       * this fragment) on the given engine channel.
756          if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;       *
757         * @param pEngineChannel - engine channel on which audio should be
758         *                         rendered
759         * @param Samples        - amount of sample points to be rendered in
760         *                         this audio fragment cycle
761         */
762        void Engine::RenderActiveVoices(EngineChannel* pEngineChannel, uint Samples) {
763            #if !CONFIG_PROCESS_MUTED_CHANNELS
764            if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
765            #endif
766    
767            uint voiceCount = 0;
768            uint streamCount = 0;
769            RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
770            RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
771            while (iuiKey != end) { // iterate through all active keys
772                midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
773                ++iuiKey;
774    
775                RTList<Voice>::Iterator itVoice     = pKey->pActiveVoices->first();
776                RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
777                for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
778                    // now render current voice
779                    itVoice->Render(Samples);
780                    if (itVoice->IsActive()) { // still active
781                        if (!itVoice->Orphan) {
782                            *(pEngineChannel->pDimRegionsInUse->allocAppend()) = itVoice->pDimRgn;
783                        }
784                        ActiveVoiceCountTemp++;
785                        voiceCount++;
786    
787                        if (itVoice->PlaybackState == Voice::playback_state_disk) {
788                            if ((itVoice->DiskStreamRef).State == Stream::state_active) streamCount++;
789                        }
790                    }  else { // voice reached end, is now inactive
791                        FreeVoice(pEngineChannel, itVoice); // remove voice from the list of active voices
792                    }
793                }
794            }
795    
796          return 0;          pEngineChannel->SetVoiceCount(voiceCount);
797            pEngineChannel->SetDiskStreamCount(streamCount);
798      }      }
799    
800      /**      /**
801       *  Will be called by the MIDIIn Thread to let the audio thread trigger a new       * Render all stolen voices (only voices which were stolen in this
802       *  voice for the given key.       * fragment) on the given engine channel. Stolen voices are rendered
803         * after all normal voices have been rendered; this is needed to render
804         * audio of those voices which were selected for voice stealing until
805         * the point were the stealing (that is the take over of the voice)
806         * actually happened.
807       *       *
808       *  @param Key      - MIDI key number of the triggered key       * @param pEngineChannel - engine channel on which audio should be
809       *  @param Velocity - MIDI velocity value of the triggered key       *                         rendered
810         * @param Samples        - amount of sample points to be rendered in
811         *                         this audio fragment cycle
812       */       */
813      void Engine::SendNoteOn(uint8_t Key, uint8_t Velocity) {      void Engine::RenderStolenVoices(uint Samples) {
814          Event event    = pEventGenerator->CreateEvent();          RTList<Event>::Iterator itVoiceStealEvent = pVoiceStealingQueue->first();
815          event.Type     = Event::type_note_on;          RTList<Event>::Iterator end               = pVoiceStealingQueue->end();
816          event.Key      = Key;          for (; itVoiceStealEvent != end; ++itVoiceStealEvent) {
817          event.Velocity = Velocity;              EngineChannel* pEngineChannel = (EngineChannel*) itVoiceStealEvent->pEngineChannel;
818          if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (!pEngineChannel->pInstrument) continue; // ignore if no instrument loaded
819          else dmsg(1,("Engine: Input event queue full!"));              Pool<Voice>::Iterator itNewVoice =
820                    LaunchVoice(pEngineChannel, itVoiceStealEvent, itVoiceStealEvent->Param.Note.Layer, itVoiceStealEvent->Param.Note.ReleaseTrigger, false, false);
821                if (itNewVoice) {
822                    itNewVoice->Render(Samples);
823                    if (itNewVoice->IsActive()) { // still active
824                        *(pEngineChannel->pDimRegionsInUse->allocAppend()) = itNewVoice->pDimRgn;
825                        ActiveVoiceCountTemp++;
826                        pEngineChannel->SetVoiceCount(pEngineChannel->GetVoiceCount() + 1);
827    
828                        if (itNewVoice->PlaybackState == Voice::playback_state_disk) {
829                            if (itNewVoice->DiskStreamRef.State == Stream::state_active) {
830                                pEngineChannel->SetDiskStreamCount(pEngineChannel->GetDiskStreamCount() + 1);
831                            }
832                        }
833                    } else { // voice reached end, is now inactive
834                        FreeVoice(pEngineChannel, itNewVoice); // remove voice from the list of active voices
835                    }
836                }
837                else dmsg(1,("gig::Engine: ERROR, voice stealing didn't work out!\n"));
838    
839                // we need to clear the key's event list explicitly here in case key was never active
840                midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoiceStealEvent->Param.Note.Key];
841                pKey->VoiceTheftsQueued--;
842                if (!pKey->Active && !pKey->VoiceTheftsQueued) pKey->pEvents->clear();
843            }
844      }      }
845    
846      /**      /**
847       *  Will be called by the MIDIIn Thread to signal the audio thread to release       * Will be called in case the respective engine channel sports FX send
848       *  voice(s) on the given key.       * channels. In this particular case, engine channel local buffers are
849         * used to render and mix all voices to. This method is responsible for
850         * copying the audio data from those local buffers to the master audio
851         * output channels as well as to the FX send audio output channels with
852         * their respective FX send levels.
853       *       *
854       *  @param Key      - MIDI key number of the released key       * @param pEngineChannel - engine channel from which audio should be
855       *  @param Velocity - MIDI release velocity value of the released key       *                         routed
856         * @param Samples        - amount of sample points to be routed in
857         *                         this audio fragment cycle
858       */       */
859      void Engine::SendNoteOff(uint8_t Key, uint8_t Velocity) {      void Engine::RouteAudio(EngineChannel* pEngineChannel, uint Samples) {
860          Event event    = pEventGenerator->CreateEvent();          // route master signal
861          event.Type     = Event::type_note_off;          {
862          event.Key      = Key;              AudioChannel* pDstL = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelLeft);
863          event.Velocity = Velocity;              AudioChannel* pDstR = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelRight);
864          if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              pEngineChannel->pChannelLeft->MixTo(pDstL, Samples);
865          else dmsg(1,("Engine: Input event queue full!"));              pEngineChannel->pChannelRight->MixTo(pDstR, Samples);
866            }
867            // route FX send signal
868            {
869                for (int iFxSend = 0; iFxSend < pEngineChannel->GetFxSendCount(); iFxSend++) {
870                    FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
871                    // left channel
872                    const int iDstL = pFxSend->DestinationChannel(0);
873                    if (iDstL < 0) {
874                        dmsg(1,("Engine::RouteAudio() Error: invalid FX send (L) destination channel"));
875                    } else {
876                        AudioChannel* pDstL = pAudioOutputDevice->Channel(iDstL);
877                        if (!pDstL) {
878                            dmsg(1,("Engine::RouteAudio() Error: invalid FX send (L) destination channel"));
879                        } else pEngineChannel->pChannelLeft->MixTo(pDstL, Samples, pFxSend->Level());
880                    }
881                    // right channel
882                    const int iDstR = pFxSend->DestinationChannel(1);
883                    if (iDstR < 0) {
884                        dmsg(1,("Engine::RouteAudio() Error: invalid FX send (R) destination channel"));
885                    } else {
886                        AudioChannel* pDstR = pAudioOutputDevice->Channel(iDstR);
887                        if (!pDstR) {
888                            dmsg(1,("Engine::RouteAudio() Error: invalid FX send (R) destination channel"));
889                        } else pEngineChannel->pChannelRight->MixTo(pDstR, Samples, pFxSend->Level());
890                    }
891                }
892            }
893            // reset buffers with silence (zero out) for the next audio cycle
894            pEngineChannel->pChannelLeft->Clear();
895            pEngineChannel->pChannelRight->Clear();
896      }      }
897    
898      /**      /**
899       *  Will be called by the MIDIIn Thread to signal the audio thread to change       * Free all keys which have turned inactive in this audio fragment, from
900       *  the pitch value for all voices.       * the list of active keys and clear all event lists on that engine
901         * channel.
902       *       *
903       *  @param Pitch - MIDI pitch value (-8192 ... +8191)       * @param pEngineChannel - engine channel to cleanup
904       */       */
905      void Engine::SendPitchbend(int Pitch) {      void Engine::PostProcess(EngineChannel* pEngineChannel) {
906          Event event = pEventGenerator->CreateEvent();          // free all keys which have no active voices left
907          event.Type  = Event::type_pitchbend;          {
908          event.Pitch = Pitch;              RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
909          if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
910          else dmsg(1,("Engine: Input event queue full!"));              while (iuiKey != end) { // iterate through all active keys
911                    midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
912                    ++iuiKey;
913                    if (pKey->pActiveVoices->isEmpty()) FreeKey(pEngineChannel, pKey);
914                    #if CONFIG_DEVMODE
915                    else { // just a sanity check for debugging
916                        RTList<Voice>::Iterator itVoice     = pKey->pActiveVoices->first();
917                        RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
918                        for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
919                            if (itVoice->itKillEvent) {
920                                dmsg(1,("gig::Engine: ERROR, killed voice survived !!!\n"));
921                            }
922                        }
923                    }
924                    #endif // CONFIG_DEVMODE
925                }
926            }
927    
928            // empty the engine channel's own event lists
929            pEngineChannel->ClearEventLists();
930      }      }
931    
932      /**      /**
933       *  Will be called by the MIDIIn Thread to signal the audio thread that a       *  Will be called by the MIDI input device whenever a MIDI system
934       *  continuous controller value has changed.       *  exclusive message has arrived.
935       *       *
936       *  @param Controller - MIDI controller number of the occured control change       *  @param pData - pointer to sysex data
937       *  @param Value      - value of the control change       *  @param Size  - lenght of sysex data (in bytes)
938       */       */
939      void Engine::SendControlChange(uint8_t Controller, uint8_t Value) {      void Engine::SendSysex(void* pData, uint Size) {
940          Event event      = pEventGenerator->CreateEvent();          Event event             = pEventGenerator->CreateEvent();
941          event.Type       = Event::type_control_change;          event.Type              = Event::type_sysex;
942          event.Controller = Controller;          event.Param.Sysex.Size  = Size;
943          event.Value      = Value;          event.pEngineChannel    = NULL; // as Engine global event
944          if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);          if (pEventQueue->write_space() > 0) {
945                if (pSysexBuffer->write_space() >= Size) {
946                    // copy sysex data to input buffer
947                    uint toWrite = Size;
948                    uint8_t* pPos = (uint8_t*) pData;
949                    while (toWrite) {
950                        const uint writeNow = RTMath::Min(toWrite, pSysexBuffer->write_space_to_end());
951                        pSysexBuffer->write(pPos, writeNow);
952                        toWrite -= writeNow;
953                        pPos    += writeNow;
954    
955                    }
956                    // finally place sysex event into input event queue
957                    pEventQueue->push(&event);
958                }
959                else dmsg(1,("Engine: Sysex message too large (%d byte) for input buffer (%d byte)!",Size,CONFIG_SYSEX_BUFFER_SIZE));
960            }
961          else dmsg(1,("Engine: Input event queue full!"));          else dmsg(1,("Engine: Input event queue full!"));
962      }      }
963    
964      /**      /**
965       *  Assigns and triggers a new voice for the respective MIDI key.       *  Assigns and triggers a new voice for the respective MIDI key.
966       *       *
967       *  @param pNoteOnEvent - key, velocity and time stamp of the event       *  @param pEngineChannel - engine channel on which this event occured on
968         *  @param itNoteOnEvent - key, velocity and time stamp of the event
969       */       */
970      void Engine::ProcessNoteOn(Event* pNoteOnEvent) {      void Engine::ProcessNoteOn(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
971          midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Key];          #if !CONFIG_PROCESS_MUTED_CHANNELS
972            if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
973            #endif
974    
975            if (!pEngineChannel->pInstrument) return; // ignore if no instrument loaded
976    
977            //HACK: we should better add the transpose value only to the most mandatory places (like for retrieving the region and calculating the tuning), because otherwise voices will unintendedly survive when changing transpose while playing
978            itNoteOnEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
979    
980            const int key = itNoteOnEvent->Param.Note.Key;
981            midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key];
982    
983            // move note on event to the key's own event list
984            RTList<Event>::Iterator itNoteOnEventOnKeyList = itNoteOnEvent.moveToEndOf(pKey->pEvents);
985    
986            // if Solo Mode then kill all already active voices
987            if (pEngineChannel->SoloMode) {
988                Pool<uint>::Iterator itYoungestKey = pEngineChannel->pActiveKeys->last();
989                if (itYoungestKey) {
990                    const int iYoungestKey = *itYoungestKey;
991                    const midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[iYoungestKey];
992                    if (pOtherKey->Active) {
993                        // get final portamento position of currently active voice
994                        if (pEngineChannel->PortamentoMode) {
995                            RTList<Voice>::Iterator itVoice = pOtherKey->pActiveVoices->last();
996                            if (itVoice) itVoice->UpdatePortamentoPos(itNoteOnEventOnKeyList);
997                        }
998                        // kill all voices on the (other) key
999                        RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
1000                        RTList<Voice>::Iterator end               = pOtherKey->pActiveVoices->end();
1001                        for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
1002                            if (itVoiceToBeKilled->Type != Voice::type_release_trigger)
1003                                itVoiceToBeKilled->Kill(itNoteOnEventOnKeyList);
1004                        }
1005                    }
1006                }
1007                // set this key as 'currently active solo key'
1008                pEngineChannel->SoloKey = key;
1009            }
1010    
1011            // Change key dimension value if key is in keyswitching area
1012            {
1013                const ::gig::Instrument* pInstrument = pEngineChannel->pInstrument;
1014                if (key >= pInstrument->DimensionKeyRange.low && key <= pInstrument->DimensionKeyRange.high)
1015                    pEngineChannel->CurrentKeyDimension = float(key - pInstrument->DimensionKeyRange.low) /
1016                        (pInstrument->DimensionKeyRange.high - pInstrument->DimensionKeyRange.low + 1);
1017            }
1018    
1019          pKey->KeyPressed = true; // the MIDI key was now pressed down          pKey->KeyPressed = true; // the MIDI key was now pressed down
1020            pKey->Velocity   = itNoteOnEventOnKeyList->Param.Note.Velocity;
1021            pKey->NoteOnTime = FrameTime + itNoteOnEventOnKeyList->FragmentPos(); // will be used to calculate note length
1022    
1023          // cancel release process of voices on this key if needed          // cancel release process of voices on this key if needed
1024          if (pKey->Active && !SustainPedal) {          if (pKey->Active && !pEngineChannel->SustainPedal) {
1025              pNoteOnEvent->Type = Event::type_cancel_release; // transform event type              RTList<Event>::Iterator itCancelReleaseEvent = pKey->pEvents->allocAppend();
1026              pEvents->move(pNoteOnEvent, pKey->pEvents); // move event to the key's own event list              if (itCancelReleaseEvent) {
1027                    *itCancelReleaseEvent = *itNoteOnEventOnKeyList;         // copy event
1028                    itCancelReleaseEvent->Type = Event::type_cancel_release; // transform event type
1029                }
1030                else dmsg(1,("Event pool emtpy!\n"));
1031          }          }
1032    
1033          // allocate a new voice for the key          // allocate and trigger new voice(s) for the key
1034          Voice* pNewVoice = pKey->pActiveVoices->alloc();          {
1035          if (pNewVoice) {              // first, get total amount of required voices (dependant on amount of layers)
1036              // launch the new voice              ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOnEventOnKeyList->Param.Note.Key);
1037              if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument) < 0) {              if (pRegion && !RegionSuspended(pRegion)) {
1038                  dmsg(1,("Triggering new voice failed!\n"));                  int voicesRequired = pRegion->Layers;
1039                  pKey->pActiveVoices->free(pNewVoice);                  // now launch the required amount of voices
1040              }                  for (int i = 0; i < voicesRequired; i++)
1041              else if (!pKey->Active) { // mark as active key                      LaunchVoice(pEngineChannel, itNoteOnEventOnKeyList, i, false, true, true);
                 pKey->Active = true;  
                 pKey->pSelf  = pActiveKeys->alloc();  
                 *pKey->pSelf = pNoteOnEvent->Key;  
1042              }              }
1043          }          }
1044          else std::cerr << "No free voice!" << std::endl << std::flush;  
1045            // if neither a voice was spawned or postponed then remove note on event from key again
1046            if (!pKey->Active && !pKey->VoiceTheftsQueued)
1047                pKey->pEvents->free(itNoteOnEventOnKeyList);
1048    
1049            if (!pEngineChannel->SoloMode || pEngineChannel->PortamentoPos < 0.0f) pEngineChannel->PortamentoPos = (float) key;
1050            pKey->RoundRobinIndex++;
1051      }      }
1052    
1053      /**      /**
# Line 515  namespace LinuxSampler { namespace gig { Line 1056  namespace LinuxSampler { namespace gig {
1056       *  sustain pedal will be released or voice turned inactive by itself (e.g.       *  sustain pedal will be released or voice turned inactive by itself (e.g.
1057       *  due to completion of sample playback).       *  due to completion of sample playback).
1058       *       *
1059       *  @param pNoteOffEvent - key, velocity and time stamp of the event       *  @param pEngineChannel - engine channel on which this event occured on
1060         *  @param itNoteOffEvent - key, velocity and time stamp of the event
1061       */       */
1062      void Engine::ProcessNoteOff(Event* pNoteOffEvent) {      void Engine::ProcessNoteOff(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOffEvent) {
1063          midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOffEvent->Key];          #if !CONFIG_PROCESS_MUTED_CHANNELS
1064            if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1065            #endif
1066    
1067            //HACK: we should better add the transpose value only to the most mandatory places (like for retrieving the region and calculating the tuning), because otherwise voices will unintendedly survive when changing transpose while playing
1068            itNoteOffEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
1069    
1070            const int iKey = itNoteOffEvent->Param.Note.Key;
1071            midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[iKey];
1072          pKey->KeyPressed = false; // the MIDI key was now released          pKey->KeyPressed = false; // the MIDI key was now released
1073    
1074          // release voices on this key if needed          // move event to the key's own event list
1075          if (pKey->Active && !SustainPedal) {          RTList<Event>::Iterator itNoteOffEventOnKeyList = itNoteOffEvent.moveToEndOf(pKey->pEvents);
1076              pNoteOffEvent->Type = Event::type_release; // transform event type  
1077              pEvents->move(pNoteOffEvent, pKey->pEvents); // move event to the key's own event list          bool bShouldRelease = pKey->Active && ShouldReleaseVoice(pEngineChannel, itNoteOffEventOnKeyList->Param.Note.Key);
1078    
1079            // in case Solo Mode is enabled, kill all voices on this key and respawn a voice on the highest pressed key (if any)
1080            if (pEngineChannel->SoloMode && pEngineChannel->pInstrument) { //TODO: this feels like too much code just for handling solo mode :P
1081                bool bOtherKeysPressed = false;
1082                if (iKey == pEngineChannel->SoloKey) {
1083                    pEngineChannel->SoloKey = -1;
1084                    // if there's still a key pressed down, respawn a voice (group) on the highest key
1085                    for (int i = 127; i > 0; i--) {
1086                        midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[i];
1087                        if (pOtherKey->KeyPressed) {
1088                            bOtherKeysPressed = true;
1089                            // make the other key the new 'currently active solo key'
1090                            pEngineChannel->SoloKey = i;
1091                            // get final portamento position of currently active voice
1092                            if (pEngineChannel->PortamentoMode) {
1093                                RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
1094                                if (itVoice) itVoice->UpdatePortamentoPos(itNoteOffEventOnKeyList);
1095                            }
1096                            // create a pseudo note on event
1097                            RTList<Event>::Iterator itPseudoNoteOnEvent = pOtherKey->pEvents->allocAppend();
1098                            if (itPseudoNoteOnEvent) {
1099                                // copy event
1100                                *itPseudoNoteOnEvent = *itNoteOffEventOnKeyList;
1101                                // transform event to a note on event
1102                                itPseudoNoteOnEvent->Type                = Event::type_note_on;
1103                                itPseudoNoteOnEvent->Param.Note.Key      = i;
1104                                itPseudoNoteOnEvent->Param.Note.Velocity = pOtherKey->Velocity;
1105                                // allocate and trigger new voice(s) for the other key
1106                                {
1107                                    // first, get total amount of required voices (dependant on amount of layers)
1108                                    ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(i);
1109                                    if (pRegion) {
1110                                        int voicesRequired = pRegion->Layers;
1111                                        // now launch the required amount of voices
1112                                        for (int iLayer = 0; iLayer < voicesRequired; iLayer++)
1113                                            LaunchVoice(pEngineChannel, itPseudoNoteOnEvent, iLayer, false, true, false);
1114                                    }
1115                                }
1116                                // if neither a voice was spawned or postponed then remove note on event from key again
1117                                if (!pOtherKey->Active && !pOtherKey->VoiceTheftsQueued)
1118                                    pOtherKey->pEvents->free(itPseudoNoteOnEvent);
1119    
1120                            } else dmsg(1,("Could not respawn voice, no free event left\n"));
1121                            break; // done
1122                        }
1123                    }
1124                }
1125                if (bOtherKeysPressed) {
1126                    if (pKey->Active) { // kill all voices on this key
1127                        bShouldRelease = false; // no need to release, as we kill it here
1128                        RTList<Voice>::Iterator itVoiceToBeKilled = pKey->pActiveVoices->first();
1129                        RTList<Voice>::Iterator end               = pKey->pActiveVoices->end();
1130                        for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
1131                            if (itVoiceToBeKilled->Type != Voice::type_release_trigger)
1132                                itVoiceToBeKilled->Kill(itNoteOffEventOnKeyList);
1133                        }
1134                    }
1135                } else pEngineChannel->PortamentoPos = -1.0f;
1136          }          }
1137    
1138            // if no solo mode (the usual case) or if solo mode and no other key pressed, then release voices on this key if needed
1139            if (bShouldRelease) {
1140                itNoteOffEventOnKeyList->Type = Event::type_release; // transform event type
1141    
1142                // spawn release triggered voice(s) if needed
1143                if (pKey->ReleaseTrigger && pEngineChannel->pInstrument) {
1144                    // first, get total amount of required voices (dependant on amount of layers)
1145                    ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key);
1146                    if (pRegion) {
1147                        int voicesRequired = pRegion->Layers;
1148    
1149                        // MIDI note-on velocity is used instead of note-off velocity
1150                        itNoteOffEventOnKeyList->Param.Note.Velocity = pKey->Velocity;
1151    
1152                        // now launch the required amount of voices
1153                        for (int i = 0; i < voicesRequired; i++)
1154                            LaunchVoice(pEngineChannel, itNoteOffEventOnKeyList, i, true, false, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples
1155                    }
1156                    pKey->ReleaseTrigger = false;
1157                }
1158            }
1159    
1160            // if neither a voice was spawned or postponed on this key then remove note off event from key again
1161            if (!pKey->Active && !pKey->VoiceTheftsQueued)
1162                pKey->pEvents->free(itNoteOffEventOnKeyList);
1163        }
1164    
1165        /**
1166         *  Moves pitchbend event from the general (input) event list to the engine
1167         *  channel's event list. It will actually processed later by the
1168         *  respective voice.
1169         *
1170         *  @param pEngineChannel - engine channel on which this event occured on
1171         *  @param itPitchbendEvent - absolute pitch value and time stamp of the event
1172         */
1173        void Engine::ProcessPitchbend(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itPitchbendEvent) {
1174            pEngineChannel->Pitch = itPitchbendEvent->Param.Pitch.Pitch; // store current pitch value
1175      }      }
1176    
1177      /**      /**
1178       *  Moves pitchbend event from the general (input) event list to the pitch       *  Allocates and triggers a new voice. This method will usually be
1179       *  event list.       *  called by the ProcessNoteOn() method and by the voices itself
1180         *  (e.g. to spawn further voices on the same key for layered sounds).
1181       *       *
1182       *  @param pPitchbendEvent - absolute pitch value and time stamp of the event       *  @param pEngineChannel      - engine channel on which this event occured on
1183         *  @param itNoteOnEvent       - key, velocity and time stamp of the event
1184         *  @param iLayer              - layer index for the new voice (optional - only
1185         *                               in case of layered sounds of course)
1186         *  @param ReleaseTriggerVoice - if new voice is a release triggered voice
1187         *                               (optional, default = false)
1188         *  @param VoiceStealing       - if voice stealing should be performed
1189         *                               when there is no free voice
1190         *                               (optional, default = true)
1191         *  @param HandleKeyGroupConflicts - if voices should be killed due to a
1192         *                                   key group conflict
1193         *  @returns pointer to new voice or NULL if there was no free voice or
1194         *           if the voice wasn't triggered (for example when no region is
1195         *           defined for the given key).
1196       */       */
1197      void Engine::ProcessPitchbend(Event* pPitchbendEvent) {      Pool<Voice>::Iterator Engine::LaunchVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing, bool HandleKeyGroupConflicts) {
1198          this->Pitch = pPitchbendEvent->Pitch; // store current pitch value          int MIDIKey            = itNoteOnEvent->Param.Note.Key;
1199          pEvents->move(pPitchbendEvent, pSynthesisEvents[Event::destination_vco]);          midi_key_info_t* pKey  = &pEngineChannel->pMIDIKeyInfo[MIDIKey];
1200            ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(MIDIKey);
1201    
1202            // if nothing defined for this key
1203            if (!pRegion) return Pool<Voice>::Iterator(); // nothing to do
1204    
1205            // only mark the first voice of a layered voice (group) to be in a
1206            // key group, so the layered voices won't kill each other
1207            int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;
1208    
1209            // handle key group (a.k.a. exclusive group) conflicts
1210            if (HandleKeyGroupConflicts) {
1211                if (iKeyGroup) { // if this voice / key belongs to a key group
1212                    uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[iKeyGroup];
1213                    if (*ppKeyGroup) { // if there's already an active key in that key group
1214                        midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[**ppKeyGroup];
1215                        // kill all voices on the (other) key
1216                        RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
1217                        RTList<Voice>::Iterator end               = pOtherKey->pActiveVoices->end();
1218                        for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
1219                            if (itVoiceToBeKilled->Type != Voice::type_release_trigger) {
1220                                itVoiceToBeKilled->Kill(itNoteOnEvent);
1221                                --VoiceSpawnsLeft; //FIXME: just a hack, we should better check in StealVoice() if the voice was killed due to key conflict
1222                            }
1223                        }
1224                    }
1225                }
1226            }
1227    
1228            Voice::type_t VoiceType = Voice::type_normal;
1229    
1230            // get current dimension values to select the right dimension region
1231            //TODO: for stolen voices this dimension region selection block is processed twice, this should be changed
1232            //FIXME: controller values for selecting the dimension region here are currently not sample accurate
1233            uint DimValues[8] = { 0 };
1234            for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
1235                switch (pRegion->pDimensionDefinitions[i].dimension) {
1236                    case ::gig::dimension_samplechannel:
1237                        DimValues[i] = 0; //TODO: we currently ignore this dimension
1238                        break;
1239                    case ::gig::dimension_layer:
1240                        DimValues[i] = iLayer;
1241                        break;
1242                    case ::gig::dimension_velocity:
1243                        DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
1244                        break;
1245                    case ::gig::dimension_channelaftertouch:
1246                        DimValues[i] = pEngineChannel->ControllerTable[128];
1247                        break;
1248                    case ::gig::dimension_releasetrigger:
1249                        VoiceType = (ReleaseTriggerVoice) ? Voice::type_release_trigger : (!iLayer) ? Voice::type_release_trigger_required : Voice::type_normal;
1250                        DimValues[i] = (uint) ReleaseTriggerVoice;
1251                        break;
1252                    case ::gig::dimension_keyboard:
1253                        DimValues[i] = (uint) (pEngineChannel->CurrentKeyDimension * pRegion->pDimensionDefinitions[i].zones);
1254                        break;
1255                    case ::gig::dimension_roundrobin:
1256                        DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on
1257                        break;
1258                    case ::gig::dimension_random:
1259                        RandomSeed   = RandomSeed * 1103515245 + 12345; // classic pseudo random number generator
1260                        DimValues[i] = (uint) RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random
1261                        break;
1262                    case ::gig::dimension_modwheel:
1263                        DimValues[i] = pEngineChannel->ControllerTable[1];
1264                        break;
1265                    case ::gig::dimension_breath:
1266                        DimValues[i] = pEngineChannel->ControllerTable[2];
1267                        break;
1268                    case ::gig::dimension_foot:
1269                        DimValues[i] = pEngineChannel->ControllerTable[4];
1270                        break;
1271                    case ::gig::dimension_portamentotime:
1272                        DimValues[i] = pEngineChannel->ControllerTable[5];
1273                        break;
1274                    case ::gig::dimension_effect1:
1275                        DimValues[i] = pEngineChannel->ControllerTable[12];
1276                        break;
1277                    case ::gig::dimension_effect2:
1278                        DimValues[i] = pEngineChannel->ControllerTable[13];
1279                        break;
1280                    case ::gig::dimension_genpurpose1:
1281                        DimValues[i] = pEngineChannel->ControllerTable[16];
1282                        break;
1283                    case ::gig::dimension_genpurpose2:
1284                        DimValues[i] = pEngineChannel->ControllerTable[17];
1285                        break;
1286                    case ::gig::dimension_genpurpose3:
1287                        DimValues[i] = pEngineChannel->ControllerTable[18];
1288                        break;
1289                    case ::gig::dimension_genpurpose4:
1290                        DimValues[i] = pEngineChannel->ControllerTable[19];
1291                        break;
1292                    case ::gig::dimension_sustainpedal:
1293                        DimValues[i] = pEngineChannel->ControllerTable[64];
1294                        break;
1295                    case ::gig::dimension_portamento:
1296                        DimValues[i] = pEngineChannel->ControllerTable[65];
1297                        break;
1298                    case ::gig::dimension_sostenutopedal:
1299                        DimValues[i] = pEngineChannel->ControllerTable[66];
1300                        break;
1301                    case ::gig::dimension_softpedal:
1302                        DimValues[i] = pEngineChannel->ControllerTable[67];
1303                        break;
1304                    case ::gig::dimension_genpurpose5:
1305                        DimValues[i] = pEngineChannel->ControllerTable[80];
1306                        break;
1307                    case ::gig::dimension_genpurpose6:
1308                        DimValues[i] = pEngineChannel->ControllerTable[81];
1309                        break;
1310                    case ::gig::dimension_genpurpose7:
1311                        DimValues[i] = pEngineChannel->ControllerTable[82];
1312                        break;
1313                    case ::gig::dimension_genpurpose8:
1314                        DimValues[i] = pEngineChannel->ControllerTable[83];
1315                        break;
1316                    case ::gig::dimension_effect1depth:
1317                        DimValues[i] = pEngineChannel->ControllerTable[91];
1318                        break;
1319                    case ::gig::dimension_effect2depth:
1320                        DimValues[i] = pEngineChannel->ControllerTable[92];
1321                        break;
1322                    case ::gig::dimension_effect3depth:
1323                        DimValues[i] = pEngineChannel->ControllerTable[93];
1324                        break;
1325                    case ::gig::dimension_effect4depth:
1326                        DimValues[i] = pEngineChannel->ControllerTable[94];
1327                        break;
1328                    case ::gig::dimension_effect5depth:
1329                        DimValues[i] = pEngineChannel->ControllerTable[95];
1330                        break;
1331                    case ::gig::dimension_none:
1332                        std::cerr << "gig::Engine::LaunchVoice() Error: dimension=none\n" << std::flush;
1333                        break;
1334                    default:
1335                        std::cerr << "gig::Engine::LaunchVoice() Error: Unknown dimension\n" << std::flush;
1336                }
1337            }
1338    
1339            // return if this is a release triggered voice and there is no
1340            // releasetrigger dimension (could happen if an instrument
1341            // change has occured between note on and off)
1342            if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
1343    
1344            ::gig::DimensionRegion* pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
1345    
1346            // no need to continue if sample is silent
1347            if (!pDimRgn->pSample || !pDimRgn->pSample->SamplesTotal) return Pool<Voice>::Iterator();
1348    
1349            // allocate a new voice for the key
1350            Pool<Voice>::Iterator itNewVoice = pKey->pActiveVoices->allocAppend();
1351            if (itNewVoice) {
1352                // launch the new voice
1353                if (itNewVoice->Trigger(pEngineChannel, itNoteOnEvent, pEngineChannel->Pitch, pDimRgn, VoiceType, iKeyGroup) < 0) {
1354                    dmsg(4,("Voice not triggered\n"));
1355                    pKey->pActiveVoices->free(itNewVoice);
1356                }
1357                else { // on success
1358                    --VoiceSpawnsLeft;
1359                    if (!pKey->Active) { // mark as active key
1360                        pKey->Active = true;
1361                        pKey->itSelf = pEngineChannel->pActiveKeys->allocAppend();
1362                        *pKey->itSelf = itNoteOnEvent->Param.Note.Key;
1363                    }
1364                    if (itNewVoice->KeyGroup) {
1365                        uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[itNewVoice->KeyGroup];
1366                        *ppKeyGroup = &*pKey->itSelf; // put key as the (new) active key to its key group
1367                    }
1368                    if (itNewVoice->Type == Voice::type_release_trigger_required) pKey->ReleaseTrigger = true; // mark key for the need of release triggered voice(s)
1369                    return itNewVoice; // success
1370                }
1371            }
1372            else if (VoiceStealing) {
1373                // try to steal one voice
1374                int result = StealVoice(pEngineChannel, itNoteOnEvent);
1375                if (!result) { // voice stolen successfully
1376                    // put note-on event into voice-stealing queue, so it will be reprocessed after killed voice died
1377                    RTList<Event>::Iterator itStealEvent = pVoiceStealingQueue->allocAppend();
1378                    if (itStealEvent) {
1379                        *itStealEvent = *itNoteOnEvent; // copy event
1380                        itStealEvent->Param.Note.Layer = iLayer;
1381                        itStealEvent->Param.Note.ReleaseTrigger = ReleaseTriggerVoice;
1382                        pKey->VoiceTheftsQueued++;
1383                    }
1384                    else dmsg(1,("Voice stealing queue full!\n"));
1385                }
1386            }
1387    
1388            return Pool<Voice>::Iterator(); // no free voice or error
1389      }      }
1390    
1391      /**      /**
1392       *  Immediately kills the voice given with pVoice (no matter if sustain is       *  Will be called by LaunchVoice() method in case there are no free
1393       *  pressed or not) and removes it from the MIDI key's list of active voice.       *  voices left. This method will select and kill one old voice for
1394       *  This method will e.g. be called if a voice went inactive by itself.       *  voice stealing and postpone the note-on event until the selected
1395         *  voice actually died.
1396       *       *
1397       *  @param pVoice - points to the voice to be killed       *  @param pEngineChannel - engine channel on which this event occured on
1398         *  @param itNoteOnEvent - key, velocity and time stamp of the event
1399         *  @returns 0 on success, a value < 0 if no active voice could be picked for voice stealing
1400       */       */
1401      void Engine::KillVoice(Voice* pVoice) {      int Engine::StealVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
1402          if (pVoice) {          if (VoiceSpawnsLeft <= 0) {
1403              if (pVoice->IsActive()) pVoice->Kill();              dmsg(1,("Max. voice thefts per audio fragment reached (you may raise CONFIG_MAX_VOICES).\n"));
1404                return -1;
1405            }
1406            if (!pEventPool->poolIsEmpty()) {
1407    
1408                RTList<Voice>::Iterator itSelectedVoice;
1409    
1410                // Select one voice for voice stealing
1411                switch (CONFIG_VOICE_STEAL_ALGO) {
1412    
1413                    // try to pick the oldest voice on the key where the new
1414                    // voice should be spawned, if there is no voice on that
1415                    // key, or no voice left to kill, then procceed with
1416                    // 'oldestkey' algorithm
1417                    case voice_steal_algo_oldestvoiceonkey: {
1418                        midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key];
1419                        itSelectedVoice = pSelectedKey->pActiveVoices->first();
1420                        // proceed iterating if voice was created in this fragment cycle
1421                        while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1422                        // if we haven't found a voice then proceed with algorithm 'oldestkey'
1423                        if (itSelectedVoice && itSelectedVoice->IsStealable()) break;
1424                    } // no break - intentional !
1425    
1426                    // try to pick the oldest voice on the oldest active key
1427                    // from the same engine channel
1428                    // (caution: must stay after 'oldestvoiceonkey' algorithm !)
1429                    case voice_steal_algo_oldestkey: {
1430                        // if we already stole in this fragment, try to proceed on same key
1431                        if (this->itLastStolenVoice) {
1432                            itSelectedVoice = this->itLastStolenVoice;
1433                            do {
1434                                ++itSelectedVoice;
1435                            } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1436                            // found a "stealable" voice ?
1437                            if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1438                                // remember which voice we stole, so we can simply proceed on next voice stealing
1439                                this->itLastStolenVoice = itSelectedVoice;
1440                                break; // selection succeeded
1441                            }
1442                        }
1443                        // get (next) oldest key
1444                        RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKey) ? ++this->iuiLastStolenKey : pEngineChannel->pActiveKeys->first();
1445                        while (iuiSelectedKey) {
1446                            midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[*iuiSelectedKey];
1447                            itSelectedVoice = pSelectedKey->pActiveVoices->first();
1448                            // proceed iterating if voice was created in this fragment cycle
1449                            while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1450                            // found a "stealable" voice ?
1451                            if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1452                                // remember which voice on which key we stole, so we can simply proceed on next voice stealing
1453                                this->iuiLastStolenKey  = iuiSelectedKey;
1454                                this->itLastStolenVoice = itSelectedVoice;
1455                                break; // selection succeeded
1456                            }
1457                            ++iuiSelectedKey; // get next oldest key
1458                        }
1459                        break;
1460                    }
1461    
1462                    // don't steal anything
1463                    case voice_steal_algo_none:
1464                    default: {
1465                        dmsg(1,("No free voice (voice stealing disabled)!\n"));
1466                        return -1;
1467                    }
1468                }
1469    
1470                // if we couldn't steal a voice from the same engine channel then
1471                // steal oldest voice on the oldest key from any other engine channel
1472                // (the smaller engine channel number, the higher priority)
1473                if (!itSelectedVoice || !itSelectedVoice->IsStealable()) {
1474                    EngineChannel* pSelectedChannel;
1475                    int            iChannelIndex;
1476                    // select engine channel
1477                    if (pLastStolenChannel) {
1478                        pSelectedChannel = pLastStolenChannel;
1479                        iChannelIndex    = pSelectedChannel->iEngineIndexSelf;
1480                    } else { // pick the engine channel followed by this engine channel
1481                        iChannelIndex    = (pEngineChannel->iEngineIndexSelf + 1) % engineChannels.size();
1482                        pSelectedChannel = engineChannels[iChannelIndex];
1483                    }
1484    
1485                    // if we already stole in this fragment, try to proceed on same key
1486                    if (this->itLastStolenVoiceGlobally) {
1487                        itSelectedVoice = this->itLastStolenVoiceGlobally;
1488                        do {
1489                            ++itSelectedVoice;
1490                        } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1491                    }
1492    
1493                    #if CONFIG_DEVMODE
1494                    EngineChannel* pBegin = pSelectedChannel; // to detect endless loop
1495                    #endif // CONFIG_DEVMODE
1496    
1497                    // did we find a 'stealable' voice?
1498                    if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1499                        // remember which voice we stole, so we can simply proceed on next voice stealing
1500                        this->itLastStolenVoiceGlobally = itSelectedVoice;
1501                    } else while (true) { // iterate through engine channels
1502                        // get (next) oldest key
1503                        RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKeyGlobally) ? ++this->iuiLastStolenKeyGlobally : pSelectedChannel->pActiveKeys->first();
1504                        this->iuiLastStolenKeyGlobally = RTList<uint>::Iterator(); // to prevent endless loop (see line above)
1505                        while (iuiSelectedKey) {
1506                            midi_key_info_t* pSelectedKey = &pSelectedChannel->pMIDIKeyInfo[*iuiSelectedKey];
1507                            itSelectedVoice = pSelectedKey->pActiveVoices->first();
1508                            // proceed iterating if voice was created in this fragment cycle
1509                            while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1510                            // found a "stealable" voice ?
1511                            if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1512                                // remember which voice on which key on which engine channel we stole, so we can simply proceed on next voice stealing
1513                                this->iuiLastStolenKeyGlobally  = iuiSelectedKey;
1514                                this->itLastStolenVoiceGlobally = itSelectedVoice;
1515                                this->pLastStolenChannel        = pSelectedChannel;
1516                                goto stealable_voice_found; // selection succeeded
1517                            }
1518                            ++iuiSelectedKey; // get next key on current engine channel
1519                        }
1520                        // get next engine channel
1521                        iChannelIndex    = (iChannelIndex + 1) % engineChannels.size();
1522                        pSelectedChannel = engineChannels[iChannelIndex];
1523    
1524                        #if CONFIG_DEVMODE
1525                        if (pSelectedChannel == pBegin) {
1526                            dmsg(1,("FATAL ERROR: voice stealing endless loop!\n"));
1527                            dmsg(1,("VoiceSpawnsLeft=%d.\n", VoiceSpawnsLeft));
1528                            dmsg(1,("Exiting.\n"));
1529                            exit(-1);
1530                        }
1531                        #endif // CONFIG_DEVMODE
1532                    }
1533                }
1534    
1535                // jump point if a 'stealable' voice was found
1536                stealable_voice_found:
1537    
1538                #if CONFIG_DEVMODE
1539                if (!itSelectedVoice->IsActive()) {
1540                    dmsg(1,("gig::Engine: ERROR, tried to steal a voice which was not active !!!\n"));
1541                    return -1;
1542                }
1543                #endif // CONFIG_DEVMODE
1544    
1545                // now kill the selected voice
1546                itSelectedVoice->Kill(itNoteOnEvent);
1547    
1548              midi_key_info_t* pKey = &pMIDIKeyInfo[pVoice->MIDIKey];              --VoiceSpawnsLeft;
1549    
1550                return 0; // success
1551            }
1552            else {
1553                dmsg(1,("Event pool emtpy!\n"));
1554                return -1;
1555            }
1556        }
1557    
1558        /**
1559         *  Removes the given voice from the MIDI key's list of active voices.
1560         *  This method will be called when a voice went inactive, e.g. because
1561         *  it finished to playback its sample, finished its release stage or
1562         *  just was killed.
1563         *
1564         *  @param pEngineChannel - engine channel on which this event occured on
1565         *  @param itVoice - points to the voice to be freed
1566         */
1567        void Engine::FreeVoice(EngineChannel* pEngineChannel, Pool<Voice>::Iterator& itVoice) {
1568            if (itVoice) {
1569                midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoice->MIDIKey];
1570    
1571                uint keygroup = itVoice->KeyGroup;
1572    
1573                // if the sample and dimension region belong to an
1574                // instrument that is unloaded, tell the disk thread to
1575                // release them
1576                if (itVoice->Orphan) {
1577                    pDiskThread->OrderDeletionOfDimreg(itVoice->pDimRgn);
1578                }
1579    
1580              // free the voice object              // free the voice object
1581              pVoicePool->free(pVoice);              pVoicePool->free(itVoice);
1582    
1583              // check if there are no voices left on the MIDI key and update the key info if so              // if no other voices left and member of a key group, remove from key group
1584              if (pKey->pActiveVoices->is_empty()) {              if (pKey->pActiveVoices->isEmpty() && keygroup) {
1585                  pKey->Active = false;                  uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[keygroup];
1586                  pActiveKeys->free(pKey->pSelf); // remove key from list of active keys                  if (*ppKeyGroup == &*pKey->itSelf) *ppKeyGroup = NULL; // remove key from key group
                 pKey->pSelf = NULL;  
                 dmsg(3,("Key has no more voices now\n"));  
1587              }              }
1588          }          }
1589          else std::cerr << "Couldn't release voice! (pVoice == NULL)\n" << std::flush;          else std::cerr << "Couldn't release voice! (!itVoice)\n" << std::flush;
1590        }
1591    
1592        /**
1593         *  Called when there's no more voice left on a key, this call will
1594         *  update the key info respectively.
1595         *
1596         *  @param pEngineChannel - engine channel on which this event occured on
1597         *  @param pKey - key which is now inactive
1598         */
1599        void Engine::FreeKey(EngineChannel* pEngineChannel, midi_key_info_t* pKey) {
1600            if (pKey->pActiveVoices->isEmpty()) {
1601                pKey->Active = false;
1602                pEngineChannel->pActiveKeys->free(pKey->itSelf); // remove key from list of active keys
1603                pKey->itSelf = RTList<uint>::Iterator();
1604                pKey->ReleaseTrigger = false;
1605                pKey->pEvents->clear();
1606                dmsg(3,("Key has no more voices now\n"));
1607            }
1608            else dmsg(1,("gig::Engine: Oops, tried to free a key which contains voices.\n"));
1609      }      }
1610    
1611      /**      /**
1612       *  Reacts on supported control change commands (e.g. pitch bend wheel,       *  Reacts on supported control change commands (e.g. pitch bend wheel,
1613       *  modulation wheel, aftertouch).       *  modulation wheel, aftertouch).
1614       *       *
1615       *  @param pControlChangeEvent - controller, value and time stamp of the event       *  @param pEngineChannel - engine channel on which this event occured on
1616         *  @param itControlChangeEvent - controller, value and time stamp of the event
1617       */       */
1618      void Engine::ProcessControlChange(Event* pControlChangeEvent) {      void Engine::ProcessControlChange(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itControlChangeEvent) {
1619          dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", pControlChangeEvent->Controller, pControlChangeEvent->Value));          dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));
1620    
1621          switch (pControlChangeEvent->Controller) {          // handle the "control triggered" MIDI rule: a control change
1622              case 64: {          // event can trigger a new note on or note off event
1623                  if (pControlChangeEvent->Value >= 64 && !SustainPedal) {          if (pEngineChannel->pInstrument) {
1624                      dmsg(4,("PEDAL DOWN\n"));  
1625                      SustainPedal = true;              ::gig::MidiRule* rule;
1626                for (int i = 0 ; (rule = pEngineChannel->pInstrument->GetMidiRule(i)) ; i++) {
1627    
1628                    if (::gig::MidiRuleCtrlTrigger* ctrlTrigger =
1629                        dynamic_cast< ::gig::MidiRuleCtrlTrigger*>(rule)) {
1630                        if (itControlChangeEvent->Param.CC.Controller ==
1631                            ctrlTrigger->ControllerNumber) {
1632    
1633                            uint8_t oldCCValue = pEngineChannel->ControllerTable[
1634                                itControlChangeEvent->Param.CC.Controller];
1635                            uint8_t newCCValue = itControlChangeEvent->Param.CC.Value;
1636    
1637                            for (int i = 0 ; i < ctrlTrigger->Triggers ; i++) {
1638                                ::gig::MidiRuleCtrlTrigger::trigger_t* pTrigger =
1639                                      &ctrlTrigger->pTriggers[i];
1640    
1641                                // check if the controller has passed the
1642                                // trigger point in the right direction
1643                                if ((pTrigger->Descending &&
1644                                     oldCCValue > pTrigger->TriggerPoint &&
1645                                     newCCValue <= pTrigger->TriggerPoint) ||
1646                                    (!pTrigger->Descending &&
1647                                     oldCCValue < pTrigger->TriggerPoint &&
1648                                     newCCValue >= pTrigger->TriggerPoint)) {
1649    
1650                                    RTList<Event>::Iterator itNewEvent = pGlobalEvents->allocAppend();
1651                                    if (itNewEvent) {
1652                                        *itNewEvent = *itControlChangeEvent;
1653                                        itNewEvent->Param.Note.Key = pTrigger->Key;
1654    
1655                                        if (pTrigger->NoteOff || pTrigger->Velocity == 0) {
1656                                            itNewEvent->Type = Event::type_note_off;
1657                                            itNewEvent->Param.Note.Velocity = 100;
1658    
1659                                            ProcessNoteOff(pEngineChannel, itNewEvent);
1660                                        } else {
1661                                            itNewEvent->Type = Event::type_note_on;
1662                                            //TODO: if Velocity is 255, the triggered velocity should
1663                                            // depend on how fast the controller is moving
1664                                            itNewEvent->Param.Note.Velocity =
1665                                                pTrigger->Velocity == 255 ? 100 :
1666                                                pTrigger->Velocity;
1667    
1668                                            ProcessNoteOn(pEngineChannel, itNewEvent);
1669                                        }
1670                                    }
1671                                    else dmsg(1,("Event pool emtpy!\n"));
1672                                }
1673                            }
1674                        }
1675                    }
1676                }
1677            }
1678    
1679            // update controller value in the engine channel's controller table
1680            pEngineChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;
1681    
1682            // handle hard coded MIDI controllers
1683            switch (itControlChangeEvent->Param.CC.Controller) {
1684                case 5: { // portamento time
1685                    pEngineChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN;
1686                    break;
1687                }
1688                case 6: { // data entry (currently only used for RPN controllers)
1689                    if (pEngineChannel->GetMidiRpnController() == 2) { // coarse tuning in half tones
1690                        int transpose = (int) itControlChangeEvent->Param.CC.Value - 64;
1691                        // limit to +- two octaves for now
1692                        transpose = RTMath::Min(transpose,  24);
1693                        transpose = RTMath::Max(transpose, -24);
1694                        pEngineChannel->GlobalTranspose = transpose;
1695                        // workaround, so we won't have hanging notes
1696                        ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1697                    }
1698                    // to avoid other MIDI CC #6 messages to be misenterpreted as RPN controller data
1699                    pEngineChannel->ResetMidiRpnController();
1700                    break;
1701                }
1702                case 7: { // volume
1703                    //TODO: not sample accurate yet
1704                    pEngineChannel->MidiVolume = VolumeCurve[itControlChangeEvent->Param.CC.Value];
1705                    pEngineChannel->bStatusChanged = true; // engine channel status has changed, so set notify flag
1706                    break;
1707                }
1708                case 10: { // panpot
1709                    //TODO: not sample accurate yet
1710                    pEngineChannel->GlobalPanLeft  = PanCurve[128 - itControlChangeEvent->Param.CC.Value];
1711                    pEngineChannel->GlobalPanRight = PanCurve[itControlChangeEvent->Param.CC.Value];
1712                    break;
1713                }
1714                case 64: { // sustain
1715                    if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SustainPedal) {
1716                        dmsg(4,("DAMPER (RIGHT) PEDAL DOWN\n"));
1717                        pEngineChannel->SustainPedal = true;
1718    
1719                        #if !CONFIG_PROCESS_MUTED_CHANNELS
1720                        if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1721                        #endif
1722    
1723                      // cancel release process of voices if necessary                      // cancel release process of voices if necessary
1724                      uint* piKey = pActiveKeys->first();                      RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1725                      if (piKey) {                      for (; iuiKey; ++iuiKey) {
1726                          pControlChangeEvent->Type = Event::type_cancel_release; // transform event type                          midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1727                          while (piKey) {                          if (!pKey->KeyPressed) {
1728                              midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];                              RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1729                              pActiveKeys->set_current(piKey);                              if (itNewEvent) {
1730                              piKey = pActiveKeys->next();                                  *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1731                              if (!pKey->KeyPressed) {                                  itNewEvent->Type = Event::type_cancel_release; // transform event type
                                 Event* pNewEvent = pKey->pEvents->alloc();  
                                 if (pNewEvent) *pNewEvent = *pControlChangeEvent; // copy event to the key's own event list  
                                 else dmsg(1,("Event pool emtpy!\n"));  
1732                              }                              }
1733                                else dmsg(1,("Event pool emtpy!\n"));
1734                          }                          }
1735                      }                      }
1736                  }                  }
1737                  if (pControlChangeEvent->Value < 64 && SustainPedal) {                  if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SustainPedal) {
1738                      dmsg(4,("PEDAL UP\n"));                      dmsg(4,("DAMPER (RIGHT) PEDAL UP\n"));
1739                      SustainPedal = false;                      pEngineChannel->SustainPedal = false;
1740    
1741                        #if !CONFIG_PROCESS_MUTED_CHANNELS
1742                        if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1743                        #endif
1744    
1745                      // release voices if their respective key is not pressed                      // release voices if their respective key is not pressed
1746                      uint* piKey = pActiveKeys->first();                      RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1747                      if (piKey) {                      for (; iuiKey; ++iuiKey) {
1748                          pControlChangeEvent->Type = Event::type_release; // transform event type                          midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1749                          while (piKey) {                          if (!pKey->KeyPressed && ShouldReleaseVoice(pEngineChannel, *iuiKey)) {
1750                              midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];                              RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1751                              pActiveKeys->set_current(piKey);                              if (itNewEvent) {
1752                              piKey = pActiveKeys->next();                                  *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1753                              if (!pKey->KeyPressed) {                                  itNewEvent->Type = Event::type_release; // transform event type
                                 Event* pNewEvent = pKey->pEvents->alloc();  
                                 if (pNewEvent) *pNewEvent = *pControlChangeEvent; // copy event to the key's own event list  
                                 else dmsg(1,("Event pool emtpy!\n"));  
1754                              }                              }
1755                                else dmsg(1,("Event pool emtpy!\n"));
1756                            }
1757                        }
1758                    }
1759                    break;
1760                }
1761                case 65: { // portamento on / off
1762                    const bool bPortamento = itControlChangeEvent->Param.CC.Value >= 64;
1763                    if (bPortamento != pEngineChannel->PortamentoMode)
1764                        KillAllVoices(pEngineChannel, itControlChangeEvent);
1765                    pEngineChannel->PortamentoMode = bPortamento;
1766                    break;
1767                }
1768                case 66: { // sostenuto
1769                    if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SostenutoPedal) {
1770                        dmsg(4,("SOSTENUTO (CENTER) PEDAL DOWN\n"));
1771                        pEngineChannel->SostenutoPedal = true;
1772    
1773                        #if !CONFIG_PROCESS_MUTED_CHANNELS
1774                        if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1775                        #endif
1776    
1777                        SostenutoKeyCount = 0;
1778                        // Remeber the pressed keys
1779                        RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1780                        for (; iuiKey; ++iuiKey) {
1781                            midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1782                            if (pKey->KeyPressed && SostenutoKeyCount < 128) SostenutoKeys[SostenutoKeyCount++] = *iuiKey;
1783                        }
1784                    }
1785                    if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SostenutoPedal) {
1786                        dmsg(4,("SOSTENUTO (CENTER) PEDAL UP\n"));
1787                        pEngineChannel->SostenutoPedal = false;
1788    
1789                        #if !CONFIG_PROCESS_MUTED_CHANNELS
1790                        if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1791                        #endif
1792    
1793                        // release voices if the damper pedal is up and their respective key is not pressed
1794                        for (int i = 0; i < SostenutoKeyCount; i++) {
1795                            midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[SostenutoKeys[i]];
1796                            if (!pKey->KeyPressed && !pEngineChannel->SustainPedal) {
1797                                RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1798                                if (itNewEvent) {
1799                                    *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1800                                    itNewEvent->Type = Event::type_release; // transform event type
1801                                }
1802                                else dmsg(1,("Event pool emtpy!\n"));
1803                            }
1804                        }
1805                    }
1806                    break;
1807                }
1808                case 100: { // RPN controller LSB
1809                    pEngineChannel->SetMidiRpnControllerLsb(itControlChangeEvent->Param.CC.Value);
1810                    break;
1811                }
1812                case 101: { // RPN controller MSB
1813                    pEngineChannel->SetMidiRpnControllerMsb(itControlChangeEvent->Param.CC.Value);
1814                    break;
1815                }
1816    
1817    
1818                // Channel Mode Messages
1819    
1820                case 120: { // all sound off
1821                    KillAllVoices(pEngineChannel, itControlChangeEvent);
1822                    break;
1823                }
1824                case 121: { // reset all controllers
1825                    pEngineChannel->ResetControllers();
1826                    break;
1827                }
1828                case 123: { // all notes off
1829                    #if CONFIG_PROCESS_ALL_NOTES_OFF
1830                    ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1831                    #endif // CONFIG_PROCESS_ALL_NOTES_OFF
1832                    break;
1833                }
1834                case 126: { // mono mode on
1835                    if (!pEngineChannel->SoloMode)
1836                        KillAllVoices(pEngineChannel, itControlChangeEvent);
1837                    pEngineChannel->SoloMode = true;
1838                    break;
1839                }
1840                case 127: { // poly mode on
1841                    if (pEngineChannel->SoloMode)
1842                        KillAllVoices(pEngineChannel, itControlChangeEvent);
1843                    pEngineChannel->SoloMode = false;
1844                    break;
1845                }
1846            }
1847    
1848            // handle FX send controllers
1849            if (!pEngineChannel->fxSends.empty()) {
1850                for (int iFxSend = 0; iFxSend < pEngineChannel->GetFxSendCount(); iFxSend++) {
1851                    FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
1852                    if (pFxSend->MidiController() == itControlChangeEvent->Param.CC.Controller)
1853                        pFxSend->SetLevel(itControlChangeEvent->Param.CC.Value);
1854                        pFxSend->SetInfoChanged(true);
1855                }
1856            }
1857        }
1858    
1859        /**
1860         *  Reacts on MIDI system exclusive messages.
1861         *
1862         *  @param itSysexEvent - sysex data size and time stamp of the sysex event
1863         */
1864        void Engine::ProcessSysex(Pool<Event>::Iterator& itSysexEvent) {
1865            RingBuffer<uint8_t,false>::NonVolatileReader reader = pSysexBuffer->get_non_volatile_reader();
1866    
1867            uint8_t exclusive_status, id;
1868            if (!reader.pop(&exclusive_status)) goto free_sysex_data;
1869            if (!reader.pop(&id))               goto free_sysex_data;
1870            if (exclusive_status != 0xF0)       goto free_sysex_data;
1871    
1872            switch (id) {
1873                case 0x41: { // Roland
1874                    dmsg(3,("Roland Sysex\n"));
1875                    uint8_t device_id, model_id, cmd_id;
1876                    if (!reader.pop(&device_id)) goto free_sysex_data;
1877                    if (!reader.pop(&model_id))  goto free_sysex_data;
1878                    if (!reader.pop(&cmd_id))    goto free_sysex_data;
1879                    if (model_id != 0x42 /*GS*/) goto free_sysex_data;
1880                    if (cmd_id != 0x12 /*DT1*/)  goto free_sysex_data;
1881    
1882                    // command address
1883                    uint8_t addr[3]; // 2 byte addr MSB, followed by 1 byte addr LSB)
1884                    const RingBuffer<uint8_t,false>::NonVolatileReader checksum_reader = reader; // so we can calculate the check sum later
1885                    if (reader.read(&addr[0], 3) != 3) goto free_sysex_data;
1886                    if (addr[0] == 0x40 && addr[1] == 0x00) { // System Parameters
1887                        dmsg(3,("\tSystem Parameter\n"));
1888                    }
1889                    else if (addr[0] == 0x40 && addr[1] == 0x01) { // Common Parameters
1890                        dmsg(3,("\tCommon Parameter\n"));
1891                    }
1892                    else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x10) { // Part Parameters (1)
1893                        dmsg(3,("\tPart Parameter\n"));
1894                        switch (addr[2]) {
1895                            case 0x40: { // scale tuning
1896                                dmsg(3,("\t\tScale Tuning\n"));
1897                                uint8_t scale_tunes[12]; // detuning of all 12 semitones of an octave
1898                                if (reader.read(&scale_tunes[0], 12) != 12) goto free_sysex_data;
1899                                uint8_t checksum;
1900                                if (!reader.pop(&checksum)) goto free_sysex_data;
1901                                #if CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1902                                if (GSCheckSum(checksum_reader, 12)) goto free_sysex_data;
1903                                #endif // CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1904                                for (int i = 0; i < 12; i++) scale_tunes[i] -= 64;
1905                                AdjustScale((int8_t*) scale_tunes);
1906                                dmsg(3,("\t\t\tNew scale applied.\n"));
1907                                break;
1908                          }                          }
1909                      }                      }
1910                  }                  }
1911                    else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x20) { // Part Parameters (2)
1912                    }
1913                    else if (addr[0] == 0x41) { // Drum Setup Parameters
1914                    }
1915                  break;                  break;
1916              }              }
1917          }          }
1918    
1919          // update controller value in the engine's controller table          free_sysex_data: // finally free sysex data
1920          ControllerTable[pControlChangeEvent->Controller] = pControlChangeEvent->Value;          pSysexBuffer->increment_read_ptr(itSysexEvent->Param.Sysex.Size);
1921        }
1922    
1923          // move event from the unsorted event list to the control change event list      /**
1924          pEvents->move(pControlChangeEvent, pCCEvents);       * Calculates the Roland GS sysex check sum.
1925         *
1926         * @param AddrReader - reader which currently points to the first GS
1927         *                     command address byte of the GS sysex message in
1928         *                     question
1929         * @param DataSize   - size of the GS message data (in bytes)
1930         */
1931        uint8_t Engine::GSCheckSum(const RingBuffer<uint8_t,false>::NonVolatileReader AddrReader, uint DataSize) {
1932            RingBuffer<uint8_t,false>::NonVolatileReader reader = AddrReader;
1933            uint bytes = 3 /*addr*/ + DataSize;
1934            uint8_t addr_and_data[bytes];
1935            reader.read(&addr_and_data[0], bytes);
1936            uint8_t sum = 0;
1937            for (uint i = 0; i < bytes; i++) sum += addr_and_data[i];
1938            return 128 - sum % 128;
1939      }      }
1940    
1941      /**      /**
1942       * Initialize the parameter sequence for the modulation destination given by       * Allows to tune each of the twelve semitones of an octave.
1943       * by 'dst' with the constant value given by val.       *
1944         * @param ScaleTunes - detuning of all twelve semitones (in cents)
1945       */       */
1946      void Engine::ResetSynthesisParameters(Event::destination_t dst, float val) {      void Engine::AdjustScale(int8_t ScaleTunes[12]) {
1947          int maxsamples = pAudioOutputDevice->MaxSamplesPerCycle();          memcpy(&this->ScaleTuning[0], &ScaleTunes[0], 12); //TODO: currently not sample accurate
         for (int i = 0; i < maxsamples; i++) pSynthesisParameters[dst][i] = val;  
1948      }      }
1949    
1950      float Engine::Volume() {      /**
1951          return GlobalVolume;       * Releases all voices on an engine channel. All voices will go into
1952         * the release stage and thus it might take some time (e.g. dependant to
1953         * their envelope release time) until they actually die.
1954         *
1955         * @param pEngineChannel - engine channel on which all voices should be released
1956         * @param itReleaseEvent - event which caused this releasing of all voices
1957         */
1958        void Engine::ReleaseAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itReleaseEvent) {
1959            RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1960            while (iuiKey) {
1961                midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1962                ++iuiKey;
1963                // append a 'release' event to the key's own event list
1964                RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1965                if (itNewEvent) {
1966                    *itNewEvent = *itReleaseEvent; // copy original event (to the key's event list)
1967                    itNewEvent->Type = Event::type_release; // transform event type
1968                }
1969                else dmsg(1,("Event pool emtpy!\n"));
1970            }
1971      }      }
1972    
1973      void Engine::Volume(float f) {      /**
1974          GlobalVolume = f;       * Kills all voices on an engine channel as soon as possible. Voices
1975         * won't get into release state, their volume level will be ramped down
1976         * as fast as possible.
1977         *
1978         * @param pEngineChannel - engine channel on which all voices should be killed
1979         * @param itKillEvent    - event which caused this killing of all voices
1980         */
1981        void Engine::KillAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itKillEvent) {
1982            RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1983            RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
1984            while (iuiKey != end) { // iterate through all active keys
1985                midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1986                ++iuiKey;
1987                RTList<Voice>::Iterator itVoice     = pKey->pActiveVoices->first();
1988                RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
1989                for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
1990                    itVoice->Kill(itKillEvent);
1991                    --VoiceSpawnsLeft; //FIXME: just a temporary workaround, we should check the cause in StealVoice() instead
1992                }
1993            }
1994        }
1995    
1996        /**
1997         * Determines whether the specified voice should be released.
1998         *
1999         * @param pEngineChannel - The engine channel on which the voice should be checked
2000         * @param Key - The key number
2001         * @returns true if the specified should be released, false otherwise.
2002         */
2003        bool Engine::ShouldReleaseVoice(EngineChannel* pEngineChannel, int Key) {
2004            if (pEngineChannel->SustainPedal) return false;
2005    
2006            if (pEngineChannel->SostenutoPedal) {
2007                for (int i = 0; i < SostenutoKeyCount; i++)
2008                    if (Key == SostenutoKeys[i]) return false;
2009            }
2010    
2011            return true;
2012      }      }
2013    
2014      uint Engine::VoiceCount() {      uint Engine::VoiceCount() {
# Line 674  namespace LinuxSampler { namespace gig { Line 2039  namespace LinuxSampler { namespace gig {
2039          return pDiskThread->GetBufferFillPercentage();          return pDiskThread->GetBufferFillPercentage();
2040      }      }
2041    
2042        String Engine::EngineName() {
2043            return LS_GIG_ENGINE_NAME;
2044        }
2045    
2046      String Engine::Description() {      String Engine::Description() {
2047          return "Gigasampler Engine";          return "Gigasampler Format Engine";
2048      }      }
2049    
2050      String Engine::Version() {      String Engine::Version() {
2051          return "0.0.1-0cvs20040423";          String s = "$Revision: 1.88 $";
2052            return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
2053        }
2054    
2055        InstrumentManager* Engine::GetInstrumentManager() {
2056            return &instruments;
2057        }
2058    
2059        // static constant initializers
2060        const Engine::FloatTable Engine::VolumeCurve(InitVolumeCurve());
2061        const Engine::FloatTable Engine::PanCurve(InitPanCurve());
2062        const Engine::FloatTable Engine::CrossfadeCurve(InitCrossfadeCurve());
2063    
2064        float* Engine::InitVolumeCurve() {
2065            // line-segment approximation
2066            const float segments[] = {
2067                0, 0, 2, 0.0046, 16, 0.016, 31, 0.051, 45, 0.115, 54.5, 0.2,
2068                64.5, 0.39, 74, 0.74, 92, 1.03, 114, 1.94, 119.2, 2.2, 127, 2.2
2069            };
2070            return InitCurve(segments);
2071        }
2072    
2073        float* Engine::InitPanCurve() {
2074            // line-segment approximation
2075            const float segments[] = {
2076                0, 0, 1, 0,
2077                2, 0.05, 31.5, 0.7, 51, 0.851, 74.5, 1.12,
2078                127, 1.41, 128, 1.41
2079            };
2080            return InitCurve(segments, 129);
2081        }
2082    
2083        float* Engine::InitCrossfadeCurve() {
2084            // line-segment approximation
2085            const float segments[] = {
2086                0, 0, 1, 0.03, 10, 0.1, 51, 0.58, 127, 1
2087            };
2088            return InitCurve(segments);
2089        }
2090    
2091        float* Engine::InitCurve(const float* segments, int size) {
2092            float* y = new float[size];
2093            for (int x = 0 ; x < size ; x++) {
2094                if (x > segments[2]) segments += 2;
2095                y[x] = segments[1] + (x - segments[0]) *
2096                    (segments[3] - segments[1]) / (segments[2] - segments[0]);
2097            }
2098            return y;
2099      }      }
2100    
2101  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.56  
changed lines
  Added in v.1700

  ViewVC Help
Powered by ViewVC