/[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 1764 - (hide annotations) (download)
Sat Sep 6 14:55:18 2008 UTC (15 years, 7 months ago) by persson
File size: 108070 byte(s)
* rewrote the ConditionServer class to make it possible to create
  multiple sample channels when the audio thread isn't running

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 persson 1764 EngineDisabled.RttDone();
577 schoenebeck 53 return 0;
578     }
579    
580 schoenebeck 1321 // process requests for suspending / resuming regions (i.e. to avoid
581     // crashes while these regions are modified by an instrument editor)
582     ProcessSuspensionsChanges();
583    
584 schoenebeck 293 // update time of start and end of this audio fragment (as events' time stamps relate to this)
585     pEventGenerator->UpdateFragmentTime(Samples);
586    
587 schoenebeck 663 // We only allow a maximum of CONFIG_MAX_VOICES voices to be spawned
588     // in each audio fragment. All subsequent request for spawning new
589     // voices in the same audio fragment will be ignored.
590     VoiceSpawnsLeft = CONFIG_MAX_VOICES;
591    
592 schoenebeck 412 // get all events from the engine's global input event queue which belong to the current fragment
593     // (these are usually just SysEx messages)
594 schoenebeck 460 ImportEvents(Samples);
595 schoenebeck 412
596     // process engine global events (these are currently only MIDI System Exclusive messages)
597     {
598 schoenebeck 460 RTList<Event>::Iterator itEvent = pGlobalEvents->first();
599     RTList<Event>::Iterator end = pGlobalEvents->end();
600 schoenebeck 412 for (; itEvent != end; ++itEvent) {
601     switch (itEvent->Type) {
602     case Event::type_sysex:
603     dmsg(5,("Engine: Sysex received\n"));
604     ProcessSysex(itEvent);
605     break;
606     }
607     }
608 schoenebeck 53 }
609 schoenebeck 412
610     // reset internal voice counter (just for statistic of active voices)
611     ActiveVoiceCountTemp = 0;
612    
613 persson 1038 // handle instrument change commands
614 persson 1646 bool instrumentChanged = false;
615     for (int i = 0; i < engineChannels.size(); i++) {
616     EngineChannel* pEngineChannel = engineChannels[i];
617 persson 1038
618 persson 1646 // as we're going to (carefully) write some status to the
619     // synchronized struct, we cast away the const
620     EngineChannel::instrument_change_command_t& cmd =
621     const_cast<EngineChannel::instrument_change_command_t&>(pEngineChannel->InstrumentChangeCommandReader.Lock());
622 schoenebeck 1321
623 persson 1646 pEngineChannel->pDimRegionsInUse = cmd.pDimRegionsInUse;
624     pEngineChannel->pDimRegionsInUse->clear();
625 persson 1038
626 persson 1646 if (cmd.bChangeInstrument) {
627     // change instrument
628     dmsg(5,("Engine: instrument change command received\n"));
629     cmd.bChangeInstrument = false;
630     pEngineChannel->pInstrument = cmd.pInstrument;
631     instrumentChanged = true;
632    
633     // Iterate through all active voices and mark them as
634     // "orphans", which means that the dimension regions
635     // and samples they use should be released to the
636     // instrument resource manager when the voices die.
637     int i = 0;
638     RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
639     RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
640     while (iuiKey != end) { // iterate through all active keys
641     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
642     ++iuiKey;
643    
644     RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
645     RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
646     for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
647 persson 1038 itVoice->Orphan = true;
648     }
649     }
650     }
651     }
652 persson 1646 if (instrumentChanged) {
653     //TODO: this is a lazy solution ATM and not safe in case somebody is currently editing the instrument we're currently switching to (we should store all suspended regions on instrument manager side and when switching to another instrument copy that list to the engine's local list of suspensions
654     ResetSuspendedRegions();
655     }
656 persson 1038
657 schoenebeck 466 // handle events on all engine channels
658 schoenebeck 460 for (int i = 0; i < engineChannels.size(); i++) {
659     ProcessEvents(engineChannels[i], Samples);
660 schoenebeck 466 }
661    
662     // render all 'normal', active voices on all engine channels
663     for (int i = 0; i < engineChannels.size(); i++) {
664 schoenebeck 460 RenderActiveVoices(engineChannels[i], Samples);
665 schoenebeck 412 }
666    
667 schoenebeck 460 // now that all ordinary voices on ALL engine channels are rendered, render new stolen voices
668     RenderStolenVoices(Samples);
669    
670 schoenebeck 1001 // handle audio routing for engine channels with FX sends
671     for (int i = 0; i < engineChannels.size(); i++) {
672     if (engineChannels[i]->fxSends.empty()) continue; // ignore if no FX sends
673     RouteAudio(engineChannels[i], Samples);
674     }
675    
676 schoenebeck 460 // handle cleanup on all engine channels for the next audio fragment
677     for (int i = 0; i < engineChannels.size(); i++) {
678     PostProcess(engineChannels[i]);
679     }
680    
681    
682     // empty the engine's event list for the next audio fragment
683     ClearEventLists();
684    
685     // reset voice stealing for the next audio fragment
686     pVoiceStealingQueue->clear();
687    
688 schoenebeck 412 // just some statistics about this engine instance
689     ActiveVoiceCount = ActiveVoiceCountTemp;
690     if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;
691    
692 schoenebeck 1321 // in case regions were previously suspended and we killed voices
693     // with disk streams due to that, check if those streams have finally
694     // been deleted by the disk thread
695     if (iPendingStreamDeletions) ProcessPendingStreamDeletions();
696    
697 persson 1646 for (int i = 0; i < engineChannels.size(); i++) {
698     engineChannels[i]->InstrumentChangeCommandReader.Unlock();
699     }
700 persson 630 FrameTime += Samples;
701    
702 persson 1764 EngineDisabled.RttDone();
703 schoenebeck 412 return 0;
704     }
705    
706 schoenebeck 473 /**
707     * Dispatch and handle all events in this audio fragment for the given
708     * engine channel.
709     *
710     * @param pEngineChannel - engine channel on which events should be
711     * processed
712     * @param Samples - amount of sample points to be processed in
713     * this audio fragment cycle
714     */
715 schoenebeck 460 void Engine::ProcessEvents(EngineChannel* pEngineChannel, uint Samples) {
716 schoenebeck 412 // get all events from the engine channels's input event queue which belong to the current fragment
717     // (these are the common events like NoteOn, NoteOff, ControlChange, etc.)
718 schoenebeck 460 pEngineChannel->ImportEvents(Samples);
719 schoenebeck 53
720     // process events
721 schoenebeck 271 {
722 schoenebeck 460 RTList<Event>::Iterator itEvent = pEngineChannel->pEvents->first();
723     RTList<Event>::Iterator end = pEngineChannel->pEvents->end();
724 schoenebeck 271 for (; itEvent != end; ++itEvent) {
725     switch (itEvent->Type) {
726     case Event::type_note_on:
727     dmsg(5,("Engine: Note on received\n"));
728 schoenebeck 412 ProcessNoteOn((EngineChannel*)itEvent->pEngineChannel, itEvent);
729 schoenebeck 271 break;
730     case Event::type_note_off:
731     dmsg(5,("Engine: Note off received\n"));
732 schoenebeck 412 ProcessNoteOff((EngineChannel*)itEvent->pEngineChannel, itEvent);
733 schoenebeck 271 break;
734     case Event::type_control_change:
735     dmsg(5,("Engine: MIDI CC received\n"));
736 schoenebeck 412 ProcessControlChange((EngineChannel*)itEvent->pEngineChannel, itEvent);
737 schoenebeck 271 break;
738     case Event::type_pitchbend:
739     dmsg(5,("Engine: Pitchbend received\n"));
740 schoenebeck 412 ProcessPitchbend((EngineChannel*)itEvent->pEngineChannel, itEvent);
741 schoenebeck 271 break;
742     }
743 schoenebeck 53 }
744     }
745 schoenebeck 649
746     // reset voice stealing for the next engine channel (or next audio fragment)
747     itLastStolenVoice = RTList<Voice>::Iterator();
748     itLastStolenVoiceGlobally = RTList<Voice>::Iterator();
749     iuiLastStolenKey = RTList<uint>::Iterator();
750     iuiLastStolenKeyGlobally = RTList<uint>::Iterator();
751     pLastStolenChannel = NULL;
752 schoenebeck 460 }
753 schoenebeck 53
754 schoenebeck 473 /**
755     * Render all 'normal' voices (that is voices which were not stolen in
756     * this fragment) on the given engine channel.
757     *
758     * @param pEngineChannel - engine channel on which audio should be
759     * rendered
760     * @param Samples - amount of sample points to be rendered in
761     * this audio fragment cycle
762     */
763 schoenebeck 460 void Engine::RenderActiveVoices(EngineChannel* pEngineChannel, uint Samples) {
764 iliev 716 #if !CONFIG_PROCESS_MUTED_CHANNELS
765 schoenebeck 705 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
766 iliev 716 #endif
767 schoenebeck 705
768 iliev 1305 uint voiceCount = 0;
769     uint streamCount = 0;
770 schoenebeck 460 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
771     RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
772     while (iuiKey != end) { // iterate through all active keys
773     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
774     ++iuiKey;
775 schoenebeck 53
776 schoenebeck 460 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
777     RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
778     for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
779     // now render current voice
780     itVoice->Render(Samples);
781 iliev 1297 if (itVoice->IsActive()) { // still active
782 persson 1646 if (!itVoice->Orphan) {
783     *(pEngineChannel->pDimRegionsInUse->allocAppend()) = itVoice->pDimRgn;
784     }
785 iliev 1297 ActiveVoiceCountTemp++;
786 iliev 1305 voiceCount++;
787 iliev 1297
788     if (itVoice->PlaybackState == Voice::playback_state_disk) {
789 iliev 1305 if ((itVoice->DiskStreamRef).State == Stream::state_active) streamCount++;
790 iliev 1297 }
791     } else { // voice reached end, is now inactive
792 schoenebeck 460 FreeVoice(pEngineChannel, itVoice); // remove voice from the list of active voices
793 schoenebeck 53 }
794     }
795     }
796 schoenebeck 1348
797 iliev 1305 pEngineChannel->SetVoiceCount(voiceCount);
798     pEngineChannel->SetDiskStreamCount(streamCount);
799 schoenebeck 460 }
800 schoenebeck 53
801 schoenebeck 473 /**
802     * Render all stolen voices (only voices which were stolen in this
803     * fragment) on the given engine channel. Stolen voices are rendered
804     * after all normal voices have been rendered; this is needed to render
805     * audio of those voices which were selected for voice stealing until
806     * the point were the stealing (that is the take over of the voice)
807     * actually happened.
808     *
809     * @param pEngineChannel - engine channel on which audio should be
810     * rendered
811     * @param Samples - amount of sample points to be rendered in
812     * this audio fragment cycle
813     */
814 schoenebeck 460 void Engine::RenderStolenVoices(uint Samples) {
815     RTList<Event>::Iterator itVoiceStealEvent = pVoiceStealingQueue->first();
816     RTList<Event>::Iterator end = pVoiceStealingQueue->end();
817     for (; itVoiceStealEvent != end; ++itVoiceStealEvent) {
818     EngineChannel* pEngineChannel = (EngineChannel*) itVoiceStealEvent->pEngineChannel;
819 persson 1038 if (!pEngineChannel->pInstrument) continue; // ignore if no instrument loaded
820 schoenebeck 460 Pool<Voice>::Iterator itNewVoice =
821 schoenebeck 668 LaunchVoice(pEngineChannel, itVoiceStealEvent, itVoiceStealEvent->Param.Note.Layer, itVoiceStealEvent->Param.Note.ReleaseTrigger, false, false);
822 schoenebeck 460 if (itNewVoice) {
823     itNewVoice->Render(Samples);
824 iliev 1297 if (itNewVoice->IsActive()) { // still active
825 persson 1646 *(pEngineChannel->pDimRegionsInUse->allocAppend()) = itNewVoice->pDimRgn;
826 iliev 1297 ActiveVoiceCountTemp++;
827     pEngineChannel->SetVoiceCount(pEngineChannel->GetVoiceCount() + 1);
828    
829     if (itNewVoice->PlaybackState == Voice::playback_state_disk) {
830     if (itNewVoice->DiskStreamRef.State == Stream::state_active) {
831     pEngineChannel->SetDiskStreamCount(pEngineChannel->GetDiskStreamCount() + 1);
832     }
833     }
834     } else { // voice reached end, is now inactive
835 schoenebeck 460 FreeVoice(pEngineChannel, itNewVoice); // remove voice from the list of active voices
836 schoenebeck 250 }
837     }
838 schoenebeck 460 else dmsg(1,("gig::Engine: ERROR, voice stealing didn't work out!\n"));
839 schoenebeck 473
840     // we need to clear the key's event list explicitly here in case key was never active
841     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoiceStealEvent->Param.Note.Key];
842     pKey->VoiceTheftsQueued--;
843     if (!pKey->Active && !pKey->VoiceTheftsQueued) pKey->pEvents->clear();
844 schoenebeck 250 }
845 schoenebeck 460 }
846 schoenebeck 250
847 schoenebeck 473 /**
848 schoenebeck 1001 * Will be called in case the respective engine channel sports FX send
849     * channels. In this particular case, engine channel local buffers are
850     * used to render and mix all voices to. This method is responsible for
851     * copying the audio data from those local buffers to the master audio
852     * output channels as well as to the FX send audio output channels with
853     * their respective FX send levels.
854     *
855     * @param pEngineChannel - engine channel from which audio should be
856     * routed
857     * @param Samples - amount of sample points to be routed in
858     * this audio fragment cycle
859     */
860     void Engine::RouteAudio(EngineChannel* pEngineChannel, uint Samples) {
861 schoenebeck 1722 // route dry signal
862 schoenebeck 1001 {
863     AudioChannel* pDstL = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelLeft);
864     AudioChannel* pDstR = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelRight);
865 schoenebeck 1037 pEngineChannel->pChannelLeft->MixTo(pDstL, Samples);
866     pEngineChannel->pChannelRight->MixTo(pDstR, Samples);
867 schoenebeck 1001 }
868     // route FX send signal
869     {
870     for (int iFxSend = 0; iFxSend < pEngineChannel->GetFxSendCount(); iFxSend++) {
871     FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
872 schoenebeck 1722 for (int iChan = 0; iChan < 2; ++iChan) {
873     AudioChannel* pSource =
874     (iChan)
875     ? pEngineChannel->pChannelRight
876     : pEngineChannel->pChannelLeft;
877     const int iDstChan = pFxSend->DestinationChannel(iChan);
878     if (iDstChan < 0) {
879     dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination channel (%d->%d)", ((iChan) ? "R" : "L"), iChan, iDstChan));
880     goto channel_cleanup;
881     }
882     AudioChannel* pDstChan = NULL;
883     if (pFxSend->DestinationMasterEffectChain() >= 0) { // fx send routed to an internal master effect
884     EffectChain* pEffectChain =
885     pAudioOutputDevice->MasterEffectChain(
886     pFxSend->DestinationMasterEffectChain()
887     );
888     if (!pEffectChain) {
889     dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination effect chain %d", ((iChan) ? "R" : "L"), pFxSend->DestinationMasterEffectChain()));
890     goto channel_cleanup;
891     }
892     Effect* pEffect =
893     pEffectChain->GetEffect(
894     pFxSend->DestinationMasterEffect()
895     );
896     if (!pEffect) {
897     dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination effect %d of effect chain %d", ((iChan) ? "R" : "L"), pFxSend->DestinationMasterEffect(), pFxSend->DestinationMasterEffectChain()));
898     goto channel_cleanup;
899     }
900     pDstChan = pEffect->InputChannel(iDstChan);
901     } else { // FX send routed directly to an audio output channel
902     pDstChan = pAudioOutputDevice->Channel(iDstChan);
903     }
904     if (!pDstChan) {
905     dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination channel (%d->%d)", ((iChan) ? "R" : "L"), iChan, iDstChan));
906     goto channel_cleanup;
907     }
908     pSource->MixTo(pDstChan, Samples, pFxSend->Level());
909 schoenebeck 1001 }
910     }
911     }
912 schoenebeck 1722 channel_cleanup:
913 schoenebeck 1001 // reset buffers with silence (zero out) for the next audio cycle
914     pEngineChannel->pChannelLeft->Clear();
915     pEngineChannel->pChannelRight->Clear();
916     }
917    
918     /**
919 schoenebeck 473 * Free all keys which have turned inactive in this audio fragment, from
920     * the list of active keys and clear all event lists on that engine
921     * channel.
922     *
923     * @param pEngineChannel - engine channel to cleanup
924     */
925 schoenebeck 460 void Engine::PostProcess(EngineChannel* pEngineChannel) {
926 schoenebeck 287 // free all keys which have no active voices left
927     {
928 schoenebeck 411 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
929     RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
930 schoenebeck 287 while (iuiKey != end) { // iterate through all active keys
931 schoenebeck 411 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
932 schoenebeck 287 ++iuiKey;
933 schoenebeck 411 if (pKey->pActiveVoices->isEmpty()) FreeKey(pEngineChannel, pKey);
934 schoenebeck 554 #if CONFIG_DEVMODE
935 schoenebeck 563 else { // just a sanity check for debugging
936 schoenebeck 287 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
937     RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
938     for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
939     if (itVoice->itKillEvent) {
940     dmsg(1,("gig::Engine: ERROR, killed voice survived !!!\n"));
941     }
942     }
943     }
944 schoenebeck 554 #endif // CONFIG_DEVMODE
945 schoenebeck 287 }
946     }
947 schoenebeck 460
948     // empty the engine channel's own event lists
949     pEngineChannel->ClearEventLists();
950 schoenebeck 412 }
951 schoenebeck 287
952 schoenebeck 53 /**
953 schoenebeck 244 * Will be called by the MIDI input device whenever a MIDI system
954     * exclusive message has arrived.
955     *
956     * @param pData - pointer to sysex data
957     * @param Size - lenght of sysex data (in bytes)
958 schoenebeck 1751 * @param pSender - the MIDI input port on which the SysEx message was
959     * received
960 schoenebeck 244 */
961 schoenebeck 1751 void Engine::SendSysex(void* pData, uint Size, MidiInputPort* pSender) {
962 schoenebeck 246 Event event = pEventGenerator->CreateEvent();
963     event.Type = Event::type_sysex;
964     event.Param.Sysex.Size = Size;
965 schoenebeck 412 event.pEngineChannel = NULL; // as Engine global event
966 schoenebeck 1751 event.pMidiInputPort = pSender;
967 schoenebeck 244 if (pEventQueue->write_space() > 0) {
968     if (pSysexBuffer->write_space() >= Size) {
969     // copy sysex data to input buffer
970     uint toWrite = Size;
971     uint8_t* pPos = (uint8_t*) pData;
972     while (toWrite) {
973     const uint writeNow = RTMath::Min(toWrite, pSysexBuffer->write_space_to_end());
974     pSysexBuffer->write(pPos, writeNow);
975     toWrite -= writeNow;
976     pPos += writeNow;
977    
978     }
979     // finally place sysex event into input event queue
980     pEventQueue->push(&event);
981     }
982 schoenebeck 554 else dmsg(1,("Engine: Sysex message too large (%d byte) for input buffer (%d byte)!",Size,CONFIG_SYSEX_BUFFER_SIZE));
983 schoenebeck 244 }
984     else dmsg(1,("Engine: Input event queue full!"));
985     }
986    
987     /**
988 schoenebeck 53 * Assigns and triggers a new voice for the respective MIDI key.
989     *
990 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
991 schoenebeck 271 * @param itNoteOnEvent - key, velocity and time stamp of the event
992 schoenebeck 53 */
993 schoenebeck 411 void Engine::ProcessNoteOn(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
994 iliev 716 #if !CONFIG_PROCESS_MUTED_CHANNELS
995     if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
996     #endif
997 persson 438
998 persson 1038 if (!pEngineChannel->pInstrument) return; // ignore if no instrument loaded
999    
1000 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
1001     itNoteOnEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
1002    
1003 schoenebeck 354 const int key = itNoteOnEvent->Param.Note.Key;
1004 schoenebeck 829 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key];
1005 schoenebeck 354
1006 schoenebeck 829 // move note on event to the key's own event list
1007     RTList<Event>::Iterator itNoteOnEventOnKeyList = itNoteOnEvent.moveToEndOf(pKey->pEvents);
1008    
1009     // if Solo Mode then kill all already active voices
1010     if (pEngineChannel->SoloMode) {
1011     Pool<uint>::Iterator itYoungestKey = pEngineChannel->pActiveKeys->last();
1012     if (itYoungestKey) {
1013     const int iYoungestKey = *itYoungestKey;
1014     const midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[iYoungestKey];
1015     if (pOtherKey->Active) {
1016     // get final portamento position of currently active voice
1017     if (pEngineChannel->PortamentoMode) {
1018     RTList<Voice>::Iterator itVoice = pOtherKey->pActiveVoices->last();
1019     if (itVoice) itVoice->UpdatePortamentoPos(itNoteOnEventOnKeyList);
1020     }
1021     // kill all voices on the (other) key
1022     RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
1023     RTList<Voice>::Iterator end = pOtherKey->pActiveVoices->end();
1024     for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
1025     if (itVoiceToBeKilled->Type != Voice::type_release_trigger)
1026     itVoiceToBeKilled->Kill(itNoteOnEventOnKeyList);
1027     }
1028     }
1029     }
1030     // set this key as 'currently active solo key'
1031     pEngineChannel->SoloKey = key;
1032     }
1033    
1034 schoenebeck 354 // Change key dimension value if key is in keyswitching area
1035 schoenebeck 411 {
1036     const ::gig::Instrument* pInstrument = pEngineChannel->pInstrument;
1037     if (key >= pInstrument->DimensionKeyRange.low && key <= pInstrument->DimensionKeyRange.high)
1038 persson 865 pEngineChannel->CurrentKeyDimension = float(key - pInstrument->DimensionKeyRange.low) /
1039 schoenebeck 411 (pInstrument->DimensionKeyRange.high - pInstrument->DimensionKeyRange.low + 1);
1040     }
1041 schoenebeck 354
1042 schoenebeck 53 pKey->KeyPressed = true; // the MIDI key was now pressed down
1043 schoenebeck 829 pKey->Velocity = itNoteOnEventOnKeyList->Param.Note.Velocity;
1044     pKey->NoteOnTime = FrameTime + itNoteOnEventOnKeyList->FragmentPos(); // will be used to calculate note length
1045 schoenebeck 53
1046     // cancel release process of voices on this key if needed
1047 schoenebeck 411 if (pKey->Active && !pEngineChannel->SustainPedal) {
1048 schoenebeck 271 RTList<Event>::Iterator itCancelReleaseEvent = pKey->pEvents->allocAppend();
1049     if (itCancelReleaseEvent) {
1050 schoenebeck 829 *itCancelReleaseEvent = *itNoteOnEventOnKeyList; // copy event
1051 schoenebeck 271 itCancelReleaseEvent->Type = Event::type_cancel_release; // transform event type
1052 schoenebeck 239 }
1053     else dmsg(1,("Event pool emtpy!\n"));
1054 schoenebeck 53 }
1055    
1056 schoenebeck 460 // allocate and trigger new voice(s) for the key
1057     {
1058     // first, get total amount of required voices (dependant on amount of layers)
1059     ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOnEventOnKeyList->Param.Note.Key);
1060 schoenebeck 1321 if (pRegion && !RegionSuspended(pRegion)) {
1061 schoenebeck 460 int voicesRequired = pRegion->Layers;
1062     // now launch the required amount of voices
1063     for (int i = 0; i < voicesRequired; i++)
1064 schoenebeck 668 LaunchVoice(pEngineChannel, itNoteOnEventOnKeyList, i, false, true, true);
1065 schoenebeck 460 }
1066     }
1067 persson 438
1068 schoenebeck 473 // if neither a voice was spawned or postponed then remove note on event from key again
1069     if (!pKey->Active && !pKey->VoiceTheftsQueued)
1070     pKey->pEvents->free(itNoteOnEventOnKeyList);
1071    
1072 schoenebeck 829 if (!pEngineChannel->SoloMode || pEngineChannel->PortamentoPos < 0.0f) pEngineChannel->PortamentoPos = (float) key;
1073 persson 438 pKey->RoundRobinIndex++;
1074 schoenebeck 53 }
1075    
1076     /**
1077     * Releases the voices on the given key if sustain pedal is not pressed.
1078     * If sustain is pressed, the release of the note will be postponed until
1079     * sustain pedal will be released or voice turned inactive by itself (e.g.
1080     * due to completion of sample playback).
1081     *
1082 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1083 schoenebeck 271 * @param itNoteOffEvent - key, velocity and time stamp of the event
1084 schoenebeck 53 */
1085 schoenebeck 411 void Engine::ProcessNoteOff(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOffEvent) {
1086 iliev 716 #if !CONFIG_PROCESS_MUTED_CHANNELS
1087 schoenebeck 705 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1088 iliev 716 #endif
1089 schoenebeck 705
1090 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
1091     itNoteOffEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
1092    
1093 schoenebeck 829 const int iKey = itNoteOffEvent->Param.Note.Key;
1094     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[iKey];
1095 schoenebeck 53 pKey->KeyPressed = false; // the MIDI key was now released
1096    
1097 schoenebeck 829 // move event to the key's own event list
1098     RTList<Event>::Iterator itNoteOffEventOnKeyList = itNoteOffEvent.moveToEndOf(pKey->pEvents);
1099 schoenebeck 242
1100 schoenebeck 829 bool bShouldRelease = pKey->Active && ShouldReleaseVoice(pEngineChannel, itNoteOffEventOnKeyList->Param.Note.Key);
1101 schoenebeck 271
1102 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)
1103 persson 1038 if (pEngineChannel->SoloMode && pEngineChannel->pInstrument) { //TODO: this feels like too much code just for handling solo mode :P
1104 schoenebeck 829 bool bOtherKeysPressed = false;
1105     if (iKey == pEngineChannel->SoloKey) {
1106     pEngineChannel->SoloKey = -1;
1107     // if there's still a key pressed down, respawn a voice (group) on the highest key
1108     for (int i = 127; i > 0; i--) {
1109     midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[i];
1110     if (pOtherKey->KeyPressed) {
1111     bOtherKeysPressed = true;
1112     // make the other key the new 'currently active solo key'
1113     pEngineChannel->SoloKey = i;
1114     // get final portamento position of currently active voice
1115     if (pEngineChannel->PortamentoMode) {
1116     RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
1117     if (itVoice) itVoice->UpdatePortamentoPos(itNoteOffEventOnKeyList);
1118     }
1119     // create a pseudo note on event
1120     RTList<Event>::Iterator itPseudoNoteOnEvent = pOtherKey->pEvents->allocAppend();
1121     if (itPseudoNoteOnEvent) {
1122     // copy event
1123     *itPseudoNoteOnEvent = *itNoteOffEventOnKeyList;
1124     // transform event to a note on event
1125     itPseudoNoteOnEvent->Type = Event::type_note_on;
1126     itPseudoNoteOnEvent->Param.Note.Key = i;
1127     itPseudoNoteOnEvent->Param.Note.Velocity = pOtherKey->Velocity;
1128     // allocate and trigger new voice(s) for the other key
1129     {
1130     // first, get total amount of required voices (dependant on amount of layers)
1131     ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(i);
1132     if (pRegion) {
1133     int voicesRequired = pRegion->Layers;
1134     // now launch the required amount of voices
1135     for (int iLayer = 0; iLayer < voicesRequired; iLayer++)
1136     LaunchVoice(pEngineChannel, itPseudoNoteOnEvent, iLayer, false, true, false);
1137     }
1138     }
1139     // if neither a voice was spawned or postponed then remove note on event from key again
1140     if (!pOtherKey->Active && !pOtherKey->VoiceTheftsQueued)
1141     pOtherKey->pEvents->free(itPseudoNoteOnEvent);
1142    
1143     } else dmsg(1,("Could not respawn voice, no free event left\n"));
1144     break; // done
1145     }
1146     }
1147     }
1148     if (bOtherKeysPressed) {
1149     if (pKey->Active) { // kill all voices on this key
1150     bShouldRelease = false; // no need to release, as we kill it here
1151     RTList<Voice>::Iterator itVoiceToBeKilled = pKey->pActiveVoices->first();
1152     RTList<Voice>::Iterator end = pKey->pActiveVoices->end();
1153     for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
1154     if (itVoiceToBeKilled->Type != Voice::type_release_trigger)
1155     itVoiceToBeKilled->Kill(itNoteOffEventOnKeyList);
1156     }
1157     }
1158     } else pEngineChannel->PortamentoPos = -1.0f;
1159     }
1160    
1161     // if no solo mode (the usual case) or if solo mode and no other key pressed, then release voices on this key if needed
1162     if (bShouldRelease) {
1163     itNoteOffEventOnKeyList->Type = Event::type_release; // transform event type
1164    
1165 persson 497 // spawn release triggered voice(s) if needed
1166 persson 1038 if (pKey->ReleaseTrigger && pEngineChannel->pInstrument) {
1167 persson 497 // first, get total amount of required voices (dependant on amount of layers)
1168     ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key);
1169     if (pRegion) {
1170     int voicesRequired = pRegion->Layers;
1171 persson 630
1172     // MIDI note-on velocity is used instead of note-off velocity
1173     itNoteOffEventOnKeyList->Param.Note.Velocity = pKey->Velocity;
1174    
1175 persson 497 // now launch the required amount of voices
1176     for (int i = 0; i < voicesRequired; i++)
1177 schoenebeck 668 LaunchVoice(pEngineChannel, itNoteOffEventOnKeyList, i, true, false, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples
1178 persson 497 }
1179     pKey->ReleaseTrigger = false;
1180 schoenebeck 460 }
1181 schoenebeck 829 }
1182 persson 497
1183 schoenebeck 829 // if neither a voice was spawned or postponed on this key then remove note off event from key again
1184     if (!pKey->Active && !pKey->VoiceTheftsQueued)
1185     pKey->pEvents->free(itNoteOffEventOnKeyList);
1186 schoenebeck 53 }
1187    
1188     /**
1189 schoenebeck 738 * Moves pitchbend event from the general (input) event list to the engine
1190     * channel's event list. It will actually processed later by the
1191     * respective voice.
1192 schoenebeck 53 *
1193 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1194 schoenebeck 271 * @param itPitchbendEvent - absolute pitch value and time stamp of the event
1195 schoenebeck 53 */
1196 schoenebeck 411 void Engine::ProcessPitchbend(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itPitchbendEvent) {
1197     pEngineChannel->Pitch = itPitchbendEvent->Param.Pitch.Pitch; // store current pitch value
1198 schoenebeck 53 }
1199    
1200     /**
1201 schoenebeck 233 * Allocates and triggers a new voice. This method will usually be
1202     * called by the ProcessNoteOn() method and by the voices itself
1203     * (e.g. to spawn further voices on the same key for layered sounds).
1204     *
1205 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1206 schoenebeck 271 * @param itNoteOnEvent - key, velocity and time stamp of the event
1207 schoenebeck 242 * @param iLayer - layer index for the new voice (optional - only
1208     * in case of layered sounds of course)
1209     * @param ReleaseTriggerVoice - if new voice is a release triggered voice
1210     * (optional, default = false)
1211 schoenebeck 250 * @param VoiceStealing - if voice stealing should be performed
1212     * when there is no free voice
1213     * (optional, default = true)
1214 schoenebeck 668 * @param HandleKeyGroupConflicts - if voices should be killed due to a
1215     * key group conflict
1216 schoenebeck 250 * @returns pointer to new voice or NULL if there was no free voice or
1217 schoenebeck 354 * if the voice wasn't triggered (for example when no region is
1218     * defined for the given key).
1219 schoenebeck 233 */
1220 schoenebeck 668 Pool<Voice>::Iterator Engine::LaunchVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing, bool HandleKeyGroupConflicts) {
1221 schoenebeck 669 int MIDIKey = itNoteOnEvent->Param.Note.Key;
1222     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[MIDIKey];
1223     ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(MIDIKey);
1224 schoenebeck 233
1225 schoenebeck 668 // if nothing defined for this key
1226     if (!pRegion) return Pool<Voice>::Iterator(); // nothing to do
1227    
1228 schoenebeck 669 // only mark the first voice of a layered voice (group) to be in a
1229     // key group, so the layered voices won't kill each other
1230     int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;
1231    
1232 schoenebeck 668 // handle key group (a.k.a. exclusive group) conflicts
1233     if (HandleKeyGroupConflicts) {
1234     if (iKeyGroup) { // if this voice / key belongs to a key group
1235     uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[iKeyGroup];
1236     if (*ppKeyGroup) { // if there's already an active key in that key group
1237     midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[**ppKeyGroup];
1238     // kill all voices on the (other) key
1239     RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
1240     RTList<Voice>::Iterator end = pOtherKey->pActiveVoices->end();
1241     for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
1242     if (itVoiceToBeKilled->Type != Voice::type_release_trigger) {
1243     itVoiceToBeKilled->Kill(itNoteOnEvent);
1244     --VoiceSpawnsLeft; //FIXME: just a hack, we should better check in StealVoice() if the voice was killed due to key conflict
1245     }
1246     }
1247     }
1248     }
1249     }
1250    
1251 schoenebeck 669 Voice::type_t VoiceType = Voice::type_normal;
1252    
1253     // get current dimension values to select the right dimension region
1254     //TODO: for stolen voices this dimension region selection block is processed twice, this should be changed
1255     //FIXME: controller values for selecting the dimension region here are currently not sample accurate
1256     uint DimValues[8] = { 0 };
1257     for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
1258     switch (pRegion->pDimensionDefinitions[i].dimension) {
1259     case ::gig::dimension_samplechannel:
1260     DimValues[i] = 0; //TODO: we currently ignore this dimension
1261     break;
1262     case ::gig::dimension_layer:
1263     DimValues[i] = iLayer;
1264     break;
1265     case ::gig::dimension_velocity:
1266     DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
1267     break;
1268     case ::gig::dimension_channelaftertouch:
1269 persson 903 DimValues[i] = pEngineChannel->ControllerTable[128];
1270 schoenebeck 669 break;
1271     case ::gig::dimension_releasetrigger:
1272     VoiceType = (ReleaseTriggerVoice) ? Voice::type_release_trigger : (!iLayer) ? Voice::type_release_trigger_required : Voice::type_normal;
1273     DimValues[i] = (uint) ReleaseTriggerVoice;
1274     break;
1275     case ::gig::dimension_keyboard:
1276 persson 865 DimValues[i] = (uint) (pEngineChannel->CurrentKeyDimension * pRegion->pDimensionDefinitions[i].zones);
1277 schoenebeck 669 break;
1278     case ::gig::dimension_roundrobin:
1279     DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on
1280     break;
1281     case ::gig::dimension_random:
1282     RandomSeed = RandomSeed * 1103515245 + 12345; // classic pseudo random number generator
1283     DimValues[i] = (uint) RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random
1284     break;
1285     case ::gig::dimension_modwheel:
1286     DimValues[i] = pEngineChannel->ControllerTable[1];
1287     break;
1288     case ::gig::dimension_breath:
1289     DimValues[i] = pEngineChannel->ControllerTable[2];
1290     break;
1291     case ::gig::dimension_foot:
1292     DimValues[i] = pEngineChannel->ControllerTable[4];
1293     break;
1294     case ::gig::dimension_portamentotime:
1295     DimValues[i] = pEngineChannel->ControllerTable[5];
1296     break;
1297     case ::gig::dimension_effect1:
1298     DimValues[i] = pEngineChannel->ControllerTable[12];
1299     break;
1300     case ::gig::dimension_effect2:
1301     DimValues[i] = pEngineChannel->ControllerTable[13];
1302     break;
1303     case ::gig::dimension_genpurpose1:
1304     DimValues[i] = pEngineChannel->ControllerTable[16];
1305     break;
1306     case ::gig::dimension_genpurpose2:
1307     DimValues[i] = pEngineChannel->ControllerTable[17];
1308     break;
1309     case ::gig::dimension_genpurpose3:
1310     DimValues[i] = pEngineChannel->ControllerTable[18];
1311     break;
1312     case ::gig::dimension_genpurpose4:
1313     DimValues[i] = pEngineChannel->ControllerTable[19];
1314     break;
1315     case ::gig::dimension_sustainpedal:
1316     DimValues[i] = pEngineChannel->ControllerTable[64];
1317     break;
1318     case ::gig::dimension_portamento:
1319     DimValues[i] = pEngineChannel->ControllerTable[65];
1320     break;
1321     case ::gig::dimension_sostenutopedal:
1322     DimValues[i] = pEngineChannel->ControllerTable[66];
1323     break;
1324     case ::gig::dimension_softpedal:
1325     DimValues[i] = pEngineChannel->ControllerTable[67];
1326     break;
1327     case ::gig::dimension_genpurpose5:
1328     DimValues[i] = pEngineChannel->ControllerTable[80];
1329     break;
1330     case ::gig::dimension_genpurpose6:
1331     DimValues[i] = pEngineChannel->ControllerTable[81];
1332     break;
1333     case ::gig::dimension_genpurpose7:
1334     DimValues[i] = pEngineChannel->ControllerTable[82];
1335     break;
1336     case ::gig::dimension_genpurpose8:
1337     DimValues[i] = pEngineChannel->ControllerTable[83];
1338     break;
1339     case ::gig::dimension_effect1depth:
1340     DimValues[i] = pEngineChannel->ControllerTable[91];
1341     break;
1342     case ::gig::dimension_effect2depth:
1343     DimValues[i] = pEngineChannel->ControllerTable[92];
1344     break;
1345     case ::gig::dimension_effect3depth:
1346     DimValues[i] = pEngineChannel->ControllerTable[93];
1347     break;
1348     case ::gig::dimension_effect4depth:
1349     DimValues[i] = pEngineChannel->ControllerTable[94];
1350     break;
1351     case ::gig::dimension_effect5depth:
1352     DimValues[i] = pEngineChannel->ControllerTable[95];
1353     break;
1354     case ::gig::dimension_none:
1355     std::cerr << "gig::Engine::LaunchVoice() Error: dimension=none\n" << std::flush;
1356     break;
1357     default:
1358     std::cerr << "gig::Engine::LaunchVoice() Error: Unknown dimension\n" << std::flush;
1359     }
1360     }
1361 persson 1038
1362     // return if this is a release triggered voice and there is no
1363     // releasetrigger dimension (could happen if an instrument
1364     // change has occured between note on and off)
1365     if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
1366    
1367 schoenebeck 669 ::gig::DimensionRegion* pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
1368    
1369     // no need to continue if sample is silent
1370     if (!pDimRgn->pSample || !pDimRgn->pSample->SamplesTotal) return Pool<Voice>::Iterator();
1371    
1372 schoenebeck 233 // allocate a new voice for the key
1373 schoenebeck 271 Pool<Voice>::Iterator itNewVoice = pKey->pActiveVoices->allocAppend();
1374     if (itNewVoice) {
1375 schoenebeck 233 // launch the new voice
1376 schoenebeck 669 if (itNewVoice->Trigger(pEngineChannel, itNoteOnEvent, pEngineChannel->Pitch, pDimRgn, VoiceType, iKeyGroup) < 0) {
1377 schoenebeck 354 dmsg(4,("Voice not triggered\n"));
1378 schoenebeck 271 pKey->pActiveVoices->free(itNewVoice);
1379 schoenebeck 233 }
1380 schoenebeck 239 else { // on success
1381 schoenebeck 663 --VoiceSpawnsLeft;
1382 schoenebeck 239 if (!pKey->Active) { // mark as active key
1383     pKey->Active = true;
1384 schoenebeck 411 pKey->itSelf = pEngineChannel->pActiveKeys->allocAppend();
1385 schoenebeck 271 *pKey->itSelf = itNoteOnEvent->Param.Note.Key;
1386 schoenebeck 239 }
1387 schoenebeck 271 if (itNewVoice->KeyGroup) {
1388 schoenebeck 668 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[itNewVoice->KeyGroup];
1389 schoenebeck 271 *ppKeyGroup = &*pKey->itSelf; // put key as the (new) active key to its key group
1390 schoenebeck 239 }
1391 schoenebeck 271 if (itNewVoice->Type == Voice::type_release_trigger_required) pKey->ReleaseTrigger = true; // mark key for the need of release triggered voice(s)
1392     return itNewVoice; // success
1393 schoenebeck 233 }
1394     }
1395 schoenebeck 285 else if (VoiceStealing) {
1396 schoenebeck 460 // try to steal one voice
1397 schoenebeck 473 int result = StealVoice(pEngineChannel, itNoteOnEvent);
1398     if (!result) { // voice stolen successfully
1399     // put note-on event into voice-stealing queue, so it will be reprocessed after killed voice died
1400     RTList<Event>::Iterator itStealEvent = pVoiceStealingQueue->allocAppend();
1401     if (itStealEvent) {
1402     *itStealEvent = *itNoteOnEvent; // copy event
1403     itStealEvent->Param.Note.Layer = iLayer;
1404     itStealEvent->Param.Note.ReleaseTrigger = ReleaseTriggerVoice;
1405     pKey->VoiceTheftsQueued++;
1406     }
1407     else dmsg(1,("Voice stealing queue full!\n"));
1408 schoenebeck 285 }
1409     }
1410    
1411 schoenebeck 271 return Pool<Voice>::Iterator(); // no free voice or error
1412 schoenebeck 233 }
1413    
1414     /**
1415 schoenebeck 250 * Will be called by LaunchVoice() method in case there are no free
1416     * voices left. This method will select and kill one old voice for
1417     * voice stealing and postpone the note-on event until the selected
1418     * voice actually died.
1419     *
1420 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1421 schoenebeck 285 * @param itNoteOnEvent - key, velocity and time stamp of the event
1422 schoenebeck 473 * @returns 0 on success, a value < 0 if no active voice could be picked for voice stealing
1423 schoenebeck 250 */
1424 schoenebeck 473 int Engine::StealVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
1425 schoenebeck 663 if (VoiceSpawnsLeft <= 0) {
1426 schoenebeck 554 dmsg(1,("Max. voice thefts per audio fragment reached (you may raise CONFIG_MAX_VOICES).\n"));
1427 schoenebeck 473 return -1;
1428 schoenebeck 460 }
1429 schoenebeck 271 if (!pEventPool->poolIsEmpty()) {
1430 schoenebeck 250
1431 schoenebeck 460 RTList<Voice>::Iterator itSelectedVoice;
1432 schoenebeck 250
1433     // Select one voice for voice stealing
1434 schoenebeck 554 switch (CONFIG_VOICE_STEAL_ALGO) {
1435 schoenebeck 250
1436     // try to pick the oldest voice on the key where the new
1437     // voice should be spawned, if there is no voice on that
1438 schoenebeck 563 // key, or no voice left to kill, then procceed with
1439 schoenebeck 250 // 'oldestkey' algorithm
1440 schoenebeck 460 case voice_steal_algo_oldestvoiceonkey: {
1441     midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key];
1442 schoenebeck 563 itSelectedVoice = pSelectedKey->pActiveVoices->first();
1443     // proceed iterating if voice was created in this fragment cycle
1444 schoenebeck 663 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1445 schoenebeck 563 // if we haven't found a voice then proceed with algorithm 'oldestkey'
1446 schoenebeck 663 if (itSelectedVoice && itSelectedVoice->IsStealable()) break;
1447 schoenebeck 250 } // no break - intentional !
1448    
1449     // try to pick the oldest voice on the oldest active key
1450 schoenebeck 563 // from the same engine channel
1451 schoenebeck 460 // (caution: must stay after 'oldestvoiceonkey' algorithm !)
1452 schoenebeck 250 case voice_steal_algo_oldestkey: {
1453 schoenebeck 649 // if we already stole in this fragment, try to proceed on same key
1454 schoenebeck 460 if (this->itLastStolenVoice) {
1455     itSelectedVoice = this->itLastStolenVoice;
1456 schoenebeck 649 do {
1457     ++itSelectedVoice;
1458 schoenebeck 663 } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1459 schoenebeck 649 // found a "stealable" voice ?
1460 schoenebeck 663 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1461 schoenebeck 649 // remember which voice we stole, so we can simply proceed on next voice stealing
1462     this->itLastStolenVoice = itSelectedVoice;
1463 schoenebeck 460 break; // selection succeeded
1464 schoenebeck 250 }
1465     }
1466 schoenebeck 649 // get (next) oldest key
1467     RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKey) ? ++this->iuiLastStolenKey : pEngineChannel->pActiveKeys->first();
1468     while (iuiSelectedKey) {
1469     midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[*iuiSelectedKey];
1470 schoenebeck 659 itSelectedVoice = pSelectedKey->pActiveVoices->first();
1471 schoenebeck 649 // proceed iterating if voice was created in this fragment cycle
1472 schoenebeck 663 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1473 schoenebeck 649 // found a "stealable" voice ?
1474 schoenebeck 663 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1475 schoenebeck 649 // remember which voice on which key we stole, so we can simply proceed on next voice stealing
1476     this->iuiLastStolenKey = iuiSelectedKey;
1477     this->itLastStolenVoice = itSelectedVoice;
1478     break; // selection succeeded
1479     }
1480     ++iuiSelectedKey; // get next oldest key
1481     }
1482 schoenebeck 250 break;
1483     }
1484    
1485     // don't steal anything
1486     case voice_steal_algo_none:
1487     default: {
1488     dmsg(1,("No free voice (voice stealing disabled)!\n"));
1489 schoenebeck 473 return -1;
1490 schoenebeck 250 }
1491     }
1492    
1493 schoenebeck 563 // if we couldn't steal a voice from the same engine channel then
1494     // steal oldest voice on the oldest key from any other engine channel
1495 schoenebeck 649 // (the smaller engine channel number, the higher priority)
1496 schoenebeck 663 if (!itSelectedVoice || !itSelectedVoice->IsStealable()) {
1497 schoenebeck 649 EngineChannel* pSelectedChannel;
1498     int iChannelIndex;
1499     // select engine channel
1500     if (pLastStolenChannel) {
1501     pSelectedChannel = pLastStolenChannel;
1502     iChannelIndex = pSelectedChannel->iEngineIndexSelf;
1503     } else { // pick the engine channel followed by this engine channel
1504     iChannelIndex = (pEngineChannel->iEngineIndexSelf + 1) % engineChannels.size();
1505     pSelectedChannel = engineChannels[iChannelIndex];
1506     }
1507 schoenebeck 663
1508     // if we already stole in this fragment, try to proceed on same key
1509     if (this->itLastStolenVoiceGlobally) {
1510     itSelectedVoice = this->itLastStolenVoiceGlobally;
1511     do {
1512     ++itSelectedVoice;
1513     } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1514     }
1515    
1516     #if CONFIG_DEVMODE
1517     EngineChannel* pBegin = pSelectedChannel; // to detect endless loop
1518     #endif // CONFIG_DEVMODE
1519    
1520     // did we find a 'stealable' voice?
1521     if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1522     // remember which voice we stole, so we can simply proceed on next voice stealing
1523     this->itLastStolenVoiceGlobally = itSelectedVoice;
1524     } else while (true) { // iterate through engine channels
1525 schoenebeck 649 // get (next) oldest key
1526 schoenebeck 663 RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKeyGlobally) ? ++this->iuiLastStolenKeyGlobally : pSelectedChannel->pActiveKeys->first();
1527     this->iuiLastStolenKeyGlobally = RTList<uint>::Iterator(); // to prevent endless loop (see line above)
1528 schoenebeck 649 while (iuiSelectedKey) {
1529 schoenebeck 663 midi_key_info_t* pSelectedKey = &pSelectedChannel->pMIDIKeyInfo[*iuiSelectedKey];
1530 schoenebeck 649 itSelectedVoice = pSelectedKey->pActiveVoices->first();
1531     // proceed iterating if voice was created in this fragment cycle
1532 schoenebeck 663 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1533 schoenebeck 649 // found a "stealable" voice ?
1534 schoenebeck 663 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1535 schoenebeck 649 // remember which voice on which key on which engine channel we stole, so we can simply proceed on next voice stealing
1536     this->iuiLastStolenKeyGlobally = iuiSelectedKey;
1537     this->itLastStolenVoiceGlobally = itSelectedVoice;
1538     this->pLastStolenChannel = pSelectedChannel;
1539 schoenebeck 665 goto stealable_voice_found; // selection succeeded
1540 schoenebeck 649 }
1541     ++iuiSelectedKey; // get next key on current engine channel
1542     }
1543     // get next engine channel
1544 schoenebeck 460 iChannelIndex = (iChannelIndex + 1) % engineChannels.size();
1545 schoenebeck 649 pSelectedChannel = engineChannels[iChannelIndex];
1546 schoenebeck 663
1547     #if CONFIG_DEVMODE
1548     if (pSelectedChannel == pBegin) {
1549     dmsg(1,("FATAL ERROR: voice stealing endless loop!\n"));
1550     dmsg(1,("VoiceSpawnsLeft=%d.\n", VoiceSpawnsLeft));
1551     dmsg(1,("Exiting.\n"));
1552     exit(-1);
1553     }
1554     #endif // CONFIG_DEVMODE
1555 schoenebeck 460 }
1556     }
1557    
1558 schoenebeck 665 // jump point if a 'stealable' voice was found
1559     stealable_voice_found:
1560    
1561 schoenebeck 563 #if CONFIG_DEVMODE
1562 schoenebeck 473 if (!itSelectedVoice->IsActive()) {
1563     dmsg(1,("gig::Engine: ERROR, tried to steal a voice which was not active !!!\n"));
1564     return -1;
1565     }
1566 schoenebeck 563 #endif // CONFIG_DEVMODE
1567 schoenebeck 287
1568 schoenebeck 250 // now kill the selected voice
1569 schoenebeck 659 itSelectedVoice->Kill(itNoteOnEvent);
1570 schoenebeck 460
1571 schoenebeck 663 --VoiceSpawnsLeft;
1572 schoenebeck 473
1573     return 0; // success
1574 schoenebeck 250 }
1575 schoenebeck 473 else {
1576     dmsg(1,("Event pool emtpy!\n"));
1577     return -1;
1578     }
1579 schoenebeck 250 }
1580    
1581     /**
1582 schoenebeck 285 * Removes the given voice from the MIDI key's list of active voices.
1583     * This method will be called when a voice went inactive, e.g. because
1584     * it finished to playback its sample, finished its release stage or
1585     * just was killed.
1586 schoenebeck 53 *
1587 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1588 schoenebeck 285 * @param itVoice - points to the voice to be freed
1589 schoenebeck 53 */
1590 schoenebeck 411 void Engine::FreeVoice(EngineChannel* pEngineChannel, Pool<Voice>::Iterator& itVoice) {
1591 schoenebeck 271 if (itVoice) {
1592 schoenebeck 411 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoice->MIDIKey];
1593 schoenebeck 53
1594 schoenebeck 271 uint keygroup = itVoice->KeyGroup;
1595    
1596 persson 1038 // if the sample and dimension region belong to an
1597     // instrument that is unloaded, tell the disk thread to
1598     // release them
1599     if (itVoice->Orphan) {
1600     pDiskThread->OrderDeletionOfDimreg(itVoice->pDimRgn);
1601     }
1602    
1603 schoenebeck 53 // free the voice object
1604 schoenebeck 271 pVoicePool->free(itVoice);
1605 schoenebeck 53
1606 schoenebeck 287 // if no other voices left and member of a key group, remove from key group
1607     if (pKey->pActiveVoices->isEmpty() && keygroup) {
1608 schoenebeck 411 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[keygroup];
1609 schoenebeck 287 if (*ppKeyGroup == &*pKey->itSelf) *ppKeyGroup = NULL; // remove key from key group
1610 schoenebeck 53 }
1611     }
1612 schoenebeck 285 else std::cerr << "Couldn't release voice! (!itVoice)\n" << std::flush;
1613 schoenebeck 53 }
1614    
1615     /**
1616 schoenebeck 287 * Called when there's no more voice left on a key, this call will
1617     * update the key info respectively.
1618     *
1619 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1620 schoenebeck 287 * @param pKey - key which is now inactive
1621     */
1622 schoenebeck 411 void Engine::FreeKey(EngineChannel* pEngineChannel, midi_key_info_t* pKey) {
1623 schoenebeck 287 if (pKey->pActiveVoices->isEmpty()) {
1624     pKey->Active = false;
1625 schoenebeck 411 pEngineChannel->pActiveKeys->free(pKey->itSelf); // remove key from list of active keys
1626 schoenebeck 287 pKey->itSelf = RTList<uint>::Iterator();
1627     pKey->ReleaseTrigger = false;
1628     pKey->pEvents->clear();
1629     dmsg(3,("Key has no more voices now\n"));
1630     }
1631     else dmsg(1,("gig::Engine: Oops, tried to free a key which contains voices.\n"));
1632     }
1633    
1634     /**
1635 schoenebeck 53 * Reacts on supported control change commands (e.g. pitch bend wheel,
1636     * modulation wheel, aftertouch).
1637     *
1638 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1639 schoenebeck 271 * @param itControlChangeEvent - controller, value and time stamp of the event
1640 schoenebeck 53 */
1641 schoenebeck 411 void Engine::ProcessControlChange(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itControlChangeEvent) {
1642 schoenebeck 271 dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));
1643 schoenebeck 53
1644 persson 1700 // handle the "control triggered" MIDI rule: a control change
1645     // event can trigger a new note on or note off event
1646     if (pEngineChannel->pInstrument) {
1647    
1648     ::gig::MidiRule* rule;
1649     for (int i = 0 ; (rule = pEngineChannel->pInstrument->GetMidiRule(i)) ; i++) {
1650    
1651     if (::gig::MidiRuleCtrlTrigger* ctrlTrigger =
1652     dynamic_cast< ::gig::MidiRuleCtrlTrigger*>(rule)) {
1653     if (itControlChangeEvent->Param.CC.Controller ==
1654     ctrlTrigger->ControllerNumber) {
1655    
1656     uint8_t oldCCValue = pEngineChannel->ControllerTable[
1657     itControlChangeEvent->Param.CC.Controller];
1658     uint8_t newCCValue = itControlChangeEvent->Param.CC.Value;
1659    
1660     for (int i = 0 ; i < ctrlTrigger->Triggers ; i++) {
1661     ::gig::MidiRuleCtrlTrigger::trigger_t* pTrigger =
1662     &ctrlTrigger->pTriggers[i];
1663    
1664     // check if the controller has passed the
1665     // trigger point in the right direction
1666     if ((pTrigger->Descending &&
1667     oldCCValue > pTrigger->TriggerPoint &&
1668     newCCValue <= pTrigger->TriggerPoint) ||
1669     (!pTrigger->Descending &&
1670     oldCCValue < pTrigger->TriggerPoint &&
1671     newCCValue >= pTrigger->TriggerPoint)) {
1672    
1673     RTList<Event>::Iterator itNewEvent = pGlobalEvents->allocAppend();
1674     if (itNewEvent) {
1675     *itNewEvent = *itControlChangeEvent;
1676     itNewEvent->Param.Note.Key = pTrigger->Key;
1677    
1678     if (pTrigger->NoteOff || pTrigger->Velocity == 0) {
1679     itNewEvent->Type = Event::type_note_off;
1680     itNewEvent->Param.Note.Velocity = 100;
1681    
1682     ProcessNoteOff(pEngineChannel, itNewEvent);
1683     } else {
1684     itNewEvent->Type = Event::type_note_on;
1685     //TODO: if Velocity is 255, the triggered velocity should
1686     // depend on how fast the controller is moving
1687     itNewEvent->Param.Note.Velocity =
1688     pTrigger->Velocity == 255 ? 100 :
1689     pTrigger->Velocity;
1690    
1691     ProcessNoteOn(pEngineChannel, itNewEvent);
1692     }
1693     }
1694     else dmsg(1,("Event pool emtpy!\n"));
1695     }
1696     }
1697     }
1698     }
1699     }
1700     }
1701    
1702 schoenebeck 473 // update controller value in the engine channel's controller table
1703     pEngineChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;
1704    
1705 schoenebeck 1001 // handle hard coded MIDI controllers
1706 schoenebeck 769 switch (itControlChangeEvent->Param.CC.Controller) {
1707 schoenebeck 829 case 5: { // portamento time
1708     pEngineChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN;
1709     break;
1710     }
1711 schoenebeck 1041 case 6: { // data entry (currently only used for RPN controllers)
1712     if (pEngineChannel->GetMidiRpnController() == 2) { // coarse tuning in half tones
1713     int transpose = (int) itControlChangeEvent->Param.CC.Value - 64;
1714     // limit to +- two octaves for now
1715     transpose = RTMath::Min(transpose, 24);
1716     transpose = RTMath::Max(transpose, -24);
1717     pEngineChannel->GlobalTranspose = transpose;
1718 schoenebeck 1043 // workaround, so we won't have hanging notes
1719     ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1720 schoenebeck 1041 }
1721 schoenebeck 1044 // to avoid other MIDI CC #6 messages to be misenterpreted as RPN controller data
1722     pEngineChannel->ResetMidiRpnController();
1723 schoenebeck 1041 break;
1724     }
1725 schoenebeck 424 case 7: { // volume
1726     //TODO: not sample accurate yet
1727 schoenebeck 947 pEngineChannel->MidiVolume = VolumeCurve[itControlChangeEvent->Param.CC.Value];
1728 schoenebeck 660 pEngineChannel->bStatusChanged = true; // engine channel status has changed, so set notify flag
1729 schoenebeck 424 break;
1730     }
1731     case 10: { // panpot
1732     //TODO: not sample accurate yet
1733 persson 831 pEngineChannel->GlobalPanLeft = PanCurve[128 - itControlChangeEvent->Param.CC.Value];
1734     pEngineChannel->GlobalPanRight = PanCurve[itControlChangeEvent->Param.CC.Value];
1735 schoenebeck 1723 pEngineChannel->iLastPanRequest = itControlChangeEvent->Param.CC.Value;
1736 schoenebeck 424 break;
1737     }
1738     case 64: { // sustain
1739 schoenebeck 769 if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SustainPedal) {
1740 iliev 776 dmsg(4,("DAMPER (RIGHT) PEDAL DOWN\n"));
1741 schoenebeck 411 pEngineChannel->SustainPedal = true;
1742 schoenebeck 53
1743 iliev 716 #if !CONFIG_PROCESS_MUTED_CHANNELS
1744 schoenebeck 705 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1745 iliev 716 #endif
1746 schoenebeck 705
1747 schoenebeck 53 // cancel release process of voices if necessary
1748 schoenebeck 411 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1749 schoenebeck 473 for (; iuiKey; ++iuiKey) {
1750     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1751     if (!pKey->KeyPressed) {
1752     RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1753     if (itNewEvent) {
1754 schoenebeck 769 *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1755 schoenebeck 473 itNewEvent->Type = Event::type_cancel_release; // transform event type
1756 schoenebeck 53 }
1757 schoenebeck 473 else dmsg(1,("Event pool emtpy!\n"));
1758 schoenebeck 53 }
1759     }
1760     }
1761 schoenebeck 769 if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SustainPedal) {
1762 iliev 776 dmsg(4,("DAMPER (RIGHT) PEDAL UP\n"));
1763 schoenebeck 411 pEngineChannel->SustainPedal = false;
1764 schoenebeck 53
1765 iliev 716 #if !CONFIG_PROCESS_MUTED_CHANNELS
1766 schoenebeck 705 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1767 iliev 716 #endif
1768 schoenebeck 705
1769 schoenebeck 53 // release voices if their respective key is not pressed
1770 schoenebeck 411 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1771 schoenebeck 473 for (; iuiKey; ++iuiKey) {
1772     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1773 iliev 776 if (!pKey->KeyPressed && ShouldReleaseVoice(pEngineChannel, *iuiKey)) {
1774 schoenebeck 473 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1775     if (itNewEvent) {
1776 schoenebeck 769 *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1777 schoenebeck 473 itNewEvent->Type = Event::type_release; // transform event type
1778 schoenebeck 53 }
1779 schoenebeck 473 else dmsg(1,("Event pool emtpy!\n"));
1780 schoenebeck 53 }
1781     }
1782     }
1783     break;
1784     }
1785 schoenebeck 829 case 65: { // portamento on / off
1786 schoenebeck 1348 const bool bPortamento = itControlChangeEvent->Param.CC.Value >= 64;
1787     if (bPortamento != pEngineChannel->PortamentoMode)
1788     KillAllVoices(pEngineChannel, itControlChangeEvent);
1789     pEngineChannel->PortamentoMode = bPortamento;
1790 schoenebeck 829 break;
1791     }
1792 iliev 776 case 66: { // sostenuto
1793     if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SostenutoPedal) {
1794     dmsg(4,("SOSTENUTO (CENTER) PEDAL DOWN\n"));
1795     pEngineChannel->SostenutoPedal = true;
1796 schoenebeck 53
1797 iliev 776 #if !CONFIG_PROCESS_MUTED_CHANNELS
1798     if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1799     #endif
1800 schoenebeck 53
1801 iliev 776 SostenutoKeyCount = 0;
1802     // Remeber the pressed keys
1803     RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1804     for (; iuiKey; ++iuiKey) {
1805     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1806     if (pKey->KeyPressed && SostenutoKeyCount < 128) SostenutoKeys[SostenutoKeyCount++] = *iuiKey;
1807     }
1808     }
1809     if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SostenutoPedal) {
1810     dmsg(4,("SOSTENUTO (CENTER) PEDAL UP\n"));
1811     pEngineChannel->SostenutoPedal = false;
1812    
1813     #if !CONFIG_PROCESS_MUTED_CHANNELS
1814     if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1815     #endif
1816    
1817     // release voices if the damper pedal is up and their respective key is not pressed
1818     for (int i = 0; i < SostenutoKeyCount; i++) {
1819     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[SostenutoKeys[i]];
1820     if (!pKey->KeyPressed && !pEngineChannel->SustainPedal) {
1821     RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1822     if (itNewEvent) {
1823     *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1824     itNewEvent->Type = Event::type_release; // transform event type
1825     }
1826     else dmsg(1,("Event pool emtpy!\n"));
1827     }
1828     }
1829     }
1830     break;
1831     }
1832 schoenebeck 1041 case 100: { // RPN controller LSB
1833     pEngineChannel->SetMidiRpnControllerLsb(itControlChangeEvent->Param.CC.Value);
1834     break;
1835     }
1836     case 101: { // RPN controller MSB
1837     pEngineChannel->SetMidiRpnControllerMsb(itControlChangeEvent->Param.CC.Value);
1838     break;
1839     }
1840 iliev 776
1841    
1842 schoenebeck 473 // Channel Mode Messages
1843    
1844     case 120: { // all sound off
1845 schoenebeck 769 KillAllVoices(pEngineChannel, itControlChangeEvent);
1846 schoenebeck 473 break;
1847     }
1848     case 121: { // reset all controllers
1849     pEngineChannel->ResetControllers();
1850     break;
1851     }
1852     case 123: { // all notes off
1853 schoenebeck 849 #if CONFIG_PROCESS_ALL_NOTES_OFF
1854 schoenebeck 769 ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1855 schoenebeck 849 #endif // CONFIG_PROCESS_ALL_NOTES_OFF
1856 schoenebeck 473 break;
1857     }
1858 schoenebeck 829 case 126: { // mono mode on
1859 schoenebeck 1348 if (!pEngineChannel->SoloMode)
1860     KillAllVoices(pEngineChannel, itControlChangeEvent);
1861 schoenebeck 829 pEngineChannel->SoloMode = true;
1862     break;
1863     }
1864     case 127: { // poly mode on
1865 schoenebeck 1348 if (pEngineChannel->SoloMode)
1866     KillAllVoices(pEngineChannel, itControlChangeEvent);
1867 schoenebeck 829 pEngineChannel->SoloMode = false;
1868     break;
1869     }
1870 schoenebeck 473 }
1871 schoenebeck 1001
1872     // handle FX send controllers
1873     if (!pEngineChannel->fxSends.empty()) {
1874     for (int iFxSend = 0; iFxSend < pEngineChannel->GetFxSendCount(); iFxSend++) {
1875     FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
1876 schoenebeck 1715 if (pFxSend->MidiController() == itControlChangeEvent->Param.CC.Controller) {
1877 schoenebeck 1001 pFxSend->SetLevel(itControlChangeEvent->Param.CC.Value);
1878 iliev 1108 pFxSend->SetInfoChanged(true);
1879 schoenebeck 1715 }
1880 schoenebeck 1001 }
1881     }
1882 schoenebeck 53 }
1883    
1884     /**
1885 schoenebeck 244 * Reacts on MIDI system exclusive messages.
1886     *
1887 schoenebeck 271 * @param itSysexEvent - sysex data size and time stamp of the sysex event
1888 schoenebeck 244 */
1889 schoenebeck 271 void Engine::ProcessSysex(Pool<Event>::Iterator& itSysexEvent) {
1890 schoenebeck 970 RingBuffer<uint8_t,false>::NonVolatileReader reader = pSysexBuffer->get_non_volatile_reader();
1891 schoenebeck 244
1892     uint8_t exclusive_status, id;
1893     if (!reader.pop(&exclusive_status)) goto free_sysex_data;
1894     if (!reader.pop(&id)) goto free_sysex_data;
1895     if (exclusive_status != 0xF0) goto free_sysex_data;
1896    
1897     switch (id) {
1898 schoenebeck 1724 case 0x7f: { // (Realtime) Universal Sysex (GM Standard)
1899     uint8_t sysex_channel, sub_id1, sub_id2, val_msb, val_lsb;;
1900     if (!reader.pop(&sysex_channel)) goto free_sysex_data;
1901     if (!reader.pop(&sub_id1)) goto free_sysex_data;
1902     if (!reader.pop(&sub_id2)) goto free_sysex_data;
1903     if (!reader.pop(&val_lsb)) goto free_sysex_data;
1904     if (!reader.pop(&val_msb)) goto free_sysex_data;
1905     //TODO: for now we simply ignore the sysex channel, seldom used anyway
1906     switch (sub_id1) {
1907     case 0x04: // Device Control
1908     switch (sub_id2) {
1909 schoenebeck 1762 case 0x01: { // Master Volume
1910     const double volume =
1911 schoenebeck 1724 double((uint(val_msb)<<7) | uint(val_lsb)) / 16383.0;
1912 schoenebeck 1762 #if CONFIG_MASTER_VOLUME_SYSEX_BY_PORT
1913     // apply volume to all sampler channels that
1914     // are connected to the same MIDI input port
1915     // this sysex message arrived on
1916     for (int i = 0; i < engineChannels.size(); ++i) {
1917     EngineChannel* pEngineChannel = engineChannels[i];
1918     if (pEngineChannel->GetMidiInputPort() ==
1919     itSysexEvent->pMidiInputPort)
1920     {
1921     pEngineChannel->Volume(volume);
1922     }
1923     }
1924     #else
1925     // apply volume globally to the whole sampler
1926     GLOBAL_VOLUME = volume;
1927     #endif // CONFIG_MASTER_VOLUME_SYSEX_BY_PORT
1928 schoenebeck 1724 break;
1929 schoenebeck 1762 }
1930 schoenebeck 1724 }
1931     break;
1932     }
1933     break;
1934     }
1935 schoenebeck 244 case 0x41: { // Roland
1936 schoenebeck 493 dmsg(3,("Roland Sysex\n"));
1937 schoenebeck 244 uint8_t device_id, model_id, cmd_id;
1938     if (!reader.pop(&device_id)) goto free_sysex_data;
1939     if (!reader.pop(&model_id)) goto free_sysex_data;
1940     if (!reader.pop(&cmd_id)) goto free_sysex_data;
1941     if (model_id != 0x42 /*GS*/) goto free_sysex_data;
1942     if (cmd_id != 0x12 /*DT1*/) goto free_sysex_data;
1943    
1944     // command address
1945     uint8_t addr[3]; // 2 byte addr MSB, followed by 1 byte addr LSB)
1946 schoenebeck 970 const RingBuffer<uint8_t,false>::NonVolatileReader checksum_reader = reader; // so we can calculate the check sum later
1947 schoenebeck 244 if (reader.read(&addr[0], 3) != 3) goto free_sysex_data;
1948     if (addr[0] == 0x40 && addr[1] == 0x00) { // System Parameters
1949 schoenebeck 493 dmsg(3,("\tSystem Parameter\n"));
1950 schoenebeck 244 }
1951     else if (addr[0] == 0x40 && addr[1] == 0x01) { // Common Parameters
1952 schoenebeck 493 dmsg(3,("\tCommon Parameter\n"));
1953 schoenebeck 244 }
1954     else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x10) { // Part Parameters (1)
1955 schoenebeck 493 dmsg(3,("\tPart Parameter\n"));
1956     switch (addr[2]) {
1957 schoenebeck 244 case 0x40: { // scale tuning
1958 schoenebeck 493 dmsg(3,("\t\tScale Tuning\n"));
1959 schoenebeck 244 uint8_t scale_tunes[12]; // detuning of all 12 semitones of an octave
1960     if (reader.read(&scale_tunes[0], 12) != 12) goto free_sysex_data;
1961     uint8_t checksum;
1962 schoenebeck 493 if (!reader.pop(&checksum)) goto free_sysex_data;
1963 schoenebeck 563 #if CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1964     if (GSCheckSum(checksum_reader, 12)) goto free_sysex_data;
1965     #endif // CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1966 schoenebeck 244 for (int i = 0; i < 12; i++) scale_tunes[i] -= 64;
1967     AdjustScale((int8_t*) scale_tunes);
1968 schoenebeck 493 dmsg(3,("\t\t\tNew scale applied.\n"));
1969 schoenebeck 244 break;
1970     }
1971 schoenebeck 1750 case 0x15: { // chromatic / drumkit mode
1972     dmsg(3,("\t\tMIDI Instrument Map Switch\n"));
1973     uint8_t part = addr[1] & 0x0f;
1974     uint8_t map;
1975     if (!reader.pop(&map)) goto free_sysex_data;
1976     for (int i = 0; i < engineChannels.size(); ++i) {
1977     EngineChannel* pEngineChannel = engineChannels[i];
1978 schoenebeck 1751 if (
1979     (pEngineChannel->midiChannel == part ||
1980     pEngineChannel->midiChannel == midi_chan_all) &&
1981 schoenebeck 1762 pEngineChannel->GetMidiInputPort() == itSysexEvent->pMidiInputPort
1982 schoenebeck 1750 ) {
1983     try {
1984     pEngineChannel->SetMidiInstrumentMap(map);
1985     } catch (Exception e) {
1986     dmsg(2,("\t\t\tCould not apply MIDI instrument map %d to part %d: %s\n", map, part, e.Message().c_str()));
1987     goto free_sysex_data;
1988     } catch (...) {
1989     dmsg(2,("\t\t\tCould not apply MIDI instrument map %d to part %d (unknown exception)\n", map, part));
1990     goto free_sysex_data;
1991     }
1992     }
1993     }
1994     dmsg(3,("\t\t\tApplied MIDI instrument map %d to part %d.\n", map, part));
1995     break;
1996     }
1997 schoenebeck 244 }
1998     }
1999     else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x20) { // Part Parameters (2)
2000     }
2001     else if (addr[0] == 0x41) { // Drum Setup Parameters
2002     }
2003     break;
2004     }
2005     }
2006    
2007     free_sysex_data: // finally free sysex data
2008 schoenebeck 271 pSysexBuffer->increment_read_ptr(itSysexEvent->Param.Sysex.Size);
2009 schoenebeck 244 }
2010    
2011     /**
2012     * Calculates the Roland GS sysex check sum.
2013     *
2014     * @param AddrReader - reader which currently points to the first GS
2015     * command address byte of the GS sysex message in
2016     * question
2017     * @param DataSize - size of the GS message data (in bytes)
2018     */
2019 schoenebeck 970 uint8_t Engine::GSCheckSum(const RingBuffer<uint8_t,false>::NonVolatileReader AddrReader, uint DataSize) {
2020     RingBuffer<uint8_t,false>::NonVolatileReader reader = AddrReader;
2021 schoenebeck 244 uint bytes = 3 /*addr*/ + DataSize;
2022     uint8_t addr_and_data[bytes];
2023     reader.read(&addr_and_data[0], bytes);
2024     uint8_t sum = 0;
2025     for (uint i = 0; i < bytes; i++) sum += addr_and_data[i];
2026     return 128 - sum % 128;
2027     }
2028    
2029     /**
2030     * Allows to tune each of the twelve semitones of an octave.
2031     *
2032     * @param ScaleTunes - detuning of all twelve semitones (in cents)
2033     */
2034     void Engine::AdjustScale(int8_t ScaleTunes[12]) {
2035     memcpy(&this->ScaleTuning[0], &ScaleTunes[0], 12); //TODO: currently not sample accurate
2036     }
2037    
2038     /**
2039 schoenebeck 473 * Releases all voices on an engine channel. All voices will go into
2040     * the release stage and thus it might take some time (e.g. dependant to
2041     * their envelope release time) until they actually die.
2042     *
2043     * @param pEngineChannel - engine channel on which all voices should be released
2044     * @param itReleaseEvent - event which caused this releasing of all voices
2045     */
2046     void Engine::ReleaseAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itReleaseEvent) {
2047     RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
2048     while (iuiKey) {
2049     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
2050     ++iuiKey;
2051     // append a 'release' event to the key's own event list
2052     RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
2053     if (itNewEvent) {
2054     *itNewEvent = *itReleaseEvent; // copy original event (to the key's event list)
2055     itNewEvent->Type = Event::type_release; // transform event type
2056     }
2057     else dmsg(1,("Event pool emtpy!\n"));
2058     }
2059     }
2060    
2061     /**
2062     * Kills all voices on an engine channel as soon as possible. Voices
2063     * won't get into release state, their volume level will be ramped down
2064     * as fast as possible.
2065     *
2066     * @param pEngineChannel - engine channel on which all voices should be killed
2067     * @param itKillEvent - event which caused this killing of all voices
2068     */
2069     void Engine::KillAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itKillEvent) {
2070     RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
2071     RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
2072     while (iuiKey != end) { // iterate through all active keys
2073     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
2074     ++iuiKey;
2075     RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
2076     RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
2077     for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
2078     itVoice->Kill(itKillEvent);
2079 schoenebeck 663 --VoiceSpawnsLeft; //FIXME: just a temporary workaround, we should check the cause in StealVoice() instead
2080 schoenebeck 473 }
2081     }
2082     }
2083    
2084 iliev 776 /**
2085     * Determines whether the specified voice should be released.
2086     *
2087     * @param pEngineChannel - The engine channel on which the voice should be checked
2088     * @param Key - The key number
2089     * @returns true if the specified should be released, false otherwise.
2090     */
2091     bool Engine::ShouldReleaseVoice(EngineChannel* pEngineChannel, int Key) {
2092     if (pEngineChannel->SustainPedal) return false;
2093    
2094     if (pEngineChannel->SostenutoPedal) {
2095     for (int i = 0; i < SostenutoKeyCount; i++)
2096     if (Key == SostenutoKeys[i]) return false;
2097     }
2098    
2099     return true;
2100     }
2101    
2102 schoenebeck 53 uint Engine::VoiceCount() {
2103     return ActiveVoiceCount;
2104     }
2105    
2106     uint Engine::VoiceCountMax() {
2107     return ActiveVoiceCountMax;
2108     }
2109    
2110     bool Engine::DiskStreamSupported() {
2111     return true;
2112     }
2113    
2114     uint Engine::DiskStreamCount() {
2115     return (pDiskThread) ? pDiskThread->ActiveStreamCount : 0;
2116     }
2117    
2118     uint Engine::DiskStreamCountMax() {
2119     return (pDiskThread) ? pDiskThread->ActiveStreamCountMax : 0;
2120     }
2121    
2122     String Engine::DiskStreamBufferFillBytes() {
2123     return pDiskThread->GetBufferFillBytes();
2124     }
2125    
2126     String Engine::DiskStreamBufferFillPercentage() {
2127     return pDiskThread->GetBufferFillPercentage();
2128     }
2129    
2130 senkov 112 String Engine::EngineName() {
2131 schoenebeck 475 return LS_GIG_ENGINE_NAME;
2132 senkov 112 }
2133    
2134 schoenebeck 53 String Engine::Description() {
2135 schoenebeck 1555 return "Gigasampler Format Engine";
2136 schoenebeck 53 }
2137    
2138     String Engine::Version() {
2139 persson 1764 String s = "$Revision: 1.97 $";
2140 schoenebeck 123 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
2141 schoenebeck 53 }
2142    
2143 schoenebeck 947 InstrumentManager* Engine::GetInstrumentManager() {
2144     return &instruments;
2145     }
2146    
2147 persson 831 // static constant initializers
2148 persson 1644 const Engine::FloatTable Engine::VolumeCurve(InitVolumeCurve());
2149     const Engine::FloatTable Engine::PanCurve(InitPanCurve());
2150     const Engine::FloatTable Engine::CrossfadeCurve(InitCrossfadeCurve());
2151 persson 831
2152     float* Engine::InitVolumeCurve() {
2153     // line-segment approximation
2154     const float segments[] = {
2155     0, 0, 2, 0.0046, 16, 0.016, 31, 0.051, 45, 0.115, 54.5, 0.2,
2156     64.5, 0.39, 74, 0.74, 92, 1.03, 114, 1.94, 119.2, 2.2, 127, 2.2
2157     };
2158     return InitCurve(segments);
2159     }
2160    
2161     float* Engine::InitPanCurve() {
2162     // line-segment approximation
2163     const float segments[] = {
2164     0, 0, 1, 0,
2165     2, 0.05, 31.5, 0.7, 51, 0.851, 74.5, 1.12,
2166     127, 1.41, 128, 1.41
2167     };
2168     return InitCurve(segments, 129);
2169     }
2170    
2171 persson 832 float* Engine::InitCrossfadeCurve() {
2172     // line-segment approximation
2173     const float segments[] = {
2174     0, 0, 1, 0.03, 10, 0.1, 51, 0.58, 127, 1
2175     };
2176     return InitCurve(segments);
2177     }
2178    
2179 persson 831 float* Engine::InitCurve(const float* segments, int size) {
2180     float* y = new float[size];
2181     for (int x = 0 ; x < size ; x++) {
2182     if (x > segments[2]) segments += 2;
2183     y[x] = segments[1] + (x - segments[0]) *
2184     (segments[3] - segments[1]) / (segments[2] - segments[0]);
2185     }
2186     return y;
2187     }
2188    
2189 schoenebeck 53 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC