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

Legend:
Removed from v.133  
changed lines
  Added in v.1424

  ViewVC Help
Powered by ViewVC