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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1762 - (hide annotations) (download)
Fri Aug 29 17:33:02 2008 UTC (15 years, 7 months ago) by schoenebeck
File size: 107998 byte(s)
* global volume sysex message can now be selected at compile time to be
  only applied to the sampler channels that are connected to the respective
  MIDI input port the SysEx message arrived on (by default global volume
  SysEx messages apply globally to the whole sampler)
* bumped version to 0.5.1.7cvs

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

  ViewVC Help
Powered by ViewVC