/[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 250 by schoenebeck, Mon Sep 20 00:31:13 2004 UTC revision 1043 by schoenebeck, Wed Feb 7 21:02:04 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  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
33    
34      InstrumentResourceManager Engine::Instruments;      InstrumentResourceManager Engine::instruments;
35    
36        std::map<AudioOutputDevice*,Engine*> Engine::engines;
37    
38        /**
39         * Get a gig::Engine object for the given gig::EngineChannel and the
40         * given AudioOutputDevice. All engine channels which are connected to
41         * the same audio output device will use the same engine instance. This
42         * method will be called by a gig::EngineChannel whenever it's
43         * connecting to a audio output device.
44         *
45         * @param pChannel - engine channel which acquires an engine object
46         * @param pDevice  - the audio output device \a pChannel is connected to
47         */
48        Engine* Engine::AcquireEngine(LinuxSampler::gig::EngineChannel* pChannel, AudioOutputDevice* pDevice) {
49            Engine* pEngine = NULL;
50            // check if there's already an engine for the given audio output device
51            if (engines.count(pDevice)) {
52                dmsg(4,("Using existing gig::Engine.\n"));
53                pEngine = engines[pDevice];
54    
55                // Disable the engine while the new engine channel is
56                // added and initialized. The engine will be enabled again
57                // in EngineChannel::Connect.
58                pEngine->DisableAndLock();
59            } else { // create a new engine (and disk thread) instance for the given audio output device
60                dmsg(4,("Creating new gig::Engine.\n"));
61                pEngine = (Engine*) EngineFactory::Create("gig");
62                pEngine->Connect(pDevice);
63                engines[pDevice] = pEngine;
64            }
65            // register engine channel to the engine instance
66            pEngine->engineChannels.add(pChannel);
67            // remember index in the ArrayList
68            pChannel->iEngineIndexSelf = pEngine->engineChannels.size() - 1;
69            dmsg(4,("This gig::Engine has now %d EngineChannels.\n",pEngine->engineChannels.size()));
70            return pEngine;
71        }
72    
73        /**
74         * Once an engine channel is disconnected from an audio output device,
75         * it wil immediately call this method to unregister itself from the
76         * engine instance and if that engine instance is not used by any other
77         * engine channel anymore, then that engine instance will be destroyed.
78         *
79         * @param pChannel - engine channel which wants to disconnect from it's
80         *                   engine instance
81         * @param pDevice  - audio output device \a pChannel was connected to
82         */
83        void Engine::FreeEngine(LinuxSampler::gig::EngineChannel* pChannel, AudioOutputDevice* pDevice) {
84            dmsg(4,("Disconnecting EngineChannel from gig::Engine.\n"));
85            Engine* pEngine = engines[pDevice];
86            // unregister EngineChannel from the Engine instance
87            pEngine->engineChannels.remove(pChannel);
88            // if the used Engine instance is not used anymore, then destroy it
89            if (pEngine->engineChannels.empty()) {
90                pDevice->Disconnect(pEngine);
91                engines.erase(pDevice);
92                delete pEngine;
93                dmsg(4,("Destroying gig::Engine.\n"));
94            }
95            else dmsg(4,("This gig::Engine has now %d EngineChannels.\n",pEngine->engineChannels.size()));
96        }
97    
98        /**
99         * Constructor
100         */
101      Engine::Engine() {      Engine::Engine() {
         pRIFF              = NULL;  
         pGig               = NULL;  
         pInstrument        = NULL;  
102          pAudioOutputDevice = NULL;          pAudioOutputDevice = NULL;
103          pDiskThread        = NULL;          pDiskThread        = NULL;
104          pEventGenerator    = NULL;          pEventGenerator    = NULL;
105          pSysexBuffer       = new RingBuffer<uint8_t>(SYSEX_BUFFER_SIZE, 0);          pSysexBuffer       = new RingBuffer<uint8_t,false>(CONFIG_SYSEX_BUFFER_SIZE, 0);
106          pEventQueue        = new RingBuffer<Event>(MAX_EVENTS_PER_FRAGMENT, 0);          pEventQueue        = new RingBuffer<Event,false>(CONFIG_MAX_EVENTS_PER_FRAGMENT, 0);
107          pEventPool         = new RTELMemoryPool<Event>(MAX_EVENTS_PER_FRAGMENT);          pEventPool         = new Pool<Event>(CONFIG_MAX_EVENTS_PER_FRAGMENT);
108          pVoicePool         = new RTELMemoryPool<Voice>(MAX_AUDIO_VOICES);          pVoicePool         = new Pool<Voice>(CONFIG_MAX_VOICES);
109          pActiveKeys        = new RTELMemoryPool<uint>(128);          pDimRegionsInUse   = new ::gig::DimensionRegion*[CONFIG_MAX_VOICES + 1];
110          pVoiceStealingQueue = new RTEList<Event>(pEventPool);          pVoiceStealingQueue = new RTList<Event>(pEventPool);
111          pEvents            = new RTEList<Event>(pEventPool);          pGlobalEvents      = new RTList<Event>(pEventPool);
112          pCCEvents          = new RTEList<Event>(pEventPool);          InstrumentChangeQueue      = new RingBuffer<instrument_change_command_t,false>(1, 0);
113          for (uint i = 0; i < Event::destination_count; i++) {          InstrumentChangeReplyQueue = new RingBuffer<instrument_change_reply_t,false>(1, 0);
114              pSynthesisEvents[i] = new RTEList<Event>(pEventPool);  
115          }          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
116          for (uint i = 0; i < 128; i++) {              iterVoice->SetEngine(this);
             pMIDIKeyInfo[i].pActiveVoices  = new RTEList<Voice>(pVoicePool);  
             pMIDIKeyInfo[i].KeyPressed     = false;  
             pMIDIKeyInfo[i].Active         = false;  
             pMIDIKeyInfo[i].ReleaseTrigger = false;  
             pMIDIKeyInfo[i].pSelf          = NULL;  
             pMIDIKeyInfo[i].pEvents        = new RTEList<Event>(pEventPool);  
         }  
         for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) {  
             pVoice->SetEngine(this);  
117          }          }
118          pVoicePool->clear();          pVoicePool->clear();
119    
         pSynthesisParameters[0] = NULL; // we allocate when an audio device is connected  
         pBasicFilterParameters  = NULL;  
         pMainFilterParameters   = NULL;  
   
         InstrumentIdx = -1;  
         InstrumentStat = -1;  
   
         AudioDeviceChannelLeft  = -1;  
         AudioDeviceChannelRight = -1;  
   
120          ResetInternal();          ResetInternal();
121            ResetScaleTuning();
122      }      }
123    
124        /**
125         * Destructor
126         */
127      Engine::~Engine() {      Engine::~Engine() {
128            MidiInputPort::RemoveSysexListener(this);
129          if (pDiskThread) {          if (pDiskThread) {
130                dmsg(1,("Stopping disk thread..."));
131              pDiskThread->StopThread();              pDiskThread->StopThread();
132              delete pDiskThread;              delete pDiskThread;
133                dmsg(1,("OK\n"));
134          }          }
         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;  
135          if (pEventQueue) delete pEventQueue;          if (pEventQueue) delete pEventQueue;
136          if (pEventPool)  delete pEventPool;          if (pEventPool)  delete pEventPool;
137          if (pVoicePool)  delete pVoicePool;          if (pVoicePool) {
138          if (pActiveKeys) delete pActiveKeys;              pVoicePool->clear();
139          if (pSysexBuffer) delete pSysexBuffer;              delete pVoicePool;
140            }
141          if (pEventGenerator) delete pEventGenerator;          if (pEventGenerator) delete pEventGenerator;
         if (pMainFilterParameters) delete[] pMainFilterParameters;  
         if (pBasicFilterParameters) delete[] pBasicFilterParameters;  
         if (pSynthesisParameters[0]) delete[] pSynthesisParameters[0];  
142          if (pVoiceStealingQueue) delete pVoiceStealingQueue;          if (pVoiceStealingQueue) delete pVoiceStealingQueue;
143            if (pSysexBuffer) delete pSysexBuffer;
144            Unregister();
145      }      }
146    
147      void Engine::Enable() {      void Engine::Enable() {
# Line 127  namespace LinuxSampler { namespace gig { Line 168  namespace LinuxSampler { namespace gig {
168       */       */
169      void Engine::Reset() {      void Engine::Reset() {
170          DisableAndLock();          DisableAndLock();
   
         //if (pAudioOutputDevice->IsPlaying()) { // if already running  
             /*  
             // signal audio thread not to enter render part anymore  
             SuspensionRequested = true;  
             // sleep until wakened by audio thread  
             pthread_mutex_lock(&__render_state_mutex);  
             pthread_cond_wait(&__render_exit_condition, &__render_state_mutex);  
             pthread_mutex_unlock(&__render_state_mutex);  
             */  
         //}  
   
         //if (wasplaying) pAudioOutputDevice->Stop();  
   
171          ResetInternal();          ResetInternal();
172            ResetScaleTuning();
         // signal audio thread to continue with rendering  
         //SuspensionRequested = false;  
173          Enable();          Enable();
174      }      }
175    
176      /**      /**
177       *  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
178       *  control and status variables. This method is not thread safe!       *  control and status variables. This method is protected by a mutex.
179       */       */
180      void Engine::ResetInternal() {      void Engine::ResetInternal() {
181          Pitch               = 0;          ResetInternalMutex.Lock();
182          SustainPedal        = false;  
183            // make sure that the engine does not get any sysex messages
184            // while it's reseting
185            bool sysexDisabled = MidiInputPort::RemoveSysexListener(this);
186          ActiveVoiceCount    = 0;          ActiveVoiceCount    = 0;
187          ActiveVoiceCountMax = 0;          ActiveVoiceCountMax = 0;
         GlobalVolume        = 1.0;  
188    
189          // reset voice stealing parameters          // reset voice stealing parameters
         pLastStolenVoice = NULL;  
         puiLastStolenKey = NULL;  
190          pVoiceStealingQueue->clear();          pVoiceStealingQueue->clear();
191            itLastStolenVoice          = RTList<Voice>::Iterator();
192          // reset to normal chromatic scale (means equal temper)          itLastStolenVoiceGlobally  = RTList<Voice>::Iterator();
193          memset(&ScaleTuning[0], 0x00, 12);          iuiLastStolenKey           = RTList<uint>::Iterator();
194            iuiLastStolenKeyGlobally   = RTList<uint>::Iterator();
195          // set all MIDI controller values to zero          pLastStolenChannel         = NULL;
         memset(ControllerTable, 0x00, 128);  
   
         // reset key info  
         for (uint i = 0; i < 128; i++) {  
             pMIDIKeyInfo[i].pActiveVoices->clear();  
             pMIDIKeyInfo[i].pEvents->clear();  
             pMIDIKeyInfo[i].KeyPressed     = false;  
             pMIDIKeyInfo[i].Active         = false;  
             pMIDIKeyInfo[i].ReleaseTrigger = false;  
             pMIDIKeyInfo[i].pSelf          = NULL;  
         }  
   
         // reset all key groups  
         map<uint,uint*>::iterator iter = ActiveKeyGroups.begin();  
         for (; iter != ActiveKeyGroups.end(); iter++) iter->second = NULL;  
196    
197          // reset all voices          // reset all voices
198          for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) {          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
199              pVoice->Reset();              iterVoice->Reset();
200          }          }
201          pVoicePool->clear();          pVoicePool->clear();
202    
         // free all active keys  
         pActiveKeys->clear();  
   
203          // reset disk thread          // reset disk thread
204          if (pDiskThread) pDiskThread->Reset();          if (pDiskThread) pDiskThread->Reset();
205    
206          // delete all input events          // delete all input events
207          pEventQueue->init();          pEventQueue->init();
208            pSysexBuffer->init();
209            if (sysexDisabled) MidiInputPort::AddSysexListener(this);
210            ResetInternalMutex.Unlock();
211      }      }
212    
213      /**      /**
214       *  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  
215       */       */
216      void Engine::LoadInstrument(const char* FileName, uint Instrument) {      void Engine::ResetScaleTuning() {
217            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;  
   
         // delete all key groups  
         ActiveKeyGroups.clear();  
   
         // 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.");  
         }  
   
         // rebuild ActiveKeyGroups map with key groups of current instrument  
         for (::gig::Region* pRegion = pInstrument->GetFirstRegion(); pRegion; pRegion = pInstrument->GetNextRegion())  
             if (pRegion->KeyGroup) ActiveKeyGroups[pRegion->KeyGroup] = NULL;  
   
         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();  
     }  
   
     /**  
      * Will be called by the InstrumentResourceManager when the instrument  
      * we are currently using in this engine is going to be updated, so we  
      * can stop playback before that happens.  
      */  
     void Engine::ResourceToBeUpdated(::gig::Instrument* pResource, void*& pUpdateArg) {  
         dmsg(3,("gig::Engine: Received instrument update message.\n"));  
         DisableAndLock();  
         ResetInternal();  
         this->pInstrument = NULL;  
218      }      }
219    
220      /**      /**
221       * Will be called by the InstrumentResourceManager when the instrument       * Connect this engine instance with the given audio output device.
222       * update process was completed, so we can continue with playback.       * This method will be called when an Engine instance is created.
223         * All of the engine's data structures which are dependant to the used
224         * audio output device / driver will be (re)allocated and / or
225         * adjusted appropriately.
226         *
227         * @param pAudioOut - audio output device to connect to
228       */       */
     void Engine::ResourceUpdated(::gig::Instrument* pOldResource, ::gig::Instrument* pNewResource, void* pUpdateArg) {  
         this->pInstrument = pNewResource; //TODO: there are couple of engine parameters we should update here as well if the instrument was updated (see LoadInstrument())  
         Enable();  
     }  
   
229      void Engine::Connect(AudioOutputDevice* pAudioOut) {      void Engine::Connect(AudioOutputDevice* pAudioOut) {
230          pAudioOutputDevice = pAudioOut;          pAudioOutputDevice = pAudioOut;
231    
# Line 304  namespace LinuxSampler { namespace gig { Line 237  namespace LinuxSampler { namespace gig {
237          }          }
238          catch (AudioOutputException e) {          catch (AudioOutputException e) {
239              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();
240              throw LinuxSamplerException(msg);              throw Exception(msg);
241          }          }
242    
243          this->AudioDeviceChannelLeft  = 0;          this->MaxSamplesPerCycle = pAudioOutputDevice->MaxSamplesPerCycle();
244          this->AudioDeviceChannelRight = 1;          this->SampleRate         = pAudioOutputDevice->SampleRate();
245          this->pOutputLeft             = pAudioOutputDevice->Channel(0)->Buffer();  
246          this->pOutputRight            = pAudioOutputDevice->Channel(1)->Buffer();          // FIXME: audio drivers with varying fragment sizes might be a problem here
247          this->MaxSamplesPerCycle      = pAudioOutputDevice->MaxSamplesPerCycle();          MaxFadeOutPos = MaxSamplesPerCycle - int(double(SampleRate) * CONFIG_EG_MIN_RELEASE_TIME) - 1;
248          this->SampleRate              = pAudioOutputDevice->SampleRate();          if (MaxFadeOutPos < 0) {
249                std::cerr << "gig::Engine: WARNING, CONFIG_EG_MIN_RELEASE_TIME "
250                          << "too big for current audio fragment size & sampling rate! "
251                          << "May lead to click sounds if voice stealing chimes in!\n" << std::flush;
252                // force volume ramp downs at the beginning of each fragment
253                MaxFadeOutPos = 0;
254                // lower minimum release time
255                const float minReleaseTime = (float) MaxSamplesPerCycle / (float) SampleRate;
256                for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
257                    iterVoice->EG1.CalculateFadeOutCoeff(minReleaseTime, SampleRate);
258                }
259                pVoicePool->clear();
260            }
261    
262          // (re)create disk thread          // (re)create disk thread
263          if (this->pDiskThread) {          if (this->pDiskThread) {
264                dmsg(1,("Stopping disk thread..."));
265              this->pDiskThread->StopThread();              this->pDiskThread->StopThread();
266              delete this->pDiskThread;              delete this->pDiskThread;
267                dmsg(1,("OK\n"));
268          }          }
269          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
270                                               &instruments);
271          if (!pDiskThread) {          if (!pDiskThread) {
272              dmsg(0,("gig::Engine  new diskthread = NULL\n"));              dmsg(0,("gig::Engine  new diskthread = NULL\n"));
273              exit(EXIT_FAILURE);              exit(EXIT_FAILURE);
274          }          }
275    
276          for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) {          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
277              pVoice->pDiskThread = this->pDiskThread;              iterVoice->pDiskThread = this->pDiskThread;
278              dmsg(3,("d"));              dmsg(3,("d"));
279          }          }
280          pVoicePool->clear();          pVoicePool->clear();
# Line 335  namespace LinuxSampler { namespace gig { Line 283  namespace LinuxSampler { namespace gig {
283          if (pEventGenerator) delete pEventGenerator;          if (pEventGenerator) delete pEventGenerator;
284          pEventGenerator = new EventGenerator(pAudioOut->SampleRate());          pEventGenerator = new EventGenerator(pAudioOut->SampleRate());
285    
         // (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()];  
   
286          dmsg(1,("Starting disk thread..."));          dmsg(1,("Starting disk thread..."));
287          pDiskThread->StartThread();          pDiskThread->StartThread();
288          dmsg(1,("OK\n"));          dmsg(1,("OK\n"));
289    
290          for (Voice* pVoice = pVoicePool->first(); pVoice; pVoice = pVoicePool->next()) {          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
291              if (!pVoice->pDiskThread) {              if (!iterVoice->pDiskThread) {
292                  dmsg(0,("Engine -> voice::trigger: !pDiskThread\n"));                  dmsg(0,("Engine -> voice::trigger: !pDiskThread\n"));
293                  exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
294              }              }
295          }          }
296      }      }
297    
298      void Engine::DisconnectAudioOutputDevice() {      /**
299          if (pAudioOutputDevice) { // if clause to prevent disconnect loops       * Clear all engine global event lists.
300              AudioOutputDevice* olddevice = pAudioOutputDevice;       */
301              pAudioOutputDevice = NULL;      void Engine::ClearEventLists() {
302              olddevice->Disconnect(this);          pGlobalEvents->clear();
303              AudioDeviceChannelLeft  = -1;      }
304              AudioDeviceChannelRight = -1;  
305        /**
306         * Copy all events from the engine's global input queue buffer to the
307         * engine's internal event list. This will be done at the beginning of
308         * each audio cycle (that is each RenderAudio() call) to distinguish
309         * all global events which have to be processed in the current audio
310         * cycle. These events are usually just SysEx messages. Every
311         * EngineChannel has it's own input event queue buffer and event list
312         * to handle common events like NoteOn, NoteOff and ControlChange
313         * events.
314         *
315         * @param Samples - number of sample points to be processed in the
316         *                  current audio cycle
317         */
318        void Engine::ImportEvents(uint Samples) {
319            RingBuffer<Event,false>::NonVolatileReader eventQueueReader = pEventQueue->get_non_volatile_reader();
320            Event* pEvent;
321            while (true) {
322                // get next event from input event queue
323                if (!(pEvent = eventQueueReader.pop())) break;
324                // if younger event reached, ignore that and all subsequent ones for now
325                if (pEvent->FragmentPos() >= Samples) {
326                    eventQueueReader--;
327                    dmsg(2,("Younger Event, pos=%d ,Samples=%d!\n",pEvent->FragmentPos(),Samples));
328                    pEvent->ResetFragmentPos();
329                    break;
330                }
331                // copy event to internal event list
332                if (pGlobalEvents->poolIsEmpty()) {
333                    dmsg(1,("Event pool emtpy!\n"));
334                    break;
335                }
336                *pGlobalEvents->allocAppend() = *pEvent;
337          }          }
338            eventQueueReader.free(); // free all copied events from input queue
339      }      }
340    
341      /**      /**
342       *  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.
343       *  calculated audio data of all voices of this engine will be placed into       * The engine will iterate through all engine channels and render audio
344       *  the engine's audio sum buffer which has to be copied and eventually be       * for each engine channel independently. The calculated audio data of
345       *  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
346       *  AlsaIO or JackIO) right after.       * buffers of the respective audio output device, connected to the
347         * respective engine channel.
348       *       *
349       *  @param Samples - number of sample points to be rendered       *  @param Samples - number of sample points to be rendered
350       *  @returns       0 on success       *  @returns       0 on success
351       */       */
352      int Engine::RenderAudio(uint Samples) {      int Engine::RenderAudio(uint Samples) {
353          dmsg(5,("RenderAudio(Samples=%d)\n", Samples));          dmsg(7,("RenderAudio(Samples=%d)\n", Samples));
354    
355          // return if no instrument loaded or engine disabled          // return if engine disabled
356          if (EngineDisabled.Pop()) {          if (EngineDisabled.Pop()) {
357              dmsg(5,("gig::Engine: engine disabled (val=%d)\n",EngineDisabled.GetUnsafe()));              dmsg(5,("gig::Engine: engine disabled (val=%d)\n",EngineDisabled.GetUnsafe()));
358              return 0;              return 0;
359          }          }
         if (!pInstrument) {  
             dmsg(5,("gig::Engine: no instrument loaded\n"));  
             return 0;  
         }  
360    
361            // update time of start and end of this audio fragment (as events' time stamps relate to this)
362            pEventGenerator->UpdateFragmentTime(Samples);
363    
364          // empty the event lists for the new fragment          // We only allow a maximum of CONFIG_MAX_VOICES voices to be spawned
365          pEvents->clear();          // in each audio fragment. All subsequent request for spawning new
366          pCCEvents->clear();          // voices in the same audio fragment will be ignored.
367          for (uint i = 0; i < Event::destination_count; i++) {          VoiceSpawnsLeft = CONFIG_MAX_VOICES;
368              pSynthesisEvents[i]->clear();  
369          }          // get all events from the engine's global input event queue which belong to the current fragment
370          for (uint* puiKey = pActiveKeys->first(); puiKey; puiKey = pActiveKeys->next()) {          // (these are usually just SysEx messages)
371              midi_key_info_t* pKey = &pMIDIKeyInfo[*puiKey];          ImportEvents(Samples);
372              pKey->pEvents->clear(); // free all events on the key  
373            // process engine global events (these are currently only MIDI System Exclusive messages)
374            {
375                RTList<Event>::Iterator itEvent = pGlobalEvents->first();
376                RTList<Event>::Iterator end     = pGlobalEvents->end();
377                for (; itEvent != end; ++itEvent) {
378                    switch (itEvent->Type) {
379                        case Event::type_sysex:
380                            dmsg(5,("Engine: Sysex received\n"));
381                            ProcessSysex(itEvent);
382                            break;
383                    }
384                }
385          }          }
386    
387          // read and copy events from input queue          // reset internal voice counter (just for statistic of active voices)
388          Event event = pEventGenerator->CreateEvent();          ActiveVoiceCountTemp = 0;
         while (true) {  
             if (!pEventQueue->pop(&event)) break;  
             pEvents->alloc_assign(event);  
         }  
389    
390            // handle instrument change commands
391            instrument_change_command_t command;
392            if (InstrumentChangeQueue->pop(&command) > 0) {
393                EngineChannel* pEngineChannel = command.pEngineChannel;
394                pEngineChannel->pInstrument = command.pInstrument;
395    
396                // iterate through all active voices and mark their
397                // dimension regions as "in use". The instrument resource
398                // manager may delete all of the instrument except the
399                // dimension regions and samples that are in use.
400                int i = 0;
401                RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
402                RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
403                while (iuiKey != end) { // iterate through all active keys
404                    midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
405                    ++iuiKey;
406    
407                    RTList<Voice>::Iterator itVoice     = pKey->pActiveVoices->first();
408                    RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
409                    for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
410                        if (!itVoice->Orphan) {
411                            itVoice->Orphan = true;
412                            pDimRegionsInUse[i++] = itVoice->pDimRgn;
413                        }
414                    }
415                }
416                pDimRegionsInUse[i] = 0; // end of list
417    
418          // update time of start and end of this audio fragment (as events' time stamps relate to this)              // send a reply to the calling thread, which is waiting
419          pEventGenerator->UpdateFragmentTime(Samples);              instrument_change_reply_t reply;
420                InstrumentChangeReplyQueue->push(&reply);
421            }
422    
423            // handle events on all engine channels
424            for (int i = 0; i < engineChannels.size(); i++) {
425                ProcessEvents(engineChannels[i], Samples);
426            }
427    
428          // process events          // render all 'normal', active voices on all engine channels
429          Event* pNextEvent = pEvents->first();          for (int i = 0; i < engineChannels.size(); i++) {
430          while (pNextEvent) {              RenderActiveVoices(engineChannels[i], Samples);
             Event* pEvent = pNextEvent;  
             pEvents->set_current(pEvent);  
             pNextEvent = pEvents->next();  
             switch (pEvent->Type) {  
                 case Event::type_note_on:  
                     dmsg(5,("Engine: Note on received\n"));  
                     ProcessNoteOn(pEvent);  
                     break;  
                 case Event::type_note_off:  
                     dmsg(5,("Engine: Note off received\n"));  
                     ProcessNoteOff(pEvent);  
                     break;  
                 case Event::type_control_change:  
                     dmsg(5,("Engine: MIDI CC received\n"));  
                     ProcessControlChange(pEvent);  
                     break;  
                 case Event::type_pitchbend:  
                     dmsg(5,("Engine: Pitchbend received\n"));  
                     ProcessPitchbend(pEvent);  
                     break;  
                 case Event::type_sysex:  
                     dmsg(5,("Engine: Sysex received\n"));  
                     ProcessSysex(pEvent);  
                     break;  
             }  
431          }          }
432    
433            // now that all ordinary voices on ALL engine channels are rendered, render new stolen voices
434            RenderStolenVoices(Samples);
435    
436          // render audio from all active voices          // handle audio routing for engine channels with FX sends
437          int active_voices = 0;          for (int i = 0; i < engineChannels.size(); i++) {
438          uint* piKey = pActiveKeys->first();              if (engineChannels[i]->fxSends.empty()) continue; // ignore if no FX sends
439          while (piKey) { // iterate through all active keys              RouteAudio(engineChannels[i], Samples);
440              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();  
441    
442                  // now render current voice          // handle cleanup on all engine channels for the next audio fragment
443                  pVoice->Render(Samples);          for (int i = 0; i < engineChannels.size(); i++) {
444                  if (pVoice->IsActive()) active_voices++; // still active              PostProcess(engineChannels[i]);
                 else { // voice reached end, is now inactive  
                     KillVoiceImmediately(pVoice); // remove voice from the list of active voices  
                 }  
             }  
445          }          }
446    
447    
448          // now render all postponed voices from voice stealing          // empty the engine's event list for the next audio fragment
449          Event* pVoiceStealEvent = pVoiceStealingQueue->first();          ClearEventLists();
         while (pVoiceStealEvent) {  
             Voice* pNewVoice = LaunchVoice(pVoiceStealEvent, pVoiceStealEvent->Param.Note.Layer, pVoiceStealEvent->Param.Note.ReleaseTrigger, false);  
             if (pNewVoice) {  
                 pNewVoice->Render(Samples);  
                 if (pNewVoice->IsActive()) active_voices++; // still active  
                 else { // voice reached end, is now inactive  
                     KillVoiceImmediately(pNewVoice); // remove voice from the list of active voices  
                 }  
             }  
             else dmsg(1,("Ouch, voice stealing didn't work out!\n"));  
             pVoiceStealEvent = pVoiceStealingQueue->next();  
         }  
         // reset voice stealing for the new fragment  
         pVoiceStealingQueue->clear();  
         pLastStolenVoice = NULL;  
         puiLastStolenKey = NULL;  
450    
451            // reset voice stealing for the next audio fragment
452            pVoiceStealingQueue->clear();
453    
454          // write that to the disk thread class so that it can print it          // just some statistics about this engine instance
455          // on the console for debugging purposes          ActiveVoiceCount = ActiveVoiceCountTemp;
         ActiveVoiceCount = active_voices;  
456          if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;          if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;
457    
458            FrameTime += Samples;
459    
460          return 0;          return 0;
461      }      }
462    
463      /**      /**
464       *  Will be called by the MIDIIn Thread to let the audio thread trigger a new       * Dispatch and handle all events in this audio fragment for the given
465       *  voice for the given key.       * engine channel.
466       *       *
467       *  @param Key      - MIDI key number of the triggered key       * @param pEngineChannel - engine channel on which events should be
468       *  @param Velocity - MIDI velocity value of the triggered key       *                         processed
469       */       * @param Samples        - amount of sample points to be processed in
470      void Engine::SendNoteOn(uint8_t Key, uint8_t Velocity) {       *                         this audio fragment cycle
471          Event event               = pEventGenerator->CreateEvent();       */
472          event.Type                = Event::type_note_on;      void Engine::ProcessEvents(EngineChannel* pEngineChannel, uint Samples) {
473          event.Param.Note.Key      = Key;          // get all events from the engine channels's input event queue which belong to the current fragment
474          event.Param.Note.Velocity = Velocity;          // (these are the common events like NoteOn, NoteOff, ControlChange, etc.)
475          if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);          pEngineChannel->ImportEvents(Samples);
476          else dmsg(1,("Engine: Input event queue full!"));  
477            // process events
478            {
479                RTList<Event>::Iterator itEvent = pEngineChannel->pEvents->first();
480                RTList<Event>::Iterator end     = pEngineChannel->pEvents->end();
481                for (; itEvent != end; ++itEvent) {
482                    switch (itEvent->Type) {
483                        case Event::type_note_on:
484                            dmsg(5,("Engine: Note on received\n"));
485                            ProcessNoteOn((EngineChannel*)itEvent->pEngineChannel, itEvent);
486                            break;
487                        case Event::type_note_off:
488                            dmsg(5,("Engine: Note off received\n"));
489                            ProcessNoteOff((EngineChannel*)itEvent->pEngineChannel, itEvent);
490                            break;
491                        case Event::type_control_change:
492                            dmsg(5,("Engine: MIDI CC received\n"));
493                            ProcessControlChange((EngineChannel*)itEvent->pEngineChannel, itEvent);
494                            break;
495                        case Event::type_pitchbend:
496                            dmsg(5,("Engine: Pitchbend received\n"));
497                            ProcessPitchbend((EngineChannel*)itEvent->pEngineChannel, itEvent);
498                            break;
499                    }
500                }
501            }
502    
503            // reset voice stealing for the next engine channel (or next audio fragment)
504            itLastStolenVoice         = RTList<Voice>::Iterator();
505            itLastStolenVoiceGlobally = RTList<Voice>::Iterator();
506            iuiLastStolenKey          = RTList<uint>::Iterator();
507            iuiLastStolenKeyGlobally  = RTList<uint>::Iterator();
508            pLastStolenChannel        = NULL;
509      }      }
510    
511      /**      /**
512       *  Will be called by the MIDIIn Thread to signal the audio thread to release       * Render all 'normal' voices (that is voices which were not stolen in
513       *  voice(s) on the given key.       * this fragment) on the given engine channel.
514       *       *
515       *  @param Key      - MIDI key number of the released key       * @param pEngineChannel - engine channel on which audio should be
516       *  @param Velocity - MIDI release velocity value of the released key       *                         rendered
517       */       * @param Samples        - amount of sample points to be rendered in
518      void Engine::SendNoteOff(uint8_t Key, uint8_t Velocity) {       *                         this audio fragment cycle
519          Event event               = pEventGenerator->CreateEvent();       */
520          event.Type                = Event::type_note_off;      void Engine::RenderActiveVoices(EngineChannel* pEngineChannel, uint Samples) {
521          event.Param.Note.Key      = Key;          #if !CONFIG_PROCESS_MUTED_CHANNELS
522          event.Param.Note.Velocity = Velocity;          if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
523          if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);          #endif
524          else dmsg(1,("Engine: Input event queue full!"));  
525            RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
526            RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
527            while (iuiKey != end) { // iterate through all active keys
528                midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
529                ++iuiKey;
530    
531                RTList<Voice>::Iterator itVoice     = pKey->pActiveVoices->first();
532                RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
533                for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
534                    // now render current voice
535                    itVoice->Render(Samples);
536                    if (itVoice->IsActive()) ActiveVoiceCountTemp++; // still active
537                    else { // voice reached end, is now inactive
538                        FreeVoice(pEngineChannel, itVoice); // remove voice from the list of active voices
539                    }
540                }
541            }
542      }      }
543    
544      /**      /**
545       *  Will be called by the MIDIIn Thread to signal the audio thread to change       * Render all stolen voices (only voices which were stolen in this
546       *  the pitch value for all voices.       * fragment) on the given engine channel. Stolen voices are rendered
547         * after all normal voices have been rendered; this is needed to render
548         * audio of those voices which were selected for voice stealing until
549         * the point were the stealing (that is the take over of the voice)
550         * actually happened.
551       *       *
552       *  @param Pitch - MIDI pitch value (-8192 ... +8191)       * @param pEngineChannel - engine channel on which audio should be
553       */       *                         rendered
554      void Engine::SendPitchbend(int Pitch) {       * @param Samples        - amount of sample points to be rendered in
555          Event event             = pEventGenerator->CreateEvent();       *                         this audio fragment cycle
556          event.Type              = Event::type_pitchbend;       */
557          event.Param.Pitch.Pitch = Pitch;      void Engine::RenderStolenVoices(uint Samples) {
558          if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);          RTList<Event>::Iterator itVoiceStealEvent = pVoiceStealingQueue->first();
559          else dmsg(1,("Engine: Input event queue full!"));          RTList<Event>::Iterator end               = pVoiceStealingQueue->end();
560            for (; itVoiceStealEvent != end; ++itVoiceStealEvent) {
561                EngineChannel* pEngineChannel = (EngineChannel*) itVoiceStealEvent->pEngineChannel;
562                if (!pEngineChannel->pInstrument) continue; // ignore if no instrument loaded
563                Pool<Voice>::Iterator itNewVoice =
564                    LaunchVoice(pEngineChannel, itVoiceStealEvent, itVoiceStealEvent->Param.Note.Layer, itVoiceStealEvent->Param.Note.ReleaseTrigger, false, false);
565                if (itNewVoice) {
566                    itNewVoice->Render(Samples);
567                    if (itNewVoice->IsActive()) ActiveVoiceCountTemp++; // still active
568                    else { // voice reached end, is now inactive
569                        FreeVoice(pEngineChannel, itNewVoice); // remove voice from the list of active voices
570                    }
571                }
572                else dmsg(1,("gig::Engine: ERROR, voice stealing didn't work out!\n"));
573    
574                // we need to clear the key's event list explicitly here in case key was never active
575                midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoiceStealEvent->Param.Note.Key];
576                pKey->VoiceTheftsQueued--;
577                if (!pKey->Active && !pKey->VoiceTheftsQueued) pKey->pEvents->clear();
578            }
579      }      }
580    
581      /**      /**
582       *  Will be called by the MIDIIn Thread to signal the audio thread that a       * Will be called in case the respective engine channel sports FX send
583       *  continuous controller value has changed.       * channels. In this particular case, engine channel local buffers are
584         * used to render and mix all voices to. This method is responsible for
585         * copying the audio data from those local buffers to the master audio
586         * output channels as well as to the FX send audio output channels with
587         * their respective FX send levels.
588       *       *
589       *  @param Controller - MIDI controller number of the occured control change       * @param pEngineChannel - engine channel from which audio should be
590       *  @param Value      - value of the control change       *                         routed
591         * @param Samples        - amount of sample points to be routed in
592         *                         this audio fragment cycle
593         */
594        void Engine::RouteAudio(EngineChannel* pEngineChannel, uint Samples) {
595            // route master signal
596            {
597                AudioChannel* pDstL = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelLeft);
598                AudioChannel* pDstR = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelRight);
599                pEngineChannel->pChannelLeft->MixTo(pDstL, Samples);
600                pEngineChannel->pChannelRight->MixTo(pDstR, Samples);
601            }
602            // route FX send signal
603            {
604                for (int iFxSend = 0; iFxSend < pEngineChannel->GetFxSendCount(); iFxSend++) {
605                    FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
606                    // left channel
607                    const int iDstL = pFxSend->DestinationChannel(0);
608                    if (iDstL < 0) {
609                        dmsg(1,("Engine::RouteAudio() Error: invalid FX send (L) destination channel"));
610                    } else {
611                        AudioChannel* pDstL = pAudioOutputDevice->Channel(iDstL);
612                        if (!pDstL) {
613                            dmsg(1,("Engine::RouteAudio() Error: invalid FX send (L) destination channel"));
614                        } else pEngineChannel->pChannelLeft->MixTo(pDstL, Samples, pFxSend->Level());
615                    }
616                    // right channel
617                    const int iDstR = pFxSend->DestinationChannel(1);
618                    if (iDstR < 0) {
619                        dmsg(1,("Engine::RouteAudio() Error: invalid FX send (R) destination channel"));
620                    } else {
621                        AudioChannel* pDstR = pAudioOutputDevice->Channel(iDstR);
622                        if (!pDstR) {
623                            dmsg(1,("Engine::RouteAudio() Error: invalid FX send (R) destination channel"));
624                        } else pEngineChannel->pChannelRight->MixTo(pDstR, Samples, pFxSend->Level());
625                    }
626                }
627            }
628            // reset buffers with silence (zero out) for the next audio cycle
629            pEngineChannel->pChannelLeft->Clear();
630            pEngineChannel->pChannelRight->Clear();
631        }
632    
633        /**
634         * Free all keys which have turned inactive in this audio fragment, from
635         * the list of active keys and clear all event lists on that engine
636         * channel.
637         *
638         * @param pEngineChannel - engine channel to cleanup
639       */       */
640      void Engine::SendControlChange(uint8_t Controller, uint8_t Value) {      void Engine::PostProcess(EngineChannel* pEngineChannel) {
641          Event event               = pEventGenerator->CreateEvent();          // free all keys which have no active voices left
642          event.Type                = Event::type_control_change;          {
643          event.Param.CC.Controller = Controller;              RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
644          event.Param.CC.Value      = Value;              RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
645          if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              while (iuiKey != end) { // iterate through all active keys
646          else dmsg(1,("Engine: Input event queue full!"));                  midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
647                    ++iuiKey;
648                    if (pKey->pActiveVoices->isEmpty()) FreeKey(pEngineChannel, pKey);
649                    #if CONFIG_DEVMODE
650                    else { // just a sanity check for debugging
651                        RTList<Voice>::Iterator itVoice     = pKey->pActiveVoices->first();
652                        RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
653                        for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
654                            if (itVoice->itKillEvent) {
655                                dmsg(1,("gig::Engine: ERROR, killed voice survived !!!\n"));
656                            }
657                        }
658                    }
659                    #endif // CONFIG_DEVMODE
660                }
661            }
662    
663            // empty the engine channel's own event lists
664            pEngineChannel->ClearEventLists();
665      }      }
666    
667      /**      /**
# Line 574  namespace LinuxSampler { namespace gig { Line 675  namespace LinuxSampler { namespace gig {
675          Event event             = pEventGenerator->CreateEvent();          Event event             = pEventGenerator->CreateEvent();
676          event.Type              = Event::type_sysex;          event.Type              = Event::type_sysex;
677          event.Param.Sysex.Size  = Size;          event.Param.Sysex.Size  = Size;
678            event.pEngineChannel    = NULL; // as Engine global event
679          if (pEventQueue->write_space() > 0) {          if (pEventQueue->write_space() > 0) {
680              if (pSysexBuffer->write_space() >= Size) {              if (pSysexBuffer->write_space() >= Size) {
681                  // copy sysex data to input buffer                  // copy sysex data to input buffer
# Line 589  namespace LinuxSampler { namespace gig { Line 691  namespace LinuxSampler { namespace gig {
691                  // finally place sysex event into input event queue                  // finally place sysex event into input event queue
692                  pEventQueue->push(&event);                  pEventQueue->push(&event);
693              }              }
694              else dmsg(1,("Engine: Sysex message too large (%d byte) for input buffer (%d byte)!",Size,SYSEX_BUFFER_SIZE));              else dmsg(1,("Engine: Sysex message too large (%d byte) for input buffer (%d byte)!",Size,CONFIG_SYSEX_BUFFER_SIZE));
695          }          }
696          else dmsg(1,("Engine: Input event queue full!"));          else dmsg(1,("Engine: Input event queue full!"));
697      }      }
# Line 597  namespace LinuxSampler { namespace gig { Line 699  namespace LinuxSampler { namespace gig {
699      /**      /**
700       *  Assigns and triggers a new voice for the respective MIDI key.       *  Assigns and triggers a new voice for the respective MIDI key.
701       *       *
702       *  @param pNoteOnEvent - key, velocity and time stamp of the event       *  @param pEngineChannel - engine channel on which this event occured on
703         *  @param itNoteOnEvent - key, velocity and time stamp of the event
704       */       */
705      void Engine::ProcessNoteOn(Event* pNoteOnEvent) {      void Engine::ProcessNoteOn(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
706          midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Param.Note.Key];          #if !CONFIG_PROCESS_MUTED_CHANNELS
707            if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
708            #endif
709    
710            if (!pEngineChannel->pInstrument) return; // ignore if no instrument loaded
711    
712            //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
713            itNoteOnEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
714    
715            const int key = itNoteOnEvent->Param.Note.Key;
716            midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key];
717    
718            // move note on event to the key's own event list
719            RTList<Event>::Iterator itNoteOnEventOnKeyList = itNoteOnEvent.moveToEndOf(pKey->pEvents);
720    
721            // if Solo Mode then kill all already active voices
722            if (pEngineChannel->SoloMode) {
723                Pool<uint>::Iterator itYoungestKey = pEngineChannel->pActiveKeys->last();
724                if (itYoungestKey) {
725                    const int iYoungestKey = *itYoungestKey;
726                    const midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[iYoungestKey];
727                    if (pOtherKey->Active) {
728                        // get final portamento position of currently active voice
729                        if (pEngineChannel->PortamentoMode) {
730                            RTList<Voice>::Iterator itVoice = pOtherKey->pActiveVoices->last();
731                            if (itVoice) itVoice->UpdatePortamentoPos(itNoteOnEventOnKeyList);
732                        }
733                        // kill all voices on the (other) key
734                        RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
735                        RTList<Voice>::Iterator end               = pOtherKey->pActiveVoices->end();
736                        for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
737                            if (itVoiceToBeKilled->Type != Voice::type_release_trigger)
738                                itVoiceToBeKilled->Kill(itNoteOnEventOnKeyList);
739                        }
740                    }
741                }
742                // set this key as 'currently active solo key'
743                pEngineChannel->SoloKey = key;
744            }
745    
746            // Change key dimension value if key is in keyswitching area
747            {
748                const ::gig::Instrument* pInstrument = pEngineChannel->pInstrument;
749                if (key >= pInstrument->DimensionKeyRange.low && key <= pInstrument->DimensionKeyRange.high)
750                    pEngineChannel->CurrentKeyDimension = float(key - pInstrument->DimensionKeyRange.low) /
751                        (pInstrument->DimensionKeyRange.high - pInstrument->DimensionKeyRange.low + 1);
752            }
753    
754          pKey->KeyPressed = true; // the MIDI key was now pressed down          pKey->KeyPressed = true; // the MIDI key was now pressed down
755            pKey->Velocity   = itNoteOnEventOnKeyList->Param.Note.Velocity;
756            pKey->NoteOnTime = FrameTime + itNoteOnEventOnKeyList->FragmentPos(); // will be used to calculate note length
757    
758          // cancel release process of voices on this key if needed          // cancel release process of voices on this key if needed
759          if (pKey->Active && !SustainPedal) {          if (pKey->Active && !pEngineChannel->SustainPedal) {
760              Event* pCancelReleaseEvent = pKey->pEvents->alloc();              RTList<Event>::Iterator itCancelReleaseEvent = pKey->pEvents->allocAppend();
761              if (pCancelReleaseEvent) {              if (itCancelReleaseEvent) {
762                  *pCancelReleaseEvent = *pNoteOnEvent;                  *itCancelReleaseEvent = *itNoteOnEventOnKeyList;         // copy event
763                  pCancelReleaseEvent->Type = Event::type_cancel_release; // transform event type                  itCancelReleaseEvent->Type = Event::type_cancel_release; // transform event type
764              }              }
765              else dmsg(1,("Event pool emtpy!\n"));              else dmsg(1,("Event pool emtpy!\n"));
766          }          }
767    
768          // allocate and trigger a new voice for the key          // allocate and trigger new voice(s) for the key
769          LaunchVoice(pNoteOnEvent);          {
770                // first, get total amount of required voices (dependant on amount of layers)
771                ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOnEventOnKeyList->Param.Note.Key);
772                if (pRegion) {
773                    int voicesRequired = pRegion->Layers;
774                    // now launch the required amount of voices
775                    for (int i = 0; i < voicesRequired; i++)
776                        LaunchVoice(pEngineChannel, itNoteOnEventOnKeyList, i, false, true, true);
777                }
778            }
779    
780            // if neither a voice was spawned or postponed then remove note on event from key again
781            if (!pKey->Active && !pKey->VoiceTheftsQueued)
782                pKey->pEvents->free(itNoteOnEventOnKeyList);
783    
784          // finally move note on event to the key's own event list          if (!pEngineChannel->SoloMode || pEngineChannel->PortamentoPos < 0.0f) pEngineChannel->PortamentoPos = (float) key;
785          pEvents->move(pNoteOnEvent, pKey->pEvents);          pKey->RoundRobinIndex++;
786      }      }
787    
788      /**      /**
# Line 627  namespace LinuxSampler { namespace gig { Line 791  namespace LinuxSampler { namespace gig {
791       *  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.
792       *  due to completion of sample playback).       *  due to completion of sample playback).
793       *       *
794       *  @param pNoteOffEvent - key, velocity and time stamp of the event       *  @param pEngineChannel - engine channel on which this event occured on
795         *  @param itNoteOffEvent - key, velocity and time stamp of the event
796       */       */
797      void Engine::ProcessNoteOff(Event* pNoteOffEvent) {      void Engine::ProcessNoteOff(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOffEvent) {
798          midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOffEvent->Param.Note.Key];          #if !CONFIG_PROCESS_MUTED_CHANNELS
799            if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
800            #endif
801    
802            //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
803            itNoteOffEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
804    
805            const int iKey = itNoteOffEvent->Param.Note.Key;
806            midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[iKey];
807          pKey->KeyPressed = false; // the MIDI key was now released          pKey->KeyPressed = false; // the MIDI key was now released
808    
809          // release voices on this key if needed          // move event to the key's own event list
810          if (pKey->Active && !SustainPedal) {          RTList<Event>::Iterator itNoteOffEventOnKeyList = itNoteOffEvent.moveToEndOf(pKey->pEvents);
811              pNoteOffEvent->Type = Event::type_release; // transform event type  
812            bool bShouldRelease = pKey->Active && ShouldReleaseVoice(pEngineChannel, itNoteOffEventOnKeyList->Param.Note.Key);
813    
814            // in case Solo Mode is enabled, kill all voices on this key and respawn a voice on the highest pressed key (if any)
815            if (pEngineChannel->SoloMode && pEngineChannel->pInstrument) { //TODO: this feels like too much code just for handling solo mode :P
816                bool bOtherKeysPressed = false;
817                if (iKey == pEngineChannel->SoloKey) {
818                    pEngineChannel->SoloKey = -1;
819                    // if there's still a key pressed down, respawn a voice (group) on the highest key
820                    for (int i = 127; i > 0; i--) {
821                        midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[i];
822                        if (pOtherKey->KeyPressed) {
823                            bOtherKeysPressed = true;
824                            // make the other key the new 'currently active solo key'
825                            pEngineChannel->SoloKey = i;
826                            // get final portamento position of currently active voice
827                            if (pEngineChannel->PortamentoMode) {
828                                RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
829                                if (itVoice) itVoice->UpdatePortamentoPos(itNoteOffEventOnKeyList);
830                            }
831                            // create a pseudo note on event
832                            RTList<Event>::Iterator itPseudoNoteOnEvent = pOtherKey->pEvents->allocAppend();
833                            if (itPseudoNoteOnEvent) {
834                                // copy event
835                                *itPseudoNoteOnEvent = *itNoteOffEventOnKeyList;
836                                // transform event to a note on event
837                                itPseudoNoteOnEvent->Type                = Event::type_note_on;
838                                itPseudoNoteOnEvent->Param.Note.Key      = i;
839                                itPseudoNoteOnEvent->Param.Note.Velocity = pOtherKey->Velocity;
840                                // allocate and trigger new voice(s) for the other key
841                                {
842                                    // first, get total amount of required voices (dependant on amount of layers)
843                                    ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(i);
844                                    if (pRegion) {
845                                        int voicesRequired = pRegion->Layers;
846                                        // now launch the required amount of voices
847                                        for (int iLayer = 0; iLayer < voicesRequired; iLayer++)
848                                            LaunchVoice(pEngineChannel, itPseudoNoteOnEvent, iLayer, false, true, false);
849                                    }
850                                }
851                                // if neither a voice was spawned or postponed then remove note on event from key again
852                                if (!pOtherKey->Active && !pOtherKey->VoiceTheftsQueued)
853                                    pOtherKey->pEvents->free(itPseudoNoteOnEvent);
854    
855                            } else dmsg(1,("Could not respawn voice, no free event left\n"));
856                            break; // done
857                        }
858                    }
859                }
860                if (bOtherKeysPressed) {
861                    if (pKey->Active) { // kill all voices on this key
862                        bShouldRelease = false; // no need to release, as we kill it here
863                        RTList<Voice>::Iterator itVoiceToBeKilled = pKey->pActiveVoices->first();
864                        RTList<Voice>::Iterator end               = pKey->pActiveVoices->end();
865                        for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
866                            if (itVoiceToBeKilled->Type != Voice::type_release_trigger)
867                                itVoiceToBeKilled->Kill(itNoteOffEventOnKeyList);
868                        }
869                    }
870                } else pEngineChannel->PortamentoPos = -1.0f;
871          }          }
872    
873          // spawn release triggered voice(s) if needed          // if no solo mode (the usual case) or if solo mode and no other key pressed, then release voices on this key if needed
874          if (pKey->ReleaseTrigger) {          if (bShouldRelease) {
875              LaunchVoice(pNoteOffEvent, 0, true);              itNoteOffEventOnKeyList->Type = Event::type_release; // transform event type
876              pKey->ReleaseTrigger = false;  
877                // spawn release triggered voice(s) if needed
878                if (pKey->ReleaseTrigger && pEngineChannel->pInstrument) {
879                    // first, get total amount of required voices (dependant on amount of layers)
880                    ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key);
881                    if (pRegion) {
882                        int voicesRequired = pRegion->Layers;
883    
884                        // MIDI note-on velocity is used instead of note-off velocity
885                        itNoteOffEventOnKeyList->Param.Note.Velocity = pKey->Velocity;
886    
887                        // now launch the required amount of voices
888                        for (int i = 0; i < voicesRequired; i++)
889                            LaunchVoice(pEngineChannel, itNoteOffEventOnKeyList, i, true, false, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples
890                    }
891                    pKey->ReleaseTrigger = false;
892                }
893          }          }
894    
895          // move event to the key's own event list          // if neither a voice was spawned or postponed on this key then remove note off event from key again
896          pEvents->move(pNoteOffEvent, pKey->pEvents);          if (!pKey->Active && !pKey->VoiceTheftsQueued)
897                pKey->pEvents->free(itNoteOffEventOnKeyList);
898      }      }
899    
900      /**      /**
901       *  Moves pitchbend event from the general (input) event list to the pitch       *  Moves pitchbend event from the general (input) event list to the engine
902       *  event list.       *  channel's event list. It will actually processed later by the
903         *  respective voice.
904       *       *
905       *  @param pPitchbendEvent - absolute pitch value and time stamp of the event       *  @param pEngineChannel - engine channel on which this event occured on
906         *  @param itPitchbendEvent - absolute pitch value and time stamp of the event
907       */       */
908      void Engine::ProcessPitchbend(Event* pPitchbendEvent) {      void Engine::ProcessPitchbend(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itPitchbendEvent) {
909          this->Pitch = pPitchbendEvent->Param.Pitch.Pitch; // store current pitch value          pEngineChannel->Pitch = itPitchbendEvent->Param.Pitch.Pitch; // store current pitch value
         pEvents->move(pPitchbendEvent, pSynthesisEvents[Event::destination_vco]);  
910      }      }
911    
912      /**      /**
# Line 665  namespace LinuxSampler { namespace gig { Line 914  namespace LinuxSampler { namespace gig {
914       *  called by the ProcessNoteOn() method and by the voices itself       *  called by the ProcessNoteOn() method and by the voices itself
915       *  (e.g. to spawn further voices on the same key for layered sounds).       *  (e.g. to spawn further voices on the same key for layered sounds).
916       *       *
917       *  @param pNoteOnEvent        - key, velocity and time stamp of the event       *  @param pEngineChannel      - engine channel on which this event occured on
918         *  @param itNoteOnEvent       - key, velocity and time stamp of the event
919       *  @param iLayer              - layer index for the new voice (optional - only       *  @param iLayer              - layer index for the new voice (optional - only
920       *                               in case of layered sounds of course)       *                               in case of layered sounds of course)
921       *  @param ReleaseTriggerVoice - if new voice is a release triggered voice       *  @param ReleaseTriggerVoice - if new voice is a release triggered voice
# Line 673  namespace LinuxSampler { namespace gig { Line 923  namespace LinuxSampler { namespace gig {
923       *  @param VoiceStealing       - if voice stealing should be performed       *  @param VoiceStealing       - if voice stealing should be performed
924       *                               when there is no free voice       *                               when there is no free voice
925       *                               (optional, default = true)       *                               (optional, default = true)
926         *  @param HandleKeyGroupConflicts - if voices should be killed due to a
927         *                                   key group conflict
928       *  @returns pointer to new voice or NULL if there was no free voice or       *  @returns pointer to new voice or NULL if there was no free voice or
929       *           if an error occured while trying to trigger the new voice       *           if the voice wasn't triggered (for example when no region is
930         *           defined for the given key).
931       */       */
932      Voice* Engine::LaunchVoice(Event* pNoteOnEvent, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) {      Pool<Voice>::Iterator Engine::LaunchVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing, bool HandleKeyGroupConflicts) {
933          midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Param.Note.Key];          int MIDIKey            = itNoteOnEvent->Param.Note.Key;
934            midi_key_info_t* pKey  = &pEngineChannel->pMIDIKeyInfo[MIDIKey];
935            ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(MIDIKey);
936    
937            // if nothing defined for this key
938            if (!pRegion) return Pool<Voice>::Iterator(); // nothing to do
939    
940            // only mark the first voice of a layered voice (group) to be in a
941            // key group, so the layered voices won't kill each other
942            int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;
943    
944            // handle key group (a.k.a. exclusive group) conflicts
945            if (HandleKeyGroupConflicts) {
946                if (iKeyGroup) { // if this voice / key belongs to a key group
947                    uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[iKeyGroup];
948                    if (*ppKeyGroup) { // if there's already an active key in that key group
949                        midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[**ppKeyGroup];
950                        // kill all voices on the (other) key
951                        RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
952                        RTList<Voice>::Iterator end               = pOtherKey->pActiveVoices->end();
953                        for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
954                            if (itVoiceToBeKilled->Type != Voice::type_release_trigger) {
955                                itVoiceToBeKilled->Kill(itNoteOnEvent);
956                                --VoiceSpawnsLeft; //FIXME: just a hack, we should better check in StealVoice() if the voice was killed due to key conflict
957                            }
958                        }
959                    }
960                }
961            }
962    
963            Voice::type_t VoiceType = Voice::type_normal;
964    
965            // get current dimension values to select the right dimension region
966            //TODO: for stolen voices this dimension region selection block is processed twice, this should be changed
967            //FIXME: controller values for selecting the dimension region here are currently not sample accurate
968            uint DimValues[8] = { 0 };
969            for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
970                switch (pRegion->pDimensionDefinitions[i].dimension) {
971                    case ::gig::dimension_samplechannel:
972                        DimValues[i] = 0; //TODO: we currently ignore this dimension
973                        break;
974                    case ::gig::dimension_layer:
975                        DimValues[i] = iLayer;
976                        break;
977                    case ::gig::dimension_velocity:
978                        DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
979                        break;
980                    case ::gig::dimension_channelaftertouch:
981                        DimValues[i] = pEngineChannel->ControllerTable[128];
982                        break;
983                    case ::gig::dimension_releasetrigger:
984                        VoiceType = (ReleaseTriggerVoice) ? Voice::type_release_trigger : (!iLayer) ? Voice::type_release_trigger_required : Voice::type_normal;
985                        DimValues[i] = (uint) ReleaseTriggerVoice;
986                        break;
987                    case ::gig::dimension_keyboard:
988                        DimValues[i] = (uint) (pEngineChannel->CurrentKeyDimension * pRegion->pDimensionDefinitions[i].zones);
989                        break;
990                    case ::gig::dimension_roundrobin:
991                        DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on
992                        break;
993                    case ::gig::dimension_random:
994                        RandomSeed   = RandomSeed * 1103515245 + 12345; // classic pseudo random number generator
995                        DimValues[i] = (uint) RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random
996                        break;
997                    case ::gig::dimension_modwheel:
998                        DimValues[i] = pEngineChannel->ControllerTable[1];
999                        break;
1000                    case ::gig::dimension_breath:
1001                        DimValues[i] = pEngineChannel->ControllerTable[2];
1002                        break;
1003                    case ::gig::dimension_foot:
1004                        DimValues[i] = pEngineChannel->ControllerTable[4];
1005                        break;
1006                    case ::gig::dimension_portamentotime:
1007                        DimValues[i] = pEngineChannel->ControllerTable[5];
1008                        break;
1009                    case ::gig::dimension_effect1:
1010                        DimValues[i] = pEngineChannel->ControllerTable[12];
1011                        break;
1012                    case ::gig::dimension_effect2:
1013                        DimValues[i] = pEngineChannel->ControllerTable[13];
1014                        break;
1015                    case ::gig::dimension_genpurpose1:
1016                        DimValues[i] = pEngineChannel->ControllerTable[16];
1017                        break;
1018                    case ::gig::dimension_genpurpose2:
1019                        DimValues[i] = pEngineChannel->ControllerTable[17];
1020                        break;
1021                    case ::gig::dimension_genpurpose3:
1022                        DimValues[i] = pEngineChannel->ControllerTable[18];
1023                        break;
1024                    case ::gig::dimension_genpurpose4:
1025                        DimValues[i] = pEngineChannel->ControllerTable[19];
1026                        break;
1027                    case ::gig::dimension_sustainpedal:
1028                        DimValues[i] = pEngineChannel->ControllerTable[64];
1029                        break;
1030                    case ::gig::dimension_portamento:
1031                        DimValues[i] = pEngineChannel->ControllerTable[65];
1032                        break;
1033                    case ::gig::dimension_sostenutopedal:
1034                        DimValues[i] = pEngineChannel->ControllerTable[66];
1035                        break;
1036                    case ::gig::dimension_softpedal:
1037                        DimValues[i] = pEngineChannel->ControllerTable[67];
1038                        break;
1039                    case ::gig::dimension_genpurpose5:
1040                        DimValues[i] = pEngineChannel->ControllerTable[80];
1041                        break;
1042                    case ::gig::dimension_genpurpose6:
1043                        DimValues[i] = pEngineChannel->ControllerTable[81];
1044                        break;
1045                    case ::gig::dimension_genpurpose7:
1046                        DimValues[i] = pEngineChannel->ControllerTable[82];
1047                        break;
1048                    case ::gig::dimension_genpurpose8:
1049                        DimValues[i] = pEngineChannel->ControllerTable[83];
1050                        break;
1051                    case ::gig::dimension_effect1depth:
1052                        DimValues[i] = pEngineChannel->ControllerTable[91];
1053                        break;
1054                    case ::gig::dimension_effect2depth:
1055                        DimValues[i] = pEngineChannel->ControllerTable[92];
1056                        break;
1057                    case ::gig::dimension_effect3depth:
1058                        DimValues[i] = pEngineChannel->ControllerTable[93];
1059                        break;
1060                    case ::gig::dimension_effect4depth:
1061                        DimValues[i] = pEngineChannel->ControllerTable[94];
1062                        break;
1063                    case ::gig::dimension_effect5depth:
1064                        DimValues[i] = pEngineChannel->ControllerTable[95];
1065                        break;
1066                    case ::gig::dimension_none:
1067                        std::cerr << "gig::Engine::LaunchVoice() Error: dimension=none\n" << std::flush;
1068                        break;
1069                    default:
1070                        std::cerr << "gig::Engine::LaunchVoice() Error: Unknown dimension\n" << std::flush;
1071                }
1072            }
1073    
1074            // return if this is a release triggered voice and there is no
1075            // releasetrigger dimension (could happen if an instrument
1076            // change has occured between note on and off)
1077            if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
1078    
1079            ::gig::DimensionRegion* pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
1080    
1081            // no need to continue if sample is silent
1082            if (!pDimRgn->pSample || !pDimRgn->pSample->SamplesTotal) return Pool<Voice>::Iterator();
1083    
1084          // allocate a new voice for the key          // allocate a new voice for the key
1085          Voice* pNewVoice = pKey->pActiveVoices->alloc();          Pool<Voice>::Iterator itNewVoice = pKey->pActiveVoices->allocAppend();
1086          if (pNewVoice) {          if (itNewVoice) {
1087              // launch the new voice              // launch the new voice
1088              if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument, iLayer, ReleaseTriggerVoice) < 0) {              if (itNewVoice->Trigger(pEngineChannel, itNoteOnEvent, pEngineChannel->Pitch, pDimRgn, VoiceType, iKeyGroup) < 0) {
1089                  dmsg(1,("Triggering new voice failed!\n"));                  dmsg(4,("Voice not triggered\n"));
1090                  pKey->pActiveVoices->free(pNewVoice);                  pKey->pActiveVoices->free(itNewVoice);
1091              }              }
1092              else { // on success              else { // on success
1093                  uint** ppKeyGroup = NULL;                  --VoiceSpawnsLeft;
                 if (pNewVoice->KeyGroup) { // if this voice / key belongs to a key group  
                     ppKeyGroup = &ActiveKeyGroups[pNewVoice->KeyGroup];  
                     if (*ppKeyGroup) { // if there's already an active key in that key group  
                         midi_key_info_t* pOtherKey = &pMIDIKeyInfo[**ppKeyGroup];  
                         // kill all voices on the (other) key  
                         Voice* pVoiceToBeKilled = pOtherKey->pActiveVoices->first();  
                         while (pVoiceToBeKilled) {  
                             Voice* pVoiceToBeKilledNext = pOtherKey->pActiveVoices->next();  
                             if (pVoiceToBeKilled->Type != Voice::type_release_trigger) pVoiceToBeKilled->Kill(pNoteOnEvent);  
                             pOtherKey->pActiveVoices->set_current(pVoiceToBeKilled);  
                             pVoiceToBeKilled = pVoiceToBeKilledNext;  
                         }  
                     }  
                 }  
1094                  if (!pKey->Active) { // mark as active key                  if (!pKey->Active) { // mark as active key
1095                      pKey->Active = true;                      pKey->Active = true;
1096                      pKey->pSelf  = pActiveKeys->alloc();                      pKey->itSelf = pEngineChannel->pActiveKeys->allocAppend();
1097                      *pKey->pSelf = pNoteOnEvent->Param.Note.Key;                      *pKey->itSelf = itNoteOnEvent->Param.Note.Key;
1098                  }                  }
1099                  if (pNewVoice->KeyGroup) {                  if (itNewVoice->KeyGroup) {
1100                      *ppKeyGroup = pKey->pSelf; // put key as the (new) active key to its key group                      uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[itNewVoice->KeyGroup];
1101                        *ppKeyGroup = &*pKey->itSelf; // put key as the (new) active key to its key group
1102                  }                  }
1103                  if (pNewVoice->Type == Voice::type_release_trigger_required) pKey->ReleaseTrigger = true; // mark key for the need of release triggered voice(s)                  if (itNewVoice->Type == Voice::type_release_trigger_required) pKey->ReleaseTrigger = true; // mark key for the need of release triggered voice(s)
1104                  return pNewVoice; // success                  return itNewVoice; // success
1105                }
1106            }
1107            else if (VoiceStealing) {
1108                // try to steal one voice
1109                int result = StealVoice(pEngineChannel, itNoteOnEvent);
1110                if (!result) { // voice stolen successfully
1111                    // put note-on event into voice-stealing queue, so it will be reprocessed after killed voice died
1112                    RTList<Event>::Iterator itStealEvent = pVoiceStealingQueue->allocAppend();
1113                    if (itStealEvent) {
1114                        *itStealEvent = *itNoteOnEvent; // copy event
1115                        itStealEvent->Param.Note.Layer = iLayer;
1116                        itStealEvent->Param.Note.ReleaseTrigger = ReleaseTriggerVoice;
1117                        pKey->VoiceTheftsQueued++;
1118                    }
1119                    else dmsg(1,("Voice stealing queue full!\n"));
1120              }              }
1121          }          }
         else if (VoiceStealing) StealVoice(pNoteOnEvent, iLayer, ReleaseTriggerVoice); // no free voice left, so steal one  
1122    
1123          return NULL; // no free voice or error          return Pool<Voice>::Iterator(); // no free voice or error
1124      }      }
1125    
1126      /**      /**
# Line 726  namespace LinuxSampler { namespace gig { Line 1129  namespace LinuxSampler { namespace gig {
1129       *  voice stealing and postpone the note-on event until the selected       *  voice stealing and postpone the note-on event until the selected
1130       *  voice actually died.       *  voice actually died.
1131       *       *
1132       *  @param pNoteOnEvent        - key, velocity and time stamp of the event       *  @param pEngineChannel - engine channel on which this event occured on
1133       *  @param iLayer              - layer index for the new voice       *  @param itNoteOnEvent - key, velocity and time stamp of the event
1134       *  @param ReleaseTriggerVoice - if new voice is a release triggered voice       *  @returns 0 on success, a value < 0 if no active voice could be picked for voice stealing
1135       */       */
1136      void Engine::StealVoice(Event* pNoteOnEvent, int iLayer, bool ReleaseTriggerVoice) {      int Engine::StealVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
1137          if (!pEventPool->pool_is_empty()) {          if (VoiceSpawnsLeft <= 0) {
1138                dmsg(1,("Max. voice thefts per audio fragment reached (you may raise CONFIG_MAX_VOICES).\n"));
1139                return -1;
1140            }
1141            if (!pEventPool->poolIsEmpty()) {
1142    
1143              uint*  puiOldestKey;              RTList<Voice>::Iterator itSelectedVoice;
             Voice* pOldestVoice;  
1144    
1145              // Select one voice for voice stealing              // Select one voice for voice stealing
1146              switch (VOICE_STEAL_ALGORITHM) {              switch (CONFIG_VOICE_STEAL_ALGO) {
1147    
1148                  // try to pick the oldest voice on the key where the new                  // try to pick the oldest voice on the key where the new
1149                  // voice should be spawned, if there is no voice on that                  // voice should be spawned, if there is no voice on that
1150                  // key, or no voice left to kill there, then procceed with                  // key, or no voice left to kill, then procceed with
1151                  // 'oldestkey' algorithm                  // 'oldestkey' algorithm
1152                  case voice_steal_algo_keymask: {                  case voice_steal_algo_oldestvoiceonkey: {
1153                      midi_key_info_t* pOldestKey = &pMIDIKeyInfo[pNoteOnEvent->Param.Note.Key];                      midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key];
1154                      if (pLastStolenVoice) {                      itSelectedVoice = pSelectedKey->pActiveVoices->first();
1155                          pOldestKey->pActiveVoices->set_current(pLastStolenVoice);                      // proceed iterating if voice was created in this fragment cycle
1156                          pOldestVoice = pOldestKey->pActiveVoices->next();                      while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1157                      }                      // if we haven't found a voice then proceed with algorithm 'oldestkey'
1158                      else { // no voice stolen in this audio fragment cycle yet                      if (itSelectedVoice && itSelectedVoice->IsStealable()) break;
                         pOldestVoice = pOldestKey->pActiveVoices->first();  
                     }  
                     if (pOldestVoice) {  
                         puiOldestKey = pOldestKey->pSelf;  
                         break; // selection succeeded  
                     }  
1159                  } // no break - intentional !                  } // no break - intentional !
1160    
1161                  // try to pick the oldest voice on the oldest active key                  // try to pick the oldest voice on the oldest active key
1162                  // (caution: must stay after 'keymask' algorithm !)                  // from the same engine channel
1163                    // (caution: must stay after 'oldestvoiceonkey' algorithm !)
1164                  case voice_steal_algo_oldestkey: {                  case voice_steal_algo_oldestkey: {
1165                      if (pLastStolenVoice) {                      // if we already stole in this fragment, try to proceed on same key
1166                          midi_key_info_t* pOldestKey = &pMIDIKeyInfo[*puiLastStolenKey];                      if (this->itLastStolenVoice) {
1167                          pOldestKey->pActiveVoices->set_current(pLastStolenVoice);                          itSelectedVoice = this->itLastStolenVoice;
1168                          pOldestVoice = pOldestKey->pActiveVoices->next();                          do {
1169                          if (!pOldestVoice) {                              ++itSelectedVoice;
1170                              pActiveKeys->set_current(puiLastStolenKey);                          } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1171                              puiOldestKey = pActiveKeys->next();                          // found a "stealable" voice ?
1172                              if (puiOldestKey) {                          if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1173                                  midi_key_info_t* pOldestKey = &pMIDIKeyInfo[*puiOldestKey];                              // remember which voice we stole, so we can simply proceed on next voice stealing
1174                                  pOldestVoice = pOldestKey->pActiveVoices->first();                              this->itLastStolenVoice = itSelectedVoice;
1175                              }                              break; // selection succeeded
                             else { // too less voices, even for voice stealing  
                                 dmsg(1,("Voice overflow! - You might recompile with higher MAX_AUDIO_VOICES!\n"));  
                                 return;  
                             }  
1176                          }                          }
                         else puiOldestKey = puiLastStolenKey;  
1177                      }                      }
1178                      else { // no voice stolen in this audio fragment cycle yet                      // get (next) oldest key
1179                          puiOldestKey = pActiveKeys->first();                      RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKey) ? ++this->iuiLastStolenKey : pEngineChannel->pActiveKeys->first();
1180                          midi_key_info_t* pOldestKey = &pMIDIKeyInfo[*puiOldestKey];                      while (iuiSelectedKey) {
1181                          pOldestVoice = pOldestKey->pActiveVoices->first();                          midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[*iuiSelectedKey];
1182                            itSelectedVoice = pSelectedKey->pActiveVoices->first();
1183                            // proceed iterating if voice was created in this fragment cycle
1184                            while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1185                            // found a "stealable" voice ?
1186                            if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1187                                // remember which voice on which key we stole, so we can simply proceed on next voice stealing
1188                                this->iuiLastStolenKey  = iuiSelectedKey;
1189                                this->itLastStolenVoice = itSelectedVoice;
1190                                break; // selection succeeded
1191                            }
1192                            ++iuiSelectedKey; // get next oldest key
1193                      }                      }
1194                      break;                      break;
1195                  }                  }
# Line 791  namespace LinuxSampler { namespace gig { Line 1198  namespace LinuxSampler { namespace gig {
1198                  case voice_steal_algo_none:                  case voice_steal_algo_none:
1199                  default: {                  default: {
1200                      dmsg(1,("No free voice (voice stealing disabled)!\n"));                      dmsg(1,("No free voice (voice stealing disabled)!\n"));
1201                      return;                      return -1;
1202                  }                  }
1203              }              }
1204    
1205                // if we couldn't steal a voice from the same engine channel then
1206                // steal oldest voice on the oldest key from any other engine channel
1207                // (the smaller engine channel number, the higher priority)
1208                if (!itSelectedVoice || !itSelectedVoice->IsStealable()) {
1209                    EngineChannel* pSelectedChannel;
1210                    int            iChannelIndex;
1211                    // select engine channel
1212                    if (pLastStolenChannel) {
1213                        pSelectedChannel = pLastStolenChannel;
1214                        iChannelIndex    = pSelectedChannel->iEngineIndexSelf;
1215                    } else { // pick the engine channel followed by this engine channel
1216                        iChannelIndex    = (pEngineChannel->iEngineIndexSelf + 1) % engineChannels.size();
1217                        pSelectedChannel = engineChannels[iChannelIndex];
1218                    }
1219    
1220                    // if we already stole in this fragment, try to proceed on same key
1221                    if (this->itLastStolenVoiceGlobally) {
1222                        itSelectedVoice = this->itLastStolenVoiceGlobally;
1223                        do {
1224                            ++itSelectedVoice;
1225                        } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1226                    }
1227    
1228                    #if CONFIG_DEVMODE
1229                    EngineChannel* pBegin = pSelectedChannel; // to detect endless loop
1230                    #endif // CONFIG_DEVMODE
1231    
1232                    // did we find a 'stealable' voice?
1233                    if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1234                        // remember which voice we stole, so we can simply proceed on next voice stealing
1235                        this->itLastStolenVoiceGlobally = itSelectedVoice;
1236                    } else while (true) { // iterate through engine channels
1237                        // get (next) oldest key
1238                        RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKeyGlobally) ? ++this->iuiLastStolenKeyGlobally : pSelectedChannel->pActiveKeys->first();
1239                        this->iuiLastStolenKeyGlobally = RTList<uint>::Iterator(); // to prevent endless loop (see line above)
1240                        while (iuiSelectedKey) {
1241                            midi_key_info_t* pSelectedKey = &pSelectedChannel->pMIDIKeyInfo[*iuiSelectedKey];
1242                            itSelectedVoice = pSelectedKey->pActiveVoices->first();
1243                            // proceed iterating if voice was created in this fragment cycle
1244                            while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1245                            // found a "stealable" voice ?
1246                            if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1247                                // remember which voice on which key on which engine channel we stole, so we can simply proceed on next voice stealing
1248                                this->iuiLastStolenKeyGlobally  = iuiSelectedKey;
1249                                this->itLastStolenVoiceGlobally = itSelectedVoice;
1250                                this->pLastStolenChannel        = pSelectedChannel;
1251                                goto stealable_voice_found; // selection succeeded
1252                            }
1253                            ++iuiSelectedKey; // get next key on current engine channel
1254                        }
1255                        // get next engine channel
1256                        iChannelIndex    = (iChannelIndex + 1) % engineChannels.size();
1257                        pSelectedChannel = engineChannels[iChannelIndex];
1258    
1259                        #if CONFIG_DEVMODE
1260                        if (pSelectedChannel == pBegin) {
1261                            dmsg(1,("FATAL ERROR: voice stealing endless loop!\n"));
1262                            dmsg(1,("VoiceSpawnsLeft=%d.\n", VoiceSpawnsLeft));
1263                            dmsg(1,("Exiting.\n"));
1264                            exit(-1);
1265                        }
1266                        #endif // CONFIG_DEVMODE
1267                    }
1268                }
1269    
1270                // jump point if a 'stealable' voice was found
1271                stealable_voice_found:
1272    
1273                #if CONFIG_DEVMODE
1274                if (!itSelectedVoice->IsActive()) {
1275                    dmsg(1,("gig::Engine: ERROR, tried to steal a voice which was not active !!!\n"));
1276                    return -1;
1277                }
1278                #endif // CONFIG_DEVMODE
1279    
1280              // now kill the selected voice              // now kill the selected voice
1281              pOldestVoice->Kill(pNoteOnEvent);              itSelectedVoice->Kill(itNoteOnEvent);
1282              // remember which voice on which key we stole, so we can simply proceed for the next voice stealing  
1283              this->pLastStolenVoice = pOldestVoice;              --VoiceSpawnsLeft;
1284              this->puiLastStolenKey = puiOldestKey;  
1285              // put note-on event into voice-stealing queue, so it will be reprocessed after killed voice died              return 0; // success
1286              Event* pStealEvent = pVoiceStealingQueue->alloc();          }
1287              *pStealEvent = *pNoteOnEvent;          else {
1288              pStealEvent->Param.Note.Layer = iLayer;              dmsg(1,("Event pool emtpy!\n"));
1289              pStealEvent->Param.Note.ReleaseTrigger = ReleaseTriggerVoice;              return -1;
1290          }          }
         else dmsg(1,("Event pool emtpy!\n"));  
1291      }      }
1292    
1293      /**      /**
1294       *  Immediately kills the voice given with pVoice (no matter if sustain is       *  Removes the given voice from the MIDI key's list of active voices.
1295       *  pressed or not) and removes it from the MIDI key's list of active voice.       *  This method will be called when a voice went inactive, e.g. because
1296       *  This method will e.g. be called if a voice went inactive by itself.       *  it finished to playback its sample, finished its release stage or
1297         *  just was killed.
1298       *       *
1299       *  @param pVoice - points to the voice to be killed       *  @param pEngineChannel - engine channel on which this event occured on
1300         *  @param itVoice - points to the voice to be freed
1301       */       */
1302      void Engine::KillVoiceImmediately(Voice* pVoice) {      void Engine::FreeVoice(EngineChannel* pEngineChannel, Pool<Voice>::Iterator& itVoice) {
1303          if (pVoice) {          if (itVoice) {
1304              if (pVoice->IsActive()) pVoice->KillImmediately();              midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoice->MIDIKey];
1305    
1306              midi_key_info_t* pKey = &pMIDIKeyInfo[pVoice->MIDIKey];              uint keygroup = itVoice->KeyGroup;
1307    
1308                // if the sample and dimension region belong to an
1309                // instrument that is unloaded, tell the disk thread to
1310                // release them
1311                if (itVoice->Orphan) {
1312                    pDiskThread->OrderDeletionOfDimreg(itVoice->pDimRgn);
1313                }
1314    
1315              // free the voice object              // free the voice object
1316              pVoicePool->free(pVoice);              pVoicePool->free(itVoice);
1317    
1318              // 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
1319              if (pKey->pActiveVoices->is_empty()) {              if (pKey->pActiveVoices->isEmpty() && keygroup) {
1320                  if (pVoice->KeyGroup) { // if voice / key belongs to a key group                  uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[keygroup];
1321                      uint** ppKeyGroup = &ActiveKeyGroups[pVoice->KeyGroup];                  if (*ppKeyGroup == &*pKey->itSelf) *ppKeyGroup = NULL; // remove key from key group
                     if (*ppKeyGroup == pKey->pSelf) *ppKeyGroup = NULL; // remove key from key group  
                 }  
                 pKey->Active = false;  
                 pActiveKeys->free(pKey->pSelf); // remove key from list of active keys  
                 pKey->pSelf = NULL;  
                 pKey->ReleaseTrigger = false;  
                 pKey->pEvents->clear();  
                 dmsg(3,("Key has no more voices now\n"));  
1322              }              }
1323          }          }
1324          else std::cerr << "Couldn't release voice! (pVoice == NULL)\n" << std::flush;          else std::cerr << "Couldn't release voice! (!itVoice)\n" << std::flush;
1325        }
1326    
1327        /**
1328         *  Called when there's no more voice left on a key, this call will
1329         *  update the key info respectively.
1330         *
1331         *  @param pEngineChannel - engine channel on which this event occured on
1332         *  @param pKey - key which is now inactive
1333         */
1334        void Engine::FreeKey(EngineChannel* pEngineChannel, midi_key_info_t* pKey) {
1335            if (pKey->pActiveVoices->isEmpty()) {
1336                pKey->Active = false;
1337                pEngineChannel->pActiveKeys->free(pKey->itSelf); // remove key from list of active keys
1338                pKey->itSelf = RTList<uint>::Iterator();
1339                pKey->ReleaseTrigger = false;
1340                pKey->pEvents->clear();
1341                dmsg(3,("Key has no more voices now\n"));
1342            }
1343            else dmsg(1,("gig::Engine: Oops, tried to free a key which contains voices.\n"));
1344      }      }
1345    
1346      /**      /**
1347       *  Reacts on supported control change commands (e.g. pitch bend wheel,       *  Reacts on supported control change commands (e.g. pitch bend wheel,
1348       *  modulation wheel, aftertouch).       *  modulation wheel, aftertouch).
1349       *       *
1350       *  @param pControlChangeEvent - controller, value and time stamp of the event       *  @param pEngineChannel - engine channel on which this event occured on
1351         *  @param itControlChangeEvent - controller, value and time stamp of the event
1352       */       */
1353      void Engine::ProcessControlChange(Event* pControlChangeEvent) {      void Engine::ProcessControlChange(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itControlChangeEvent) {
1354          dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", pControlChangeEvent->Param.CC.Controller, pControlChangeEvent->Param.CC.Value));          dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));
1355    
1356            // update controller value in the engine channel's controller table
1357            pEngineChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;
1358    
1359          switch (pControlChangeEvent->Param.CC.Controller) {          // handle hard coded MIDI controllers
1360              case 64: {          switch (itControlChangeEvent->Param.CC.Controller) {
1361                  if (pControlChangeEvent->Param.CC.Value >= 64 && !SustainPedal) {              case 5: { // portamento time
1362                      dmsg(4,("PEDAL DOWN\n"));                  pEngineChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN;
1363                      SustainPedal = true;                  break;
1364                }
1365                case 6: { // data entry (currently only used for RPN controllers)
1366                    if (pEngineChannel->GetMidiRpnController() == 2) { // coarse tuning in half tones
1367                        int transpose = (int) itControlChangeEvent->Param.CC.Value - 64;
1368                        // limit to +- two octaves for now
1369                        transpose = RTMath::Min(transpose,  24);
1370                        transpose = RTMath::Max(transpose, -24);
1371                        pEngineChannel->GlobalTranspose = transpose;
1372                        // workaround, so we won't have hanging notes
1373                        ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1374                    }
1375                    break;
1376                }
1377                case 7: { // volume
1378                    //TODO: not sample accurate yet
1379                    pEngineChannel->MidiVolume = VolumeCurve[itControlChangeEvent->Param.CC.Value];
1380                    pEngineChannel->bStatusChanged = true; // engine channel status has changed, so set notify flag
1381                    break;
1382                }
1383                case 10: { // panpot
1384                    //TODO: not sample accurate yet
1385                    pEngineChannel->GlobalPanLeft  = PanCurve[128 - itControlChangeEvent->Param.CC.Value];
1386                    pEngineChannel->GlobalPanRight = PanCurve[itControlChangeEvent->Param.CC.Value];
1387                    break;
1388                }
1389                case 64: { // sustain
1390                    if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SustainPedal) {
1391                        dmsg(4,("DAMPER (RIGHT) PEDAL DOWN\n"));
1392                        pEngineChannel->SustainPedal = true;
1393    
1394                        #if !CONFIG_PROCESS_MUTED_CHANNELS
1395                        if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1396                        #endif
1397    
1398                      // cancel release process of voices if necessary                      // cancel release process of voices if necessary
1399                      uint* piKey = pActiveKeys->first();                      RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1400                      if (piKey) {                      for (; iuiKey; ++iuiKey) {
1401                          pControlChangeEvent->Type = Event::type_cancel_release; // transform event type                          midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1402                          while (piKey) {                          if (!pKey->KeyPressed) {
1403                              midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];                              RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1404                              pActiveKeys->set_current(piKey);                              if (itNewEvent) {
1405                              piKey = pActiveKeys->next();                                  *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1406                              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"));  
1407                              }                              }
1408                                else dmsg(1,("Event pool emtpy!\n"));
1409                          }                          }
1410                      }                      }
1411                  }                  }
1412                  if (pControlChangeEvent->Param.CC.Value < 64 && SustainPedal) {                  if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SustainPedal) {
1413                      dmsg(4,("PEDAL UP\n"));                      dmsg(4,("DAMPER (RIGHT) PEDAL UP\n"));
1414                      SustainPedal = false;                      pEngineChannel->SustainPedal = false;
1415    
1416                        #if !CONFIG_PROCESS_MUTED_CHANNELS
1417                        if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1418                        #endif
1419    
1420                      // release voices if their respective key is not pressed                      // release voices if their respective key is not pressed
1421                      uint* piKey = pActiveKeys->first();                      RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1422                      if (piKey) {                      for (; iuiKey; ++iuiKey) {
1423                          pControlChangeEvent->Type = Event::type_release; // transform event type                          midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1424                          while (piKey) {                          if (!pKey->KeyPressed && ShouldReleaseVoice(pEngineChannel, *iuiKey)) {
1425                              midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];                              RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1426                              pActiveKeys->set_current(piKey);                              if (itNewEvent) {
1427                              piKey = pActiveKeys->next();                                  *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1428                              if (!pKey->KeyPressed) {                                  itNewEvent->Type = Event::type_release; // transform event type
                                 Event* pNewEvent = pKey->pEvents->alloc();  
                                 if (pNewEvent) *pNewEvent = *pControlChangeEvent; // copy event to the key's own event list  
                                 else dmsg(1,("Event pool emtpy!\n"));  
1429                              }                              }
1430                                else dmsg(1,("Event pool emtpy!\n"));
1431                          }                          }
1432                      }                      }
1433                  }                  }
1434                  break;                  break;
1435              }              }
1436          }              case 65: { // portamento on / off
1437                    KillAllVoices(pEngineChannel, itControlChangeEvent);
1438                    pEngineChannel->PortamentoMode = itControlChangeEvent->Param.CC.Value >= 64;
1439                    break;
1440                }
1441                case 66: { // sostenuto
1442                    if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SostenutoPedal) {
1443                        dmsg(4,("SOSTENUTO (CENTER) PEDAL DOWN\n"));
1444                        pEngineChannel->SostenutoPedal = true;
1445    
1446                        #if !CONFIG_PROCESS_MUTED_CHANNELS
1447                        if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1448                        #endif
1449    
1450                        SostenutoKeyCount = 0;
1451                        // Remeber the pressed keys
1452                        RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1453                        for (; iuiKey; ++iuiKey) {
1454                            midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1455                            if (pKey->KeyPressed && SostenutoKeyCount < 128) SostenutoKeys[SostenutoKeyCount++] = *iuiKey;
1456                        }
1457                    }
1458                    if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SostenutoPedal) {
1459                        dmsg(4,("SOSTENUTO (CENTER) PEDAL UP\n"));
1460                        pEngineChannel->SostenutoPedal = false;
1461    
1462                        #if !CONFIG_PROCESS_MUTED_CHANNELS
1463                        if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1464                        #endif
1465    
1466                        // release voices if the damper pedal is up and their respective key is not pressed
1467                        for (int i = 0; i < SostenutoKeyCount; i++) {
1468                            midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[SostenutoKeys[i]];
1469                            if (!pKey->KeyPressed && !pEngineChannel->SustainPedal) {
1470                                RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1471                                if (itNewEvent) {
1472                                    *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1473                                    itNewEvent->Type = Event::type_release; // transform event type
1474                                }
1475                                else dmsg(1,("Event pool emtpy!\n"));
1476                            }
1477                        }
1478                    }
1479                    break;
1480                }
1481                case 100: { // RPN controller LSB
1482                    pEngineChannel->SetMidiRpnControllerLsb(itControlChangeEvent->Param.CC.Value);
1483                    break;
1484                }
1485                case 101: { // RPN controller MSB
1486                    pEngineChannel->SetMidiRpnControllerMsb(itControlChangeEvent->Param.CC.Value);
1487                    break;
1488                }
1489    
1490    
1491          // update controller value in the engine's controller table              // Channel Mode Messages
         ControllerTable[pControlChangeEvent->Param.CC.Controller] = pControlChangeEvent->Param.CC.Value;  
1492    
1493          // move event from the unsorted event list to the control change event list              case 120: { // all sound off
1494          pEvents->move(pControlChangeEvent, pCCEvents);                  KillAllVoices(pEngineChannel, itControlChangeEvent);
1495                    break;
1496                }
1497                case 121: { // reset all controllers
1498                    pEngineChannel->ResetControllers();
1499                    break;
1500                }
1501                case 123: { // all notes off
1502                    #if CONFIG_PROCESS_ALL_NOTES_OFF
1503                    ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1504                    #endif // CONFIG_PROCESS_ALL_NOTES_OFF
1505                    break;
1506                }
1507                case 126: { // mono mode on
1508                    KillAllVoices(pEngineChannel, itControlChangeEvent);
1509                    pEngineChannel->SoloMode = true;
1510                    break;
1511                }
1512                case 127: { // poly mode on
1513                    KillAllVoices(pEngineChannel, itControlChangeEvent);
1514                    pEngineChannel->SoloMode = false;
1515                    break;
1516                }
1517            }
1518    
1519            // handle FX send controllers
1520            if (!pEngineChannel->fxSends.empty()) {
1521                for (int iFxSend = 0; iFxSend < pEngineChannel->GetFxSendCount(); iFxSend++) {
1522                    FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
1523                    if (pFxSend->MidiController() == itControlChangeEvent->Param.CC.Controller)
1524                        pFxSend->SetLevel(itControlChangeEvent->Param.CC.Value);
1525                }
1526            }
1527      }      }
1528    
1529      /**      /**
1530       *  Reacts on MIDI system exclusive messages.       *  Reacts on MIDI system exclusive messages.
1531       *       *
1532       *  @param pSysexEvent - sysex data size and time stamp of the sysex event       *  @param itSysexEvent - sysex data size and time stamp of the sysex event
1533       */       */
1534      void Engine::ProcessSysex(Event* pSysexEvent) {      void Engine::ProcessSysex(Pool<Event>::Iterator& itSysexEvent) {
1535          RingBuffer<uint8_t>::NonVolatileReader reader = pSysexBuffer->get_non_volatile_reader();          RingBuffer<uint8_t,false>::NonVolatileReader reader = pSysexBuffer->get_non_volatile_reader();
1536    
1537          uint8_t exclusive_status, id;          uint8_t exclusive_status, id;
1538          if (!reader.pop(&exclusive_status)) goto free_sysex_data;          if (!reader.pop(&exclusive_status)) goto free_sysex_data;
# Line 919  namespace LinuxSampler { namespace gig { Line 1541  namespace LinuxSampler { namespace gig {
1541    
1542          switch (id) {          switch (id) {
1543              case 0x41: { // Roland              case 0x41: { // Roland
1544                    dmsg(3,("Roland Sysex\n"));
1545                  uint8_t device_id, model_id, cmd_id;                  uint8_t device_id, model_id, cmd_id;
1546                  if (!reader.pop(&device_id)) goto free_sysex_data;                  if (!reader.pop(&device_id)) goto free_sysex_data;
1547                  if (!reader.pop(&model_id))  goto free_sysex_data;                  if (!reader.pop(&model_id))  goto free_sysex_data;
# Line 928  namespace LinuxSampler { namespace gig { Line 1551  namespace LinuxSampler { namespace gig {
1551    
1552                  // command address                  // command address
1553                  uint8_t addr[3]; // 2 byte addr MSB, followed by 1 byte addr LSB)                  uint8_t addr[3]; // 2 byte addr MSB, followed by 1 byte addr LSB)
1554                  const RingBuffer<uint8_t>::NonVolatileReader checksum_reader = reader; // so we can calculate the check sum later                  const RingBuffer<uint8_t,false>::NonVolatileReader checksum_reader = reader; // so we can calculate the check sum later
1555                  if (reader.read(&addr[0], 3) != 3) goto free_sysex_data;                  if (reader.read(&addr[0], 3) != 3) goto free_sysex_data;
1556                  if (addr[0] == 0x40 && addr[1] == 0x00) { // System Parameters                  if (addr[0] == 0x40 && addr[1] == 0x00) { // System Parameters
1557                        dmsg(3,("\tSystem Parameter\n"));
1558                  }                  }
1559                  else if (addr[0] == 0x40 && addr[1] == 0x01) { // Common Parameters                  else if (addr[0] == 0x40 && addr[1] == 0x01) { // Common Parameters
1560                        dmsg(3,("\tCommon Parameter\n"));
1561                  }                  }
1562                  else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x10) { // Part Parameters (1)                  else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x10) { // Part Parameters (1)
1563                      switch (addr[3]) {                      dmsg(3,("\tPart Parameter\n"));
1564                        switch (addr[2]) {
1565                          case 0x40: { // scale tuning                          case 0x40: { // scale tuning
1566                                dmsg(3,("\t\tScale Tuning\n"));
1567                              uint8_t scale_tunes[12]; // detuning of all 12 semitones of an octave                              uint8_t scale_tunes[12]; // detuning of all 12 semitones of an octave
1568                              if (reader.read(&scale_tunes[0], 12) != 12) goto free_sysex_data;                              if (reader.read(&scale_tunes[0], 12) != 12) goto free_sysex_data;
1569                              uint8_t checksum;                              uint8_t checksum;
1570                              if (!reader.pop(&checksum))                      goto free_sysex_data;                              if (!reader.pop(&checksum)) goto free_sysex_data;
1571                              if (GSCheckSum(checksum_reader, 12) != checksum) goto free_sysex_data;                              #if CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1572                                if (GSCheckSum(checksum_reader, 12)) goto free_sysex_data;
1573                                #endif // CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1574                              for (int i = 0; i < 12; i++) scale_tunes[i] -= 64;                              for (int i = 0; i < 12; i++) scale_tunes[i] -= 64;
1575                              AdjustScale((int8_t*) scale_tunes);                              AdjustScale((int8_t*) scale_tunes);
1576                                dmsg(3,("\t\t\tNew scale applied.\n"));
1577                              break;                              break;
1578                          }                          }
1579                      }                      }
# Line 957  namespace LinuxSampler { namespace gig { Line 1587  namespace LinuxSampler { namespace gig {
1587          }          }
1588    
1589          free_sysex_data: // finally free sysex data          free_sysex_data: // finally free sysex data
1590          pSysexBuffer->increment_read_ptr(pSysexEvent->Param.Sysex.Size);          pSysexBuffer->increment_read_ptr(itSysexEvent->Param.Sysex.Size);
1591      }      }
1592    
1593      /**      /**
# Line 968  namespace LinuxSampler { namespace gig { Line 1598  namespace LinuxSampler { namespace gig {
1598       *                     question       *                     question
1599       * @param DataSize   - size of the GS message data (in bytes)       * @param DataSize   - size of the GS message data (in bytes)
1600       */       */
1601      uint8_t Engine::GSCheckSum(const RingBuffer<uint8_t>::NonVolatileReader AddrReader, uint DataSize) {      uint8_t Engine::GSCheckSum(const RingBuffer<uint8_t,false>::NonVolatileReader AddrReader, uint DataSize) {
1602          RingBuffer<uint8_t>::NonVolatileReader reader = AddrReader;          RingBuffer<uint8_t,false>::NonVolatileReader reader = AddrReader;
1603          uint bytes = 3 /*addr*/ + DataSize;          uint bytes = 3 /*addr*/ + DataSize;
1604          uint8_t addr_and_data[bytes];          uint8_t addr_and_data[bytes];
1605          reader.read(&addr_and_data[0], bytes);          reader.read(&addr_and_data[0], bytes);
# Line 988  namespace LinuxSampler { namespace gig { Line 1618  namespace LinuxSampler { namespace gig {
1618      }      }
1619    
1620      /**      /**
1621       * Initialize the parameter sequence for the modulation destination given by       * Releases all voices on an engine channel. All voices will go into
1622       * by 'dst' with the constant value given by val.       * the release stage and thus it might take some time (e.g. dependant to
1623         * their envelope release time) until they actually die.
1624         *
1625         * @param pEngineChannel - engine channel on which all voices should be released
1626         * @param itReleaseEvent - event which caused this releasing of all voices
1627       */       */
1628      void Engine::ResetSynthesisParameters(Event::destination_t dst, float val) {      void Engine::ReleaseAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itReleaseEvent) {
1629          int maxsamples = pAudioOutputDevice->MaxSamplesPerCycle();          RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1630          float* m = &pSynthesisParameters[dst][0];          while (iuiKey) {
1631          for (int i = 0; i < maxsamples; i += 4) {              midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1632             m[i]   = val;              ++iuiKey;
1633             m[i+1] = val;              // append a 'release' event to the key's own event list
1634             m[i+2] = val;              RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1635             m[i+3] = val;              if (itNewEvent) {
1636                    *itNewEvent = *itReleaseEvent; // copy original event (to the key's event list)
1637                    itNewEvent->Type = Event::type_release; // transform event type
1638                }
1639                else dmsg(1,("Event pool emtpy!\n"));
1640          }          }
1641      }      }
1642    
1643      float Engine::Volume() {      /**
1644          return GlobalVolume;       * Kills all voices on an engine channel as soon as possible. Voices
1645      }       * won't get into release state, their volume level will be ramped down
1646         * as fast as possible.
1647      void Engine::Volume(float f) {       *
1648          GlobalVolume = f;       * @param pEngineChannel - engine channel on which all voices should be killed
1649      }       * @param itKillEvent    - event which caused this killing of all voices
1650         */
1651      uint Engine::Channels() {      void Engine::KillAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itKillEvent) {
1652          return 2;          RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1653      }          RTList<uint>::Iterator end    = pEngineChannel->pActiveKeys->end();
1654            while (iuiKey != end) { // iterate through all active keys
1655      void Engine::SetOutputChannel(uint EngineAudioChannel, uint AudioDeviceChannel) {              midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1656          AudioChannel* pChannel = pAudioOutputDevice->Channel(AudioDeviceChannel);              ++iuiKey;
1657          if (!pChannel) throw AudioOutputException("Invalid audio output device channel " + ToString(AudioDeviceChannel));              RTList<Voice>::Iterator itVoice     = pKey->pActiveVoices->first();
1658          switch (EngineAudioChannel) {              RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
1659              case 0: // left output channel              for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
1660                  pOutputLeft = pChannel->Buffer();                  itVoice->Kill(itKillEvent);
1661                  AudioDeviceChannelLeft = AudioDeviceChannel;                  --VoiceSpawnsLeft; //FIXME: just a temporary workaround, we should check the cause in StealVoice() instead
1662                  break;              }
             case 1: // right output channel  
                 pOutputRight = pChannel->Buffer();  
                 AudioDeviceChannelRight = AudioDeviceChannel;  
                 break;  
             default:  
                 throw AudioOutputException("Invalid engine audio channel " + ToString(EngineAudioChannel));  
1663          }          }
1664      }      }
1665    
1666      int Engine::OutputChannel(uint EngineAudioChannel) {      /**
1667          switch (EngineAudioChannel) {       * Determines whether the specified voice should be released.
1668              case 0: // left channel       *
1669                  return AudioDeviceChannelLeft;       * @param pEngineChannel - The engine channel on which the voice should be checked
1670              case 1: // right channel       * @param Key - The key number
1671                  return AudioDeviceChannelRight;       * @returns true if the specified should be released, false otherwise.
1672              default:       */
1673                  throw AudioOutputException("Invalid engine audio channel " + ToString(EngineAudioChannel));      bool Engine::ShouldReleaseVoice(EngineChannel* pEngineChannel, int Key) {
1674            if (pEngineChannel->SustainPedal) return false;
1675    
1676            if (pEngineChannel->SostenutoPedal) {
1677                for (int i = 0; i < SostenutoKeyCount; i++)
1678                    if (Key == SostenutoKeys[i]) return false;
1679          }          }
1680    
1681            return true;
1682      }      }
1683    
1684      uint Engine::VoiceCount() {      uint Engine::VoiceCount() {
# Line 1071  namespace LinuxSampler { namespace gig { Line 1710  namespace LinuxSampler { namespace gig {
1710      }      }
1711    
1712      String Engine::EngineName() {      String Engine::EngineName() {
1713          return "GigEngine";          return LS_GIG_ENGINE_NAME;
1714      }      }
1715    
1716      String Engine::InstrumentFileName() {      String Engine::Description() {
1717          return InstrumentFile;          return "Gigasampler Engine";
1718      }      }
1719    
1720      int Engine::InstrumentIndex() {      String Engine::Version() {
1721          return InstrumentIdx;          String s = "$Revision: 1.74 $";
1722            return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
1723      }      }
1724    
1725      int Engine::InstrumentStatus() {      InstrumentManager* Engine::GetInstrumentManager() {
1726          return InstrumentStat;          return &instruments;
1727      }      }
1728    
1729      String Engine::Description() {      // static constant initializers
1730          return "Gigasampler Engine";      const float* Engine::VolumeCurve(InitVolumeCurve());
1731        const float* Engine::PanCurve(InitPanCurve());
1732        const float* Engine::CrossfadeCurve(InitCrossfadeCurve());
1733    
1734        float* Engine::InitVolumeCurve() {
1735            // line-segment approximation
1736            const float segments[] = {
1737                0, 0, 2, 0.0046, 16, 0.016, 31, 0.051, 45, 0.115, 54.5, 0.2,
1738                64.5, 0.39, 74, 0.74, 92, 1.03, 114, 1.94, 119.2, 2.2, 127, 2.2
1739            };
1740            return InitCurve(segments);
1741      }      }
1742    
1743      String Engine::Version() {      float* Engine::InitPanCurve() {
1744          String s = "$Revision: 1.14 $";          // line-segment approximation
1745          return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword          const float segments[] = {
1746                0, 0, 1, 0,
1747                2, 0.05, 31.5, 0.7, 51, 0.851, 74.5, 1.12,
1748                127, 1.41, 128, 1.41
1749            };
1750            return InitCurve(segments, 129);
1751        }
1752    
1753        float* Engine::InitCrossfadeCurve() {
1754            // line-segment approximation
1755            const float segments[] = {
1756                0, 0, 1, 0.03, 10, 0.1, 51, 0.58, 127, 1
1757            };
1758            return InitCurve(segments);
1759        }
1760    
1761        float* Engine::InitCurve(const float* segments, int size) {
1762            float* y = new float[size];
1763            for (int x = 0 ; x < size ; x++) {
1764                if (x > segments[2]) segments += 2;
1765                y[x] = segments[1] + (x - segments[0]) *
1766                    (segments[3] - segments[1]) / (segments[2] - segments[0]);
1767            }
1768            return y;
1769        }
1770    
1771        /**
1772         * Changes the instrument for an engine channel.
1773         *
1774         * @param pEngineChannel - engine channel on which the instrument
1775         *                         should be changed
1776         * @param pInstrument - new instrument
1777         * @returns a list of dimension regions from the old instrument
1778         *          that are still in use
1779         */
1780        ::gig::DimensionRegion** Engine::ChangeInstrument(EngineChannel* pEngineChannel, ::gig::Instrument* pInstrument) {
1781            instrument_change_command_t command;
1782            command.pEngineChannel = pEngineChannel;
1783            command.pInstrument = pInstrument;
1784            InstrumentChangeQueue->push(&command);
1785    
1786            // wait for the audio thread to confirm that the instrument
1787            // change has been done
1788            instrument_change_reply_t reply;
1789            while (InstrumentChangeReplyQueue->pop(&reply) == 0) {
1790                usleep(10000);
1791            }
1792            return pDimRegionsInUse;
1793      }      }
1794    
1795  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.250  
changed lines
  Added in v.1043

  ViewVC Help
Powered by ViewVC