/[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 1700 - (hide annotations) (download)
Sun Feb 17 12:40:59 2008 UTC (16 years, 1 month ago) by persson
File size: 102666 byte(s)
* added partial support for the "Controller Triggered" MIDI rule,
  enough for piano gigs with pedal noise samples

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 schoenebeck 285 // FIXME: audio drivers with varying fragment sizes might be a problem here
362 schoenebeck 554 MaxFadeOutPos = MaxSamplesPerCycle - int(double(SampleRate) * CONFIG_EG_MIN_RELEASE_TIME) - 1;
363 schoenebeck 688 if (MaxFadeOutPos < 0) {
364     std::cerr << "gig::Engine: WARNING, CONFIG_EG_MIN_RELEASE_TIME "
365     << "too big for current audio fragment size & sampling rate! "
366 schoenebeck 690 << "May lead to click sounds if voice stealing chimes in!\n" << std::flush;
367 schoenebeck 688 // force volume ramp downs at the beginning of each fragment
368     MaxFadeOutPos = 0;
369     // lower minimum release time
370     const float minReleaseTime = (float) MaxSamplesPerCycle / (float) SampleRate;
371     for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
372 schoenebeck 738 iterVoice->EG1.CalculateFadeOutCoeff(minReleaseTime, SampleRate);
373 schoenebeck 688 }
374     pVoicePool->clear();
375     }
376 schoenebeck 285
377 schoenebeck 53 // (re)create disk thread
378     if (this->pDiskThread) {
379 senkov 329 dmsg(1,("Stopping disk thread..."));
380 schoenebeck 53 this->pDiskThread->StopThread();
381     delete this->pDiskThread;
382 senkov 329 dmsg(1,("OK\n"));
383 schoenebeck 53 }
384 persson 1038 this->pDiskThread = new DiskThread(((pAudioOut->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6, //FIXME: assuming stereo
385     &instruments);
386 schoenebeck 53 if (!pDiskThread) {
387     dmsg(0,("gig::Engine new diskthread = NULL\n"));
388     exit(EXIT_FAILURE);
389     }
390    
391 schoenebeck 271 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
392     iterVoice->pDiskThread = this->pDiskThread;
393 schoenebeck 53 dmsg(3,("d"));
394     }
395     pVoicePool->clear();
396    
397     // (re)create event generator
398     if (pEventGenerator) delete pEventGenerator;
399     pEventGenerator = new EventGenerator(pAudioOut->SampleRate());
400    
401     dmsg(1,("Starting disk thread..."));
402     pDiskThread->StartThread();
403     dmsg(1,("OK\n"));
404    
405 schoenebeck 271 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
406     if (!iterVoice->pDiskThread) {
407 schoenebeck 53 dmsg(0,("Engine -> voice::trigger: !pDiskThread\n"));
408     exit(EXIT_FAILURE);
409     }
410     }
411     }
412    
413 schoenebeck 473 /**
414 schoenebeck 1321 * Called by the engine's (audio) thread once per cycle to process requests
415     * from the outer world to suspend or resume a given @c gig::Region .
416     */
417     void Engine::ProcessSuspensionsChanges() {
418     // process request for suspending one region
419     if (pPendingRegionSuspension) {
420     // kill all voices on all engine channels that use this region
421     for (int iChannel = 0; iChannel < engineChannels.size(); iChannel++) {
422     EngineChannel* pEngineChannel = engineChannels[iChannel];
423     RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
424     RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
425     for (; iuiKey != end; ++iuiKey) { // iterate through all active keys
426     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
427     RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
428     // if current key is not associated with this region, skip this key
429     if (itVoice->pDimRgn->GetParent() != pPendingRegionSuspension) continue;
430     RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
431     for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
432     // request a notification from disk thread side for stream deletion
433     const Stream::Handle hStream = itVoice->KillImmediately(true);
434     if (hStream != Stream::INVALID_HANDLE) { // voice actually used a stream
435     iPendingStreamDeletions++;
436     }
437     }
438     }
439     }
440     // make sure the region is not yet on the list
441     bool bAlreadySuspended = false;
442     RTList< ::gig::Region*>::Iterator iter = SuspendedRegions.first();
443     RTList< ::gig::Region*>::Iterator end = SuspendedRegions.end();
444     for (; iter != end; ++iter) { // iterate through all suspended regions
445     if (*iter == pPendingRegionSuspension) { // found
446     bAlreadySuspended = true;
447     dmsg(1,("gig::Engine: attempt to suspend an already suspended region !!!\n"));
448     break;
449     }
450     }
451     if (!bAlreadySuspended) {
452     // put the region on the list of suspended regions
453     RTList< ::gig::Region*>::Iterator iter = SuspendedRegions.allocAppend();
454     if (iter) {
455     *iter = pPendingRegionSuspension;
456     } else std::cerr << "gig::Engine: Could not suspend Region, list is full. This is a bug!!!\n" << std::flush;
457     }
458     // free request slot for next caller (and to make sure that
459     // we're not going to process the same request in the next cycle)
460     pPendingRegionSuspension = NULL;
461 persson 1646 // if no disk stream deletions are pending, awaken other side, as
462 schoenebeck 1321 // we're done in this case
463     if (!iPendingStreamDeletions) SuspensionChangeOngoing.Set(false);
464     }
465    
466     // process request for resuming one region
467     if (pPendingRegionResumption) {
468     // remove region from the list of suspended regions
469     RTList< ::gig::Region*>::Iterator iter = SuspendedRegions.first();
470     RTList< ::gig::Region*>::Iterator end = SuspendedRegions.end();
471     for (; iter != end; ++iter) { // iterate through all suspended regions
472     if (*iter == pPendingRegionResumption) { // found
473     SuspendedRegions.free(iter);
474     break; // done
475     }
476     }
477     // free request slot for next caller
478     pPendingRegionResumption = NULL;
479     // awake other side as we're done
480     SuspensionChangeOngoing.Set(false);
481     }
482     }
483    
484     /**
485     * Called by the engine's (audio) thread once per cycle to check if
486     * streams of voices that were killed due to suspension request have
487     * finally really been deleted by the disk thread.
488     */
489     void Engine::ProcessPendingStreamDeletions() {
490     if (!iPendingStreamDeletions) return;
491     //TODO: or shall we better store a list with stream handles instead of a scalar amount of streams to be deleted? might be safer
492     while (
493     iPendingStreamDeletions &&
494     pDiskThread->AskForDeletedStream() != Stream::INVALID_HANDLE
495     ) iPendingStreamDeletions--;
496     // just for safety ...
497     while (pDiskThread->AskForDeletedStream() != Stream::INVALID_HANDLE);
498     // now that all disk streams are deleted, awake other side as
499     // we're finally done with suspending the requested region
500     if (!iPendingStreamDeletions) SuspensionChangeOngoing.Set(false);
501     }
502    
503     /**
504     * Returns @c true if the given region is currently set to be suspended
505     * from being used, @c false otherwise.
506     */
507     bool Engine::RegionSuspended(::gig::Region* pRegion) {
508     if (SuspendedRegions.isEmpty()) return false;
509     //TODO: or shall we use a sorted container instead of the RTList? might be faster ... or trivial ;-)
510     RTList< ::gig::Region*>::Iterator iter = SuspendedRegions.first();
511     RTList< ::gig::Region*>::Iterator end = SuspendedRegions.end();
512     for (; iter != end; ++iter) // iterate through all suspended regions
513     if (*iter == pRegion) return true;
514     return false;
515     }
516    
517     /**
518 schoenebeck 473 * Clear all engine global event lists.
519     */
520 schoenebeck 412 void Engine::ClearEventLists() {
521 schoenebeck 460 pGlobalEvents->clear();
522 schoenebeck 412 }
523    
524 schoenebeck 53 /**
525 schoenebeck 460 * Copy all events from the engine's global input queue buffer to the
526     * engine's internal event list. This will be done at the beginning of
527     * each audio cycle (that is each RenderAudio() call) to distinguish
528     * all global events which have to be processed in the current audio
529     * cycle. These events are usually just SysEx messages. Every
530     * EngineChannel has it's own input event queue buffer and event list
531     * to handle common events like NoteOn, NoteOff and ControlChange
532     * events.
533 schoenebeck 412 *
534 schoenebeck 460 * @param Samples - number of sample points to be processed in the
535     * current audio cycle
536 schoenebeck 412 */
537 schoenebeck 460 void Engine::ImportEvents(uint Samples) {
538 schoenebeck 970 RingBuffer<Event,false>::NonVolatileReader eventQueueReader = pEventQueue->get_non_volatile_reader();
539 schoenebeck 412 Event* pEvent;
540     while (true) {
541     // get next event from input event queue
542     if (!(pEvent = eventQueueReader.pop())) break;
543     // if younger event reached, ignore that and all subsequent ones for now
544     if (pEvent->FragmentPos() >= Samples) {
545     eventQueueReader--;
546     dmsg(2,("Younger Event, pos=%d ,Samples=%d!\n",pEvent->FragmentPos(),Samples));
547     pEvent->ResetFragmentPos();
548     break;
549     }
550     // copy event to internal event list
551 schoenebeck 460 if (pGlobalEvents->poolIsEmpty()) {
552 schoenebeck 412 dmsg(1,("Event pool emtpy!\n"));
553     break;
554     }
555 schoenebeck 460 *pGlobalEvents->allocAppend() = *pEvent;
556 schoenebeck 412 }
557     eventQueueReader.free(); // free all copied events from input queue
558 persson 438 }
559 schoenebeck 412
560     /**
561 schoenebeck 924 * Let this engine proceed to render the given amount of sample points.
562     * The engine will iterate through all engine channels and render audio
563     * for each engine channel independently. The calculated audio data of
564     * all voices of each engine channel will be placed into the audio sum
565     * buffers of the respective audio output device, connected to the
566     * respective engine channel.
567 schoenebeck 53 *
568     * @param Samples - number of sample points to be rendered
569     * @returns 0 on success
570     */
571 schoenebeck 412 int Engine::RenderAudio(uint Samples) {
572 senoner 1481 dmsg(8,("RenderAudio(Samples=%d)\n", Samples));
573 schoenebeck 53
574 schoenebeck 412 // return if engine disabled
575 schoenebeck 53 if (EngineDisabled.Pop()) {
576     dmsg(5,("gig::Engine: engine disabled (val=%d)\n",EngineDisabled.GetUnsafe()));
577     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 schoenebeck 412 return 0;
703     }
704    
705 schoenebeck 473 /**
706     * Dispatch and handle all events in this audio fragment for the given
707     * engine channel.
708     *
709     * @param pEngineChannel - engine channel on which events should be
710     * processed
711     * @param Samples - amount of sample points to be processed in
712     * this audio fragment cycle
713     */
714 schoenebeck 460 void Engine::ProcessEvents(EngineChannel* pEngineChannel, uint Samples) {
715 schoenebeck 412 // get all events from the engine channels's input event queue which belong to the current fragment
716     // (these are the common events like NoteOn, NoteOff, ControlChange, etc.)
717 schoenebeck 460 pEngineChannel->ImportEvents(Samples);
718 schoenebeck 53
719     // process events
720 schoenebeck 271 {
721 schoenebeck 460 RTList<Event>::Iterator itEvent = pEngineChannel->pEvents->first();
722     RTList<Event>::Iterator end = pEngineChannel->pEvents->end();
723 schoenebeck 271 for (; itEvent != end; ++itEvent) {
724     switch (itEvent->Type) {
725     case Event::type_note_on:
726     dmsg(5,("Engine: Note on received\n"));
727 schoenebeck 412 ProcessNoteOn((EngineChannel*)itEvent->pEngineChannel, itEvent);
728 schoenebeck 271 break;
729     case Event::type_note_off:
730     dmsg(5,("Engine: Note off received\n"));
731 schoenebeck 412 ProcessNoteOff((EngineChannel*)itEvent->pEngineChannel, itEvent);
732 schoenebeck 271 break;
733     case Event::type_control_change:
734     dmsg(5,("Engine: MIDI CC received\n"));
735 schoenebeck 412 ProcessControlChange((EngineChannel*)itEvent->pEngineChannel, itEvent);
736 schoenebeck 271 break;
737     case Event::type_pitchbend:
738     dmsg(5,("Engine: Pitchbend received\n"));
739 schoenebeck 412 ProcessPitchbend((EngineChannel*)itEvent->pEngineChannel, itEvent);
740 schoenebeck 271 break;
741     }
742 schoenebeck 53 }
743     }
744 schoenebeck 649
745     // reset voice stealing for the next engine channel (or next audio fragment)
746     itLastStolenVoice = RTList<Voice>::Iterator();
747     itLastStolenVoiceGlobally = RTList<Voice>::Iterator();
748     iuiLastStolenKey = RTList<uint>::Iterator();
749     iuiLastStolenKeyGlobally = RTList<uint>::Iterator();
750     pLastStolenChannel = NULL;
751 schoenebeck 460 }
752 schoenebeck 53
753 schoenebeck 473 /**
754     * Render all 'normal' voices (that is voices which were not stolen in
755     * this fragment) on the given engine channel.
756     *
757     * @param pEngineChannel - engine channel on which audio should be
758     * rendered
759     * @param Samples - amount of sample points to be rendered in
760     * this audio fragment cycle
761     */
762 schoenebeck 460 void Engine::RenderActiveVoices(EngineChannel* pEngineChannel, uint Samples) {
763 iliev 716 #if !CONFIG_PROCESS_MUTED_CHANNELS
764 schoenebeck 705 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
765 iliev 716 #endif
766 schoenebeck 705
767 iliev 1305 uint voiceCount = 0;
768     uint streamCount = 0;
769 schoenebeck 460 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
770     RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
771     while (iuiKey != end) { // iterate through all active keys
772     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
773     ++iuiKey;
774 schoenebeck 53
775 schoenebeck 460 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
776     RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
777     for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
778     // now render current voice
779     itVoice->Render(Samples);
780 iliev 1297 if (itVoice->IsActive()) { // still active
781 persson 1646 if (!itVoice->Orphan) {
782     *(pEngineChannel->pDimRegionsInUse->allocAppend()) = itVoice->pDimRgn;
783     }
784 iliev 1297 ActiveVoiceCountTemp++;
785 iliev 1305 voiceCount++;
786 iliev 1297
787     if (itVoice->PlaybackState == Voice::playback_state_disk) {
788 iliev 1305 if ((itVoice->DiskStreamRef).State == Stream::state_active) streamCount++;
789 iliev 1297 }
790     } else { // voice reached end, is now inactive
791 schoenebeck 460 FreeVoice(pEngineChannel, itVoice); // remove voice from the list of active voices
792 schoenebeck 53 }
793     }
794     }
795 schoenebeck 1348
796 iliev 1305 pEngineChannel->SetVoiceCount(voiceCount);
797     pEngineChannel->SetDiskStreamCount(streamCount);
798 schoenebeck 460 }
799 schoenebeck 53
800 schoenebeck 473 /**
801     * Render all stolen voices (only voices which were stolen in this
802     * fragment) on the given engine channel. Stolen voices are rendered
803     * after all normal voices have been rendered; this is needed to render
804     * audio of those voices which were selected for voice stealing until
805     * the point were the stealing (that is the take over of the voice)
806     * actually happened.
807     *
808     * @param pEngineChannel - engine channel on which audio should be
809     * rendered
810     * @param Samples - amount of sample points to be rendered in
811     * this audio fragment cycle
812     */
813 schoenebeck 460 void Engine::RenderStolenVoices(uint Samples) {
814     RTList<Event>::Iterator itVoiceStealEvent = pVoiceStealingQueue->first();
815     RTList<Event>::Iterator end = pVoiceStealingQueue->end();
816     for (; itVoiceStealEvent != end; ++itVoiceStealEvent) {
817     EngineChannel* pEngineChannel = (EngineChannel*) itVoiceStealEvent->pEngineChannel;
818 persson 1038 if (!pEngineChannel->pInstrument) continue; // ignore if no instrument loaded
819 schoenebeck 460 Pool<Voice>::Iterator itNewVoice =
820 schoenebeck 668 LaunchVoice(pEngineChannel, itVoiceStealEvent, itVoiceStealEvent->Param.Note.Layer, itVoiceStealEvent->Param.Note.ReleaseTrigger, false, false);
821 schoenebeck 460 if (itNewVoice) {
822     itNewVoice->Render(Samples);
823 iliev 1297 if (itNewVoice->IsActive()) { // still active
824 persson 1646 *(pEngineChannel->pDimRegionsInUse->allocAppend()) = itNewVoice->pDimRgn;
825 iliev 1297 ActiveVoiceCountTemp++;
826     pEngineChannel->SetVoiceCount(pEngineChannel->GetVoiceCount() + 1);
827    
828     if (itNewVoice->PlaybackState == Voice::playback_state_disk) {
829     if (itNewVoice->DiskStreamRef.State == Stream::state_active) {
830     pEngineChannel->SetDiskStreamCount(pEngineChannel->GetDiskStreamCount() + 1);
831     }
832     }
833     } else { // voice reached end, is now inactive
834 schoenebeck 460 FreeVoice(pEngineChannel, itNewVoice); // remove voice from the list of active voices
835 schoenebeck 250 }
836     }
837 schoenebeck 460 else dmsg(1,("gig::Engine: ERROR, voice stealing didn't work out!\n"));
838 schoenebeck 473
839     // we need to clear the key's event list explicitly here in case key was never active
840     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoiceStealEvent->Param.Note.Key];
841     pKey->VoiceTheftsQueued--;
842     if (!pKey->Active && !pKey->VoiceTheftsQueued) pKey->pEvents->clear();
843 schoenebeck 250 }
844 schoenebeck 460 }
845 schoenebeck 250
846 schoenebeck 473 /**
847 schoenebeck 1001 * Will be called in case the respective engine channel sports FX send
848     * channels. In this particular case, engine channel local buffers are
849     * used to render and mix all voices to. This method is responsible for
850     * copying the audio data from those local buffers to the master audio
851     * output channels as well as to the FX send audio output channels with
852     * their respective FX send levels.
853     *
854     * @param pEngineChannel - engine channel from which audio should be
855     * routed
856     * @param Samples - amount of sample points to be routed in
857     * this audio fragment cycle
858     */
859     void Engine::RouteAudio(EngineChannel* pEngineChannel, uint Samples) {
860     // route master signal
861     {
862     AudioChannel* pDstL = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelLeft);
863     AudioChannel* pDstR = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelRight);
864 schoenebeck 1037 pEngineChannel->pChannelLeft->MixTo(pDstL, Samples);
865     pEngineChannel->pChannelRight->MixTo(pDstR, Samples);
866 schoenebeck 1001 }
867     // route FX send signal
868     {
869     for (int iFxSend = 0; iFxSend < pEngineChannel->GetFxSendCount(); iFxSend++) {
870     FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
871     // left channel
872     const int iDstL = pFxSend->DestinationChannel(0);
873     if (iDstL < 0) {
874     dmsg(1,("Engine::RouteAudio() Error: invalid FX send (L) destination channel"));
875     } else {
876     AudioChannel* pDstL = pAudioOutputDevice->Channel(iDstL);
877     if (!pDstL) {
878     dmsg(1,("Engine::RouteAudio() Error: invalid FX send (L) destination channel"));
879 schoenebeck 1037 } else pEngineChannel->pChannelLeft->MixTo(pDstL, Samples, pFxSend->Level());
880 schoenebeck 1001 }
881     // right channel
882     const int iDstR = pFxSend->DestinationChannel(1);
883     if (iDstR < 0) {
884     dmsg(1,("Engine::RouteAudio() Error: invalid FX send (R) destination channel"));
885     } else {
886     AudioChannel* pDstR = pAudioOutputDevice->Channel(iDstR);
887     if (!pDstR) {
888     dmsg(1,("Engine::RouteAudio() Error: invalid FX send (R) destination channel"));
889 schoenebeck 1037 } else pEngineChannel->pChannelRight->MixTo(pDstR, Samples, pFxSend->Level());
890 schoenebeck 1001 }
891     }
892     }
893     // reset buffers with silence (zero out) for the next audio cycle
894     pEngineChannel->pChannelLeft->Clear();
895     pEngineChannel->pChannelRight->Clear();
896     }
897    
898     /**
899 schoenebeck 473 * Free all keys which have turned inactive in this audio fragment, from
900     * the list of active keys and clear all event lists on that engine
901     * channel.
902     *
903     * @param pEngineChannel - engine channel to cleanup
904     */
905 schoenebeck 460 void Engine::PostProcess(EngineChannel* pEngineChannel) {
906 schoenebeck 287 // free all keys which have no active voices left
907     {
908 schoenebeck 411 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
909     RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
910 schoenebeck 287 while (iuiKey != end) { // iterate through all active keys
911 schoenebeck 411 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
912 schoenebeck 287 ++iuiKey;
913 schoenebeck 411 if (pKey->pActiveVoices->isEmpty()) FreeKey(pEngineChannel, pKey);
914 schoenebeck 554 #if CONFIG_DEVMODE
915 schoenebeck 563 else { // just a sanity check for debugging
916 schoenebeck 287 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
917     RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
918     for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
919     if (itVoice->itKillEvent) {
920     dmsg(1,("gig::Engine: ERROR, killed voice survived !!!\n"));
921     }
922     }
923     }
924 schoenebeck 554 #endif // CONFIG_DEVMODE
925 schoenebeck 287 }
926     }
927 schoenebeck 460
928     // empty the engine channel's own event lists
929     pEngineChannel->ClearEventLists();
930 schoenebeck 412 }
931 schoenebeck 287
932 schoenebeck 53 /**
933 schoenebeck 244 * Will be called by the MIDI input device whenever a MIDI system
934     * exclusive message has arrived.
935     *
936     * @param pData - pointer to sysex data
937     * @param Size - lenght of sysex data (in bytes)
938     */
939     void Engine::SendSysex(void* pData, uint Size) {
940 schoenebeck 246 Event event = pEventGenerator->CreateEvent();
941     event.Type = Event::type_sysex;
942     event.Param.Sysex.Size = Size;
943 schoenebeck 412 event.pEngineChannel = NULL; // as Engine global event
944 schoenebeck 244 if (pEventQueue->write_space() > 0) {
945     if (pSysexBuffer->write_space() >= Size) {
946     // copy sysex data to input buffer
947     uint toWrite = Size;
948     uint8_t* pPos = (uint8_t*) pData;
949     while (toWrite) {
950     const uint writeNow = RTMath::Min(toWrite, pSysexBuffer->write_space_to_end());
951     pSysexBuffer->write(pPos, writeNow);
952     toWrite -= writeNow;
953     pPos += writeNow;
954    
955     }
956     // finally place sysex event into input event queue
957     pEventQueue->push(&event);
958     }
959 schoenebeck 554 else dmsg(1,("Engine: Sysex message too large (%d byte) for input buffer (%d byte)!",Size,CONFIG_SYSEX_BUFFER_SIZE));
960 schoenebeck 244 }
961     else dmsg(1,("Engine: Input event queue full!"));
962     }
963    
964     /**
965 schoenebeck 53 * Assigns and triggers a new voice for the respective MIDI key.
966     *
967 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
968 schoenebeck 271 * @param itNoteOnEvent - key, velocity and time stamp of the event
969 schoenebeck 53 */
970 schoenebeck 411 void Engine::ProcessNoteOn(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
971 iliev 716 #if !CONFIG_PROCESS_MUTED_CHANNELS
972     if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
973     #endif
974 persson 438
975 persson 1038 if (!pEngineChannel->pInstrument) return; // ignore if no instrument loaded
976    
977 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
978     itNoteOnEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
979    
980 schoenebeck 354 const int key = itNoteOnEvent->Param.Note.Key;
981 schoenebeck 829 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key];
982 schoenebeck 354
983 schoenebeck 829 // move note on event to the key's own event list
984     RTList<Event>::Iterator itNoteOnEventOnKeyList = itNoteOnEvent.moveToEndOf(pKey->pEvents);
985    
986     // if Solo Mode then kill all already active voices
987     if (pEngineChannel->SoloMode) {
988     Pool<uint>::Iterator itYoungestKey = pEngineChannel->pActiveKeys->last();
989     if (itYoungestKey) {
990     const int iYoungestKey = *itYoungestKey;
991     const midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[iYoungestKey];
992     if (pOtherKey->Active) {
993     // get final portamento position of currently active voice
994     if (pEngineChannel->PortamentoMode) {
995     RTList<Voice>::Iterator itVoice = pOtherKey->pActiveVoices->last();
996     if (itVoice) itVoice->UpdatePortamentoPos(itNoteOnEventOnKeyList);
997     }
998     // kill all voices on the (other) key
999     RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
1000     RTList<Voice>::Iterator end = pOtherKey->pActiveVoices->end();
1001     for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
1002     if (itVoiceToBeKilled->Type != Voice::type_release_trigger)
1003     itVoiceToBeKilled->Kill(itNoteOnEventOnKeyList);
1004     }
1005     }
1006     }
1007     // set this key as 'currently active solo key'
1008     pEngineChannel->SoloKey = key;
1009     }
1010    
1011 schoenebeck 354 // Change key dimension value if key is in keyswitching area
1012 schoenebeck 411 {
1013     const ::gig::Instrument* pInstrument = pEngineChannel->pInstrument;
1014     if (key >= pInstrument->DimensionKeyRange.low && key <= pInstrument->DimensionKeyRange.high)
1015 persson 865 pEngineChannel->CurrentKeyDimension = float(key - pInstrument->DimensionKeyRange.low) /
1016 schoenebeck 411 (pInstrument->DimensionKeyRange.high - pInstrument->DimensionKeyRange.low + 1);
1017     }
1018 schoenebeck 354
1019 schoenebeck 53 pKey->KeyPressed = true; // the MIDI key was now pressed down
1020 schoenebeck 829 pKey->Velocity = itNoteOnEventOnKeyList->Param.Note.Velocity;
1021     pKey->NoteOnTime = FrameTime + itNoteOnEventOnKeyList->FragmentPos(); // will be used to calculate note length
1022 schoenebeck 53
1023     // cancel release process of voices on this key if needed
1024 schoenebeck 411 if (pKey->Active && !pEngineChannel->SustainPedal) {
1025 schoenebeck 271 RTList<Event>::Iterator itCancelReleaseEvent = pKey->pEvents->allocAppend();
1026     if (itCancelReleaseEvent) {
1027 schoenebeck 829 *itCancelReleaseEvent = *itNoteOnEventOnKeyList; // copy event
1028 schoenebeck 271 itCancelReleaseEvent->Type = Event::type_cancel_release; // transform event type
1029 schoenebeck 239 }
1030     else dmsg(1,("Event pool emtpy!\n"));
1031 schoenebeck 53 }
1032    
1033 schoenebeck 460 // allocate and trigger new voice(s) for the key
1034     {
1035     // first, get total amount of required voices (dependant on amount of layers)
1036     ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOnEventOnKeyList->Param.Note.Key);
1037 schoenebeck 1321 if (pRegion && !RegionSuspended(pRegion)) {
1038 schoenebeck 460 int voicesRequired = pRegion->Layers;
1039     // now launch the required amount of voices
1040     for (int i = 0; i < voicesRequired; i++)
1041 schoenebeck 668 LaunchVoice(pEngineChannel, itNoteOnEventOnKeyList, i, false, true, true);
1042 schoenebeck 460 }
1043     }
1044 persson 438
1045 schoenebeck 473 // if neither a voice was spawned or postponed then remove note on event from key again
1046     if (!pKey->Active && !pKey->VoiceTheftsQueued)
1047     pKey->pEvents->free(itNoteOnEventOnKeyList);
1048    
1049 schoenebeck 829 if (!pEngineChannel->SoloMode || pEngineChannel->PortamentoPos < 0.0f) pEngineChannel->PortamentoPos = (float) key;
1050 persson 438 pKey->RoundRobinIndex++;
1051 schoenebeck 53 }
1052    
1053     /**
1054     * Releases the voices on the given key if sustain pedal is not pressed.
1055     * If sustain is pressed, the release of the note will be postponed until
1056     * sustain pedal will be released or voice turned inactive by itself (e.g.
1057     * due to completion of sample playback).
1058     *
1059 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1060 schoenebeck 271 * @param itNoteOffEvent - key, velocity and time stamp of the event
1061 schoenebeck 53 */
1062 schoenebeck 411 void Engine::ProcessNoteOff(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOffEvent) {
1063 iliev 716 #if !CONFIG_PROCESS_MUTED_CHANNELS
1064 schoenebeck 705 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1065 iliev 716 #endif
1066 schoenebeck 705
1067 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
1068     itNoteOffEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
1069    
1070 schoenebeck 829 const int iKey = itNoteOffEvent->Param.Note.Key;
1071     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[iKey];
1072 schoenebeck 53 pKey->KeyPressed = false; // the MIDI key was now released
1073    
1074 schoenebeck 829 // move event to the key's own event list
1075     RTList<Event>::Iterator itNoteOffEventOnKeyList = itNoteOffEvent.moveToEndOf(pKey->pEvents);
1076 schoenebeck 242
1077 schoenebeck 829 bool bShouldRelease = pKey->Active && ShouldReleaseVoice(pEngineChannel, itNoteOffEventOnKeyList->Param.Note.Key);
1078 schoenebeck 271
1079 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)
1080 persson 1038 if (pEngineChannel->SoloMode && pEngineChannel->pInstrument) { //TODO: this feels like too much code just for handling solo mode :P
1081 schoenebeck 829 bool bOtherKeysPressed = false;
1082     if (iKey == pEngineChannel->SoloKey) {
1083     pEngineChannel->SoloKey = -1;
1084     // if there's still a key pressed down, respawn a voice (group) on the highest key
1085     for (int i = 127; i > 0; i--) {
1086     midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[i];
1087     if (pOtherKey->KeyPressed) {
1088     bOtherKeysPressed = true;
1089     // make the other key the new 'currently active solo key'
1090     pEngineChannel->SoloKey = i;
1091     // get final portamento position of currently active voice
1092     if (pEngineChannel->PortamentoMode) {
1093     RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
1094     if (itVoice) itVoice->UpdatePortamentoPos(itNoteOffEventOnKeyList);
1095     }
1096     // create a pseudo note on event
1097     RTList<Event>::Iterator itPseudoNoteOnEvent = pOtherKey->pEvents->allocAppend();
1098     if (itPseudoNoteOnEvent) {
1099     // copy event
1100     *itPseudoNoteOnEvent = *itNoteOffEventOnKeyList;
1101     // transform event to a note on event
1102     itPseudoNoteOnEvent->Type = Event::type_note_on;
1103     itPseudoNoteOnEvent->Param.Note.Key = i;
1104     itPseudoNoteOnEvent->Param.Note.Velocity = pOtherKey->Velocity;
1105     // allocate and trigger new voice(s) for the other key
1106     {
1107     // first, get total amount of required voices (dependant on amount of layers)
1108     ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(i);
1109     if (pRegion) {
1110     int voicesRequired = pRegion->Layers;
1111     // now launch the required amount of voices
1112     for (int iLayer = 0; iLayer < voicesRequired; iLayer++)
1113     LaunchVoice(pEngineChannel, itPseudoNoteOnEvent, iLayer, false, true, false);
1114     }
1115     }
1116     // if neither a voice was spawned or postponed then remove note on event from key again
1117     if (!pOtherKey->Active && !pOtherKey->VoiceTheftsQueued)
1118     pOtherKey->pEvents->free(itPseudoNoteOnEvent);
1119    
1120     } else dmsg(1,("Could not respawn voice, no free event left\n"));
1121     break; // done
1122     }
1123     }
1124     }
1125     if (bOtherKeysPressed) {
1126     if (pKey->Active) { // kill all voices on this key
1127     bShouldRelease = false; // no need to release, as we kill it here
1128     RTList<Voice>::Iterator itVoiceToBeKilled = pKey->pActiveVoices->first();
1129     RTList<Voice>::Iterator end = pKey->pActiveVoices->end();
1130     for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
1131     if (itVoiceToBeKilled->Type != Voice::type_release_trigger)
1132     itVoiceToBeKilled->Kill(itNoteOffEventOnKeyList);
1133     }
1134     }
1135     } else pEngineChannel->PortamentoPos = -1.0f;
1136     }
1137    
1138     // if no solo mode (the usual case) or if solo mode and no other key pressed, then release voices on this key if needed
1139     if (bShouldRelease) {
1140     itNoteOffEventOnKeyList->Type = Event::type_release; // transform event type
1141    
1142 persson 497 // spawn release triggered voice(s) if needed
1143 persson 1038 if (pKey->ReleaseTrigger && pEngineChannel->pInstrument) {
1144 persson 497 // first, get total amount of required voices (dependant on amount of layers)
1145     ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key);
1146     if (pRegion) {
1147     int voicesRequired = pRegion->Layers;
1148 persson 630
1149     // MIDI note-on velocity is used instead of note-off velocity
1150     itNoteOffEventOnKeyList->Param.Note.Velocity = pKey->Velocity;
1151    
1152 persson 497 // now launch the required amount of voices
1153     for (int i = 0; i < voicesRequired; i++)
1154 schoenebeck 668 LaunchVoice(pEngineChannel, itNoteOffEventOnKeyList, i, true, false, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples
1155 persson 497 }
1156     pKey->ReleaseTrigger = false;
1157 schoenebeck 460 }
1158 schoenebeck 829 }
1159 persson 497
1160 schoenebeck 829 // if neither a voice was spawned or postponed on this key then remove note off event from key again
1161     if (!pKey->Active && !pKey->VoiceTheftsQueued)
1162     pKey->pEvents->free(itNoteOffEventOnKeyList);
1163 schoenebeck 53 }
1164    
1165     /**
1166 schoenebeck 738 * Moves pitchbend event from the general (input) event list to the engine
1167     * channel's event list. It will actually processed later by the
1168     * respective voice.
1169 schoenebeck 53 *
1170 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1171 schoenebeck 271 * @param itPitchbendEvent - absolute pitch value and time stamp of the event
1172 schoenebeck 53 */
1173 schoenebeck 411 void Engine::ProcessPitchbend(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itPitchbendEvent) {
1174     pEngineChannel->Pitch = itPitchbendEvent->Param.Pitch.Pitch; // store current pitch value
1175 schoenebeck 53 }
1176    
1177     /**
1178 schoenebeck 233 * Allocates and triggers a new voice. This method will usually be
1179     * called by the ProcessNoteOn() method and by the voices itself
1180     * (e.g. to spawn further voices on the same key for layered sounds).
1181     *
1182 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1183 schoenebeck 271 * @param itNoteOnEvent - key, velocity and time stamp of the event
1184 schoenebeck 242 * @param iLayer - layer index for the new voice (optional - only
1185     * in case of layered sounds of course)
1186     * @param ReleaseTriggerVoice - if new voice is a release triggered voice
1187     * (optional, default = false)
1188 schoenebeck 250 * @param VoiceStealing - if voice stealing should be performed
1189     * when there is no free voice
1190     * (optional, default = true)
1191 schoenebeck 668 * @param HandleKeyGroupConflicts - if voices should be killed due to a
1192     * key group conflict
1193 schoenebeck 250 * @returns pointer to new voice or NULL if there was no free voice or
1194 schoenebeck 354 * if the voice wasn't triggered (for example when no region is
1195     * defined for the given key).
1196 schoenebeck 233 */
1197 schoenebeck 668 Pool<Voice>::Iterator Engine::LaunchVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing, bool HandleKeyGroupConflicts) {
1198 schoenebeck 669 int MIDIKey = itNoteOnEvent->Param.Note.Key;
1199     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[MIDIKey];
1200     ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(MIDIKey);
1201 schoenebeck 233
1202 schoenebeck 668 // if nothing defined for this key
1203     if (!pRegion) return Pool<Voice>::Iterator(); // nothing to do
1204    
1205 schoenebeck 669 // only mark the first voice of a layered voice (group) to be in a
1206     // key group, so the layered voices won't kill each other
1207     int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;
1208    
1209 schoenebeck 668 // handle key group (a.k.a. exclusive group) conflicts
1210     if (HandleKeyGroupConflicts) {
1211     if (iKeyGroup) { // if this voice / key belongs to a key group
1212     uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[iKeyGroup];
1213     if (*ppKeyGroup) { // if there's already an active key in that key group
1214     midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[**ppKeyGroup];
1215     // kill all voices on the (other) key
1216     RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
1217     RTList<Voice>::Iterator end = pOtherKey->pActiveVoices->end();
1218     for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
1219     if (itVoiceToBeKilled->Type != Voice::type_release_trigger) {
1220     itVoiceToBeKilled->Kill(itNoteOnEvent);
1221     --VoiceSpawnsLeft; //FIXME: just a hack, we should better check in StealVoice() if the voice was killed due to key conflict
1222     }
1223     }
1224     }
1225     }
1226     }
1227    
1228 schoenebeck 669 Voice::type_t VoiceType = Voice::type_normal;
1229    
1230     // get current dimension values to select the right dimension region
1231     //TODO: for stolen voices this dimension region selection block is processed twice, this should be changed
1232     //FIXME: controller values for selecting the dimension region here are currently not sample accurate
1233     uint DimValues[8] = { 0 };
1234     for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
1235     switch (pRegion->pDimensionDefinitions[i].dimension) {
1236     case ::gig::dimension_samplechannel:
1237     DimValues[i] = 0; //TODO: we currently ignore this dimension
1238     break;
1239     case ::gig::dimension_layer:
1240     DimValues[i] = iLayer;
1241     break;
1242     case ::gig::dimension_velocity:
1243     DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
1244     break;
1245     case ::gig::dimension_channelaftertouch:
1246 persson 903 DimValues[i] = pEngineChannel->ControllerTable[128];
1247 schoenebeck 669 break;
1248     case ::gig::dimension_releasetrigger:
1249     VoiceType = (ReleaseTriggerVoice) ? Voice::type_release_trigger : (!iLayer) ? Voice::type_release_trigger_required : Voice::type_normal;
1250     DimValues[i] = (uint) ReleaseTriggerVoice;
1251     break;
1252     case ::gig::dimension_keyboard:
1253 persson 865 DimValues[i] = (uint) (pEngineChannel->CurrentKeyDimension * pRegion->pDimensionDefinitions[i].zones);
1254 schoenebeck 669 break;
1255     case ::gig::dimension_roundrobin:
1256     DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on
1257     break;
1258     case ::gig::dimension_random:
1259     RandomSeed = RandomSeed * 1103515245 + 12345; // classic pseudo random number generator
1260     DimValues[i] = (uint) RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random
1261     break;
1262     case ::gig::dimension_modwheel:
1263     DimValues[i] = pEngineChannel->ControllerTable[1];
1264     break;
1265     case ::gig::dimension_breath:
1266     DimValues[i] = pEngineChannel->ControllerTable[2];
1267     break;
1268     case ::gig::dimension_foot:
1269     DimValues[i] = pEngineChannel->ControllerTable[4];
1270     break;
1271     case ::gig::dimension_portamentotime:
1272     DimValues[i] = pEngineChannel->ControllerTable[5];
1273     break;
1274     case ::gig::dimension_effect1:
1275     DimValues[i] = pEngineChannel->ControllerTable[12];
1276     break;
1277     case ::gig::dimension_effect2:
1278     DimValues[i] = pEngineChannel->ControllerTable[13];
1279     break;
1280     case ::gig::dimension_genpurpose1:
1281     DimValues[i] = pEngineChannel->ControllerTable[16];
1282     break;
1283     case ::gig::dimension_genpurpose2:
1284     DimValues[i] = pEngineChannel->ControllerTable[17];
1285     break;
1286     case ::gig::dimension_genpurpose3:
1287     DimValues[i] = pEngineChannel->ControllerTable[18];
1288     break;
1289     case ::gig::dimension_genpurpose4:
1290     DimValues[i] = pEngineChannel->ControllerTable[19];
1291     break;
1292     case ::gig::dimension_sustainpedal:
1293     DimValues[i] = pEngineChannel->ControllerTable[64];
1294     break;
1295     case ::gig::dimension_portamento:
1296     DimValues[i] = pEngineChannel->ControllerTable[65];
1297     break;
1298     case ::gig::dimension_sostenutopedal:
1299     DimValues[i] = pEngineChannel->ControllerTable[66];
1300     break;
1301     case ::gig::dimension_softpedal:
1302     DimValues[i] = pEngineChannel->ControllerTable[67];
1303     break;
1304     case ::gig::dimension_genpurpose5:
1305     DimValues[i] = pEngineChannel->ControllerTable[80];
1306     break;
1307     case ::gig::dimension_genpurpose6:
1308     DimValues[i] = pEngineChannel->ControllerTable[81];
1309     break;
1310     case ::gig::dimension_genpurpose7:
1311     DimValues[i] = pEngineChannel->ControllerTable[82];
1312     break;
1313     case ::gig::dimension_genpurpose8:
1314     DimValues[i] = pEngineChannel->ControllerTable[83];
1315     break;
1316     case ::gig::dimension_effect1depth:
1317     DimValues[i] = pEngineChannel->ControllerTable[91];
1318     break;
1319     case ::gig::dimension_effect2depth:
1320     DimValues[i] = pEngineChannel->ControllerTable[92];
1321     break;
1322     case ::gig::dimension_effect3depth:
1323     DimValues[i] = pEngineChannel->ControllerTable[93];
1324     break;
1325     case ::gig::dimension_effect4depth:
1326     DimValues[i] = pEngineChannel->ControllerTable[94];
1327     break;
1328     case ::gig::dimension_effect5depth:
1329     DimValues[i] = pEngineChannel->ControllerTable[95];
1330     break;
1331     case ::gig::dimension_none:
1332     std::cerr << "gig::Engine::LaunchVoice() Error: dimension=none\n" << std::flush;
1333     break;
1334     default:
1335     std::cerr << "gig::Engine::LaunchVoice() Error: Unknown dimension\n" << std::flush;
1336     }
1337     }
1338 persson 1038
1339     // return if this is a release triggered voice and there is no
1340     // releasetrigger dimension (could happen if an instrument
1341     // change has occured between note on and off)
1342     if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
1343    
1344 schoenebeck 669 ::gig::DimensionRegion* pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
1345    
1346     // no need to continue if sample is silent
1347     if (!pDimRgn->pSample || !pDimRgn->pSample->SamplesTotal) return Pool<Voice>::Iterator();
1348    
1349 schoenebeck 233 // allocate a new voice for the key
1350 schoenebeck 271 Pool<Voice>::Iterator itNewVoice = pKey->pActiveVoices->allocAppend();
1351     if (itNewVoice) {
1352 schoenebeck 233 // launch the new voice
1353 schoenebeck 669 if (itNewVoice->Trigger(pEngineChannel, itNoteOnEvent, pEngineChannel->Pitch, pDimRgn, VoiceType, iKeyGroup) < 0) {
1354 schoenebeck 354 dmsg(4,("Voice not triggered\n"));
1355 schoenebeck 271 pKey->pActiveVoices->free(itNewVoice);
1356 schoenebeck 233 }
1357 schoenebeck 239 else { // on success
1358 schoenebeck 663 --VoiceSpawnsLeft;
1359 schoenebeck 239 if (!pKey->Active) { // mark as active key
1360     pKey->Active = true;
1361 schoenebeck 411 pKey->itSelf = pEngineChannel->pActiveKeys->allocAppend();
1362 schoenebeck 271 *pKey->itSelf = itNoteOnEvent->Param.Note.Key;
1363 schoenebeck 239 }
1364 schoenebeck 271 if (itNewVoice->KeyGroup) {
1365 schoenebeck 668 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[itNewVoice->KeyGroup];
1366 schoenebeck 271 *ppKeyGroup = &*pKey->itSelf; // put key as the (new) active key to its key group
1367 schoenebeck 239 }
1368 schoenebeck 271 if (itNewVoice->Type == Voice::type_release_trigger_required) pKey->ReleaseTrigger = true; // mark key for the need of release triggered voice(s)
1369     return itNewVoice; // success
1370 schoenebeck 233 }
1371     }
1372 schoenebeck 285 else if (VoiceStealing) {
1373 schoenebeck 460 // try to steal one voice
1374 schoenebeck 473 int result = StealVoice(pEngineChannel, itNoteOnEvent);
1375     if (!result) { // voice stolen successfully
1376     // put note-on event into voice-stealing queue, so it will be reprocessed after killed voice died
1377     RTList<Event>::Iterator itStealEvent = pVoiceStealingQueue->allocAppend();
1378     if (itStealEvent) {
1379     *itStealEvent = *itNoteOnEvent; // copy event
1380     itStealEvent->Param.Note.Layer = iLayer;
1381     itStealEvent->Param.Note.ReleaseTrigger = ReleaseTriggerVoice;
1382     pKey->VoiceTheftsQueued++;
1383     }
1384     else dmsg(1,("Voice stealing queue full!\n"));
1385 schoenebeck 285 }
1386     }
1387    
1388 schoenebeck 271 return Pool<Voice>::Iterator(); // no free voice or error
1389 schoenebeck 233 }
1390    
1391     /**
1392 schoenebeck 250 * Will be called by LaunchVoice() method in case there are no free
1393     * voices left. This method will select and kill one old voice for
1394     * voice stealing and postpone the note-on event until the selected
1395     * voice actually died.
1396     *
1397 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1398 schoenebeck 285 * @param itNoteOnEvent - key, velocity and time stamp of the event
1399 schoenebeck 473 * @returns 0 on success, a value < 0 if no active voice could be picked for voice stealing
1400 schoenebeck 250 */
1401 schoenebeck 473 int Engine::StealVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
1402 schoenebeck 663 if (VoiceSpawnsLeft <= 0) {
1403 schoenebeck 554 dmsg(1,("Max. voice thefts per audio fragment reached (you may raise CONFIG_MAX_VOICES).\n"));
1404 schoenebeck 473 return -1;
1405 schoenebeck 460 }
1406 schoenebeck 271 if (!pEventPool->poolIsEmpty()) {
1407 schoenebeck 250
1408 schoenebeck 460 RTList<Voice>::Iterator itSelectedVoice;
1409 schoenebeck 250
1410     // Select one voice for voice stealing
1411 schoenebeck 554 switch (CONFIG_VOICE_STEAL_ALGO) {
1412 schoenebeck 250
1413     // try to pick the oldest voice on the key where the new
1414     // voice should be spawned, if there is no voice on that
1415 schoenebeck 563 // key, or no voice left to kill, then procceed with
1416 schoenebeck 250 // 'oldestkey' algorithm
1417 schoenebeck 460 case voice_steal_algo_oldestvoiceonkey: {
1418     midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key];
1419 schoenebeck 563 itSelectedVoice = pSelectedKey->pActiveVoices->first();
1420     // proceed iterating if voice was created in this fragment cycle
1421 schoenebeck 663 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1422 schoenebeck 563 // if we haven't found a voice then proceed with algorithm 'oldestkey'
1423 schoenebeck 663 if (itSelectedVoice && itSelectedVoice->IsStealable()) break;
1424 schoenebeck 250 } // no break - intentional !
1425    
1426     // try to pick the oldest voice on the oldest active key
1427 schoenebeck 563 // from the same engine channel
1428 schoenebeck 460 // (caution: must stay after 'oldestvoiceonkey' algorithm !)
1429 schoenebeck 250 case voice_steal_algo_oldestkey: {
1430 schoenebeck 649 // if we already stole in this fragment, try to proceed on same key
1431 schoenebeck 460 if (this->itLastStolenVoice) {
1432     itSelectedVoice = this->itLastStolenVoice;
1433 schoenebeck 649 do {
1434     ++itSelectedVoice;
1435 schoenebeck 663 } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1436 schoenebeck 649 // found a "stealable" voice ?
1437 schoenebeck 663 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1438 schoenebeck 649 // remember which voice we stole, so we can simply proceed on next voice stealing
1439     this->itLastStolenVoice = itSelectedVoice;
1440 schoenebeck 460 break; // selection succeeded
1441 schoenebeck 250 }
1442     }
1443 schoenebeck 649 // get (next) oldest key
1444     RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKey) ? ++this->iuiLastStolenKey : pEngineChannel->pActiveKeys->first();
1445     while (iuiSelectedKey) {
1446     midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[*iuiSelectedKey];
1447 schoenebeck 659 itSelectedVoice = pSelectedKey->pActiveVoices->first();
1448 schoenebeck 649 // proceed iterating if voice was created in this fragment cycle
1449 schoenebeck 663 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1450 schoenebeck 649 // found a "stealable" voice ?
1451 schoenebeck 663 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1452 schoenebeck 649 // remember which voice on which key we stole, so we can simply proceed on next voice stealing
1453     this->iuiLastStolenKey = iuiSelectedKey;
1454     this->itLastStolenVoice = itSelectedVoice;
1455     break; // selection succeeded
1456     }
1457     ++iuiSelectedKey; // get next oldest key
1458     }
1459 schoenebeck 250 break;
1460     }
1461    
1462     // don't steal anything
1463     case voice_steal_algo_none:
1464     default: {
1465     dmsg(1,("No free voice (voice stealing disabled)!\n"));
1466 schoenebeck 473 return -1;
1467 schoenebeck 250 }
1468     }
1469    
1470 schoenebeck 563 // if we couldn't steal a voice from the same engine channel then
1471     // steal oldest voice on the oldest key from any other engine channel
1472 schoenebeck 649 // (the smaller engine channel number, the higher priority)
1473 schoenebeck 663 if (!itSelectedVoice || !itSelectedVoice->IsStealable()) {
1474 schoenebeck 649 EngineChannel* pSelectedChannel;
1475     int iChannelIndex;
1476     // select engine channel
1477     if (pLastStolenChannel) {
1478     pSelectedChannel = pLastStolenChannel;
1479     iChannelIndex = pSelectedChannel->iEngineIndexSelf;
1480     } else { // pick the engine channel followed by this engine channel
1481     iChannelIndex = (pEngineChannel->iEngineIndexSelf + 1) % engineChannels.size();
1482     pSelectedChannel = engineChannels[iChannelIndex];
1483     }
1484 schoenebeck 663
1485     // if we already stole in this fragment, try to proceed on same key
1486     if (this->itLastStolenVoiceGlobally) {
1487     itSelectedVoice = this->itLastStolenVoiceGlobally;
1488     do {
1489     ++itSelectedVoice;
1490     } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1491     }
1492    
1493     #if CONFIG_DEVMODE
1494     EngineChannel* pBegin = pSelectedChannel; // to detect endless loop
1495     #endif // CONFIG_DEVMODE
1496    
1497     // did we find a 'stealable' voice?
1498     if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1499     // remember which voice we stole, so we can simply proceed on next voice stealing
1500     this->itLastStolenVoiceGlobally = itSelectedVoice;
1501     } else while (true) { // iterate through engine channels
1502 schoenebeck 649 // get (next) oldest key
1503 schoenebeck 663 RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKeyGlobally) ? ++this->iuiLastStolenKeyGlobally : pSelectedChannel->pActiveKeys->first();
1504     this->iuiLastStolenKeyGlobally = RTList<uint>::Iterator(); // to prevent endless loop (see line above)
1505 schoenebeck 649 while (iuiSelectedKey) {
1506 schoenebeck 663 midi_key_info_t* pSelectedKey = &pSelectedChannel->pMIDIKeyInfo[*iuiSelectedKey];
1507 schoenebeck 649 itSelectedVoice = pSelectedKey->pActiveVoices->first();
1508     // proceed iterating if voice was created in this fragment cycle
1509 schoenebeck 663 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1510 schoenebeck 649 // found a "stealable" voice ?
1511 schoenebeck 663 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1512 schoenebeck 649 // remember which voice on which key on which engine channel we stole, so we can simply proceed on next voice stealing
1513     this->iuiLastStolenKeyGlobally = iuiSelectedKey;
1514     this->itLastStolenVoiceGlobally = itSelectedVoice;
1515     this->pLastStolenChannel = pSelectedChannel;
1516 schoenebeck 665 goto stealable_voice_found; // selection succeeded
1517 schoenebeck 649 }
1518     ++iuiSelectedKey; // get next key on current engine channel
1519     }
1520     // get next engine channel
1521 schoenebeck 460 iChannelIndex = (iChannelIndex + 1) % engineChannels.size();
1522 schoenebeck 649 pSelectedChannel = engineChannels[iChannelIndex];
1523 schoenebeck 663
1524     #if CONFIG_DEVMODE
1525     if (pSelectedChannel == pBegin) {
1526     dmsg(1,("FATAL ERROR: voice stealing endless loop!\n"));
1527     dmsg(1,("VoiceSpawnsLeft=%d.\n", VoiceSpawnsLeft));
1528     dmsg(1,("Exiting.\n"));
1529     exit(-1);
1530     }
1531     #endif // CONFIG_DEVMODE
1532 schoenebeck 460 }
1533     }
1534    
1535 schoenebeck 665 // jump point if a 'stealable' voice was found
1536     stealable_voice_found:
1537    
1538 schoenebeck 563 #if CONFIG_DEVMODE
1539 schoenebeck 473 if (!itSelectedVoice->IsActive()) {
1540     dmsg(1,("gig::Engine: ERROR, tried to steal a voice which was not active !!!\n"));
1541     return -1;
1542     }
1543 schoenebeck 563 #endif // CONFIG_DEVMODE
1544 schoenebeck 287
1545 schoenebeck 250 // now kill the selected voice
1546 schoenebeck 659 itSelectedVoice->Kill(itNoteOnEvent);
1547 schoenebeck 460
1548 schoenebeck 663 --VoiceSpawnsLeft;
1549 schoenebeck 473
1550     return 0; // success
1551 schoenebeck 250 }
1552 schoenebeck 473 else {
1553     dmsg(1,("Event pool emtpy!\n"));
1554     return -1;
1555     }
1556 schoenebeck 250 }
1557    
1558     /**
1559 schoenebeck 285 * Removes the given voice from the MIDI key's list of active voices.
1560     * This method will be called when a voice went inactive, e.g. because
1561     * it finished to playback its sample, finished its release stage or
1562     * just was killed.
1563 schoenebeck 53 *
1564 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1565 schoenebeck 285 * @param itVoice - points to the voice to be freed
1566 schoenebeck 53 */
1567 schoenebeck 411 void Engine::FreeVoice(EngineChannel* pEngineChannel, Pool<Voice>::Iterator& itVoice) {
1568 schoenebeck 271 if (itVoice) {
1569 schoenebeck 411 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoice->MIDIKey];
1570 schoenebeck 53
1571 schoenebeck 271 uint keygroup = itVoice->KeyGroup;
1572    
1573 persson 1038 // if the sample and dimension region belong to an
1574     // instrument that is unloaded, tell the disk thread to
1575     // release them
1576     if (itVoice->Orphan) {
1577     pDiskThread->OrderDeletionOfDimreg(itVoice->pDimRgn);
1578     }
1579    
1580 schoenebeck 53 // free the voice object
1581 schoenebeck 271 pVoicePool->free(itVoice);
1582 schoenebeck 53
1583 schoenebeck 287 // if no other voices left and member of a key group, remove from key group
1584     if (pKey->pActiveVoices->isEmpty() && keygroup) {
1585 schoenebeck 411 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[keygroup];
1586 schoenebeck 287 if (*ppKeyGroup == &*pKey->itSelf) *ppKeyGroup = NULL; // remove key from key group
1587 schoenebeck 53 }
1588     }
1589 schoenebeck 285 else std::cerr << "Couldn't release voice! (!itVoice)\n" << std::flush;
1590 schoenebeck 53 }
1591    
1592     /**
1593 schoenebeck 287 * Called when there's no more voice left on a key, this call will
1594     * update the key info respectively.
1595     *
1596 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1597 schoenebeck 287 * @param pKey - key which is now inactive
1598     */
1599 schoenebeck 411 void Engine::FreeKey(EngineChannel* pEngineChannel, midi_key_info_t* pKey) {
1600 schoenebeck 287 if (pKey->pActiveVoices->isEmpty()) {
1601     pKey->Active = false;
1602 schoenebeck 411 pEngineChannel->pActiveKeys->free(pKey->itSelf); // remove key from list of active keys
1603 schoenebeck 287 pKey->itSelf = RTList<uint>::Iterator();
1604     pKey->ReleaseTrigger = false;
1605     pKey->pEvents->clear();
1606     dmsg(3,("Key has no more voices now\n"));
1607     }
1608     else dmsg(1,("gig::Engine: Oops, tried to free a key which contains voices.\n"));
1609     }
1610    
1611     /**
1612 schoenebeck 53 * Reacts on supported control change commands (e.g. pitch bend wheel,
1613     * modulation wheel, aftertouch).
1614     *
1615 schoenebeck 411 * @param pEngineChannel - engine channel on which this event occured on
1616 schoenebeck 271 * @param itControlChangeEvent - controller, value and time stamp of the event
1617 schoenebeck 53 */
1618 schoenebeck 411 void Engine::ProcessControlChange(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itControlChangeEvent) {
1619 schoenebeck 271 dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));
1620 schoenebeck 53
1621 persson 1700 // handle the "control triggered" MIDI rule: a control change
1622     // event can trigger a new note on or note off event
1623     if (pEngineChannel->pInstrument) {
1624    
1625     ::gig::MidiRule* rule;
1626     for (int i = 0 ; (rule = pEngineChannel->pInstrument->GetMidiRule(i)) ; i++) {
1627    
1628     if (::gig::MidiRuleCtrlTrigger* ctrlTrigger =
1629     dynamic_cast< ::gig::MidiRuleCtrlTrigger*>(rule)) {
1630     if (itControlChangeEvent->Param.CC.Controller ==
1631     ctrlTrigger->ControllerNumber) {
1632    
1633     uint8_t oldCCValue = pEngineChannel->ControllerTable[
1634     itControlChangeEvent->Param.CC.Controller];
1635     uint8_t newCCValue = itControlChangeEvent->Param.CC.Value;
1636    
1637     for (int i = 0 ; i < ctrlTrigger->Triggers ; i++) {
1638     ::gig::MidiRuleCtrlTrigger::trigger_t* pTrigger =
1639     &ctrlTrigger->pTriggers[i];
1640    
1641     // check if the controller has passed the
1642     // trigger point in the right direction
1643     if ((pTrigger->Descending &&
1644     oldCCValue > pTrigger->TriggerPoint &&
1645     newCCValue <= pTrigger->TriggerPoint) ||
1646     (!pTrigger->Descending &&
1647     oldCCValue < pTrigger->TriggerPoint &&
1648     newCCValue >= pTrigger->TriggerPoint)) {
1649    
1650     RTList<Event>::Iterator itNewEvent = pGlobalEvents->allocAppend();
1651     if (itNewEvent) {
1652     *itNewEvent = *itControlChangeEvent;
1653     itNewEvent->Param.Note.Key = pTrigger->Key;
1654    
1655     if (pTrigger->NoteOff || pTrigger->Velocity == 0) {
1656     itNewEvent->Type = Event::type_note_off;
1657     itNewEvent->Param.Note.Velocity = 100;
1658    
1659     ProcessNoteOff(pEngineChannel, itNewEvent);
1660     } else {
1661     itNewEvent->Type = Event::type_note_on;
1662     //TODO: if Velocity is 255, the triggered velocity should
1663     // depend on how fast the controller is moving
1664     itNewEvent->Param.Note.Velocity =
1665     pTrigger->Velocity == 255 ? 100 :
1666     pTrigger->Velocity;
1667    
1668     ProcessNoteOn(pEngineChannel, itNewEvent);
1669     }
1670     }
1671     else dmsg(1,("Event pool emtpy!\n"));
1672     }
1673     }
1674     }
1675     }
1676     }
1677     }
1678    
1679 schoenebeck 473 // update controller value in the engine channel's controller table
1680     pEngineChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;
1681    
1682 schoenebeck 1001 // handle hard coded MIDI controllers
1683 schoenebeck 769 switch (itControlChangeEvent->Param.CC.Controller) {
1684 schoenebeck 829 case 5: { // portamento time
1685     pEngineChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN;
1686     break;
1687     }
1688 schoenebeck 1041 case 6: { // data entry (currently only used for RPN controllers)
1689     if (pEngineChannel->GetMidiRpnController() == 2) { // coarse tuning in half tones
1690     int transpose = (int) itControlChangeEvent->Param.CC.Value - 64;
1691     // limit to +- two octaves for now
1692     transpose = RTMath::Min(transpose, 24);
1693     transpose = RTMath::Max(transpose, -24);
1694     pEngineChannel->GlobalTranspose = transpose;
1695 schoenebeck 1043 // workaround, so we won't have hanging notes
1696     ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1697 schoenebeck 1041 }
1698 schoenebeck 1044 // to avoid other MIDI CC #6 messages to be misenterpreted as RPN controller data
1699     pEngineChannel->ResetMidiRpnController();
1700 schoenebeck 1041 break;
1701     }
1702 schoenebeck 424 case 7: { // volume
1703     //TODO: not sample accurate yet
1704 schoenebeck 947 pEngineChannel->MidiVolume = VolumeCurve[itControlChangeEvent->Param.CC.Value];
1705 schoenebeck 660 pEngineChannel->bStatusChanged = true; // engine channel status has changed, so set notify flag
1706 schoenebeck 424 break;
1707     }
1708     case 10: { // panpot
1709     //TODO: not sample accurate yet
1710 persson 831 pEngineChannel->GlobalPanLeft = PanCurve[128 - itControlChangeEvent->Param.CC.Value];
1711     pEngineChannel->GlobalPanRight = PanCurve[itControlChangeEvent->Param.CC.Value];
1712 schoenebeck 424 break;
1713     }
1714     case 64: { // sustain
1715 schoenebeck 769 if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SustainPedal) {
1716 iliev 776 dmsg(4,("DAMPER (RIGHT) PEDAL DOWN\n"));
1717 schoenebeck 411 pEngineChannel->SustainPedal = true;
1718 schoenebeck 53
1719 iliev 716 #if !CONFIG_PROCESS_MUTED_CHANNELS
1720 schoenebeck 705 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1721 iliev 716 #endif
1722 schoenebeck 705
1723 schoenebeck 53 // cancel release process of voices if necessary
1724 schoenebeck 411 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1725 schoenebeck 473 for (; iuiKey; ++iuiKey) {
1726     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1727     if (!pKey->KeyPressed) {
1728     RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1729     if (itNewEvent) {
1730 schoenebeck 769 *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1731 schoenebeck 473 itNewEvent->Type = Event::type_cancel_release; // transform event type
1732 schoenebeck 53 }
1733 schoenebeck 473 else dmsg(1,("Event pool emtpy!\n"));
1734 schoenebeck 53 }
1735     }
1736     }
1737 schoenebeck 769 if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SustainPedal) {
1738 iliev 776 dmsg(4,("DAMPER (RIGHT) PEDAL UP\n"));
1739 schoenebeck 411 pEngineChannel->SustainPedal = false;
1740 schoenebeck 53
1741 iliev 716 #if !CONFIG_PROCESS_MUTED_CHANNELS
1742 schoenebeck 705 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1743 iliev 716 #endif
1744 schoenebeck 705
1745 schoenebeck 53 // release voices if their respective key is not pressed
1746 schoenebeck 411 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1747 schoenebeck 473 for (; iuiKey; ++iuiKey) {
1748     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1749 iliev 776 if (!pKey->KeyPressed && ShouldReleaseVoice(pEngineChannel, *iuiKey)) {
1750 schoenebeck 473 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1751     if (itNewEvent) {
1752 schoenebeck 769 *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1753 schoenebeck 473 itNewEvent->Type = Event::type_release; // transform event type
1754 schoenebeck 53 }
1755 schoenebeck 473 else dmsg(1,("Event pool emtpy!\n"));
1756 schoenebeck 53 }
1757     }
1758     }
1759     break;
1760     }
1761 schoenebeck 829 case 65: { // portamento on / off
1762 schoenebeck 1348 const bool bPortamento = itControlChangeEvent->Param.CC.Value >= 64;
1763     if (bPortamento != pEngineChannel->PortamentoMode)
1764     KillAllVoices(pEngineChannel, itControlChangeEvent);
1765     pEngineChannel->PortamentoMode = bPortamento;
1766 schoenebeck 829 break;
1767     }
1768 iliev 776 case 66: { // sostenuto
1769     if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SostenutoPedal) {
1770     dmsg(4,("SOSTENUTO (CENTER) PEDAL DOWN\n"));
1771     pEngineChannel->SostenutoPedal = true;
1772 schoenebeck 53
1773 iliev 776 #if !CONFIG_PROCESS_MUTED_CHANNELS
1774     if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1775     #endif
1776 schoenebeck 53
1777 iliev 776 SostenutoKeyCount = 0;
1778     // Remeber the pressed keys
1779     RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1780     for (; iuiKey; ++iuiKey) {
1781     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1782     if (pKey->KeyPressed && SostenutoKeyCount < 128) SostenutoKeys[SostenutoKeyCount++] = *iuiKey;
1783     }
1784     }
1785     if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SostenutoPedal) {
1786     dmsg(4,("SOSTENUTO (CENTER) PEDAL UP\n"));
1787     pEngineChannel->SostenutoPedal = false;
1788    
1789     #if !CONFIG_PROCESS_MUTED_CHANNELS
1790     if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1791     #endif
1792    
1793     // release voices if the damper pedal is up and their respective key is not pressed
1794     for (int i = 0; i < SostenutoKeyCount; i++) {
1795     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[SostenutoKeys[i]];
1796     if (!pKey->KeyPressed && !pEngineChannel->SustainPedal) {
1797     RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1798     if (itNewEvent) {
1799     *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1800     itNewEvent->Type = Event::type_release; // transform event type
1801     }
1802     else dmsg(1,("Event pool emtpy!\n"));
1803     }
1804     }
1805     }
1806     break;
1807     }
1808 schoenebeck 1041 case 100: { // RPN controller LSB
1809     pEngineChannel->SetMidiRpnControllerLsb(itControlChangeEvent->Param.CC.Value);
1810     break;
1811     }
1812     case 101: { // RPN controller MSB
1813     pEngineChannel->SetMidiRpnControllerMsb(itControlChangeEvent->Param.CC.Value);
1814     break;
1815     }
1816 iliev 776
1817    
1818 schoenebeck 473 // Channel Mode Messages
1819    
1820     case 120: { // all sound off
1821 schoenebeck 769 KillAllVoices(pEngineChannel, itControlChangeEvent);
1822 schoenebeck 473 break;
1823     }
1824     case 121: { // reset all controllers
1825     pEngineChannel->ResetControllers();
1826     break;
1827     }
1828     case 123: { // all notes off
1829 schoenebeck 849 #if CONFIG_PROCESS_ALL_NOTES_OFF
1830 schoenebeck 769 ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1831 schoenebeck 849 #endif // CONFIG_PROCESS_ALL_NOTES_OFF
1832 schoenebeck 473 break;
1833     }
1834 schoenebeck 829 case 126: { // mono mode on
1835 schoenebeck 1348 if (!pEngineChannel->SoloMode)
1836     KillAllVoices(pEngineChannel, itControlChangeEvent);
1837 schoenebeck 829 pEngineChannel->SoloMode = true;
1838     break;
1839     }
1840     case 127: { // poly mode on
1841 schoenebeck 1348 if (pEngineChannel->SoloMode)
1842     KillAllVoices(pEngineChannel, itControlChangeEvent);
1843 schoenebeck 829 pEngineChannel->SoloMode = false;
1844     break;
1845     }
1846 schoenebeck 473 }
1847 schoenebeck 1001
1848     // handle FX send controllers
1849     if (!pEngineChannel->fxSends.empty()) {
1850     for (int iFxSend = 0; iFxSend < pEngineChannel->GetFxSendCount(); iFxSend++) {
1851     FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
1852     if (pFxSend->MidiController() == itControlChangeEvent->Param.CC.Controller)
1853     pFxSend->SetLevel(itControlChangeEvent->Param.CC.Value);
1854 iliev 1108 pFxSend->SetInfoChanged(true);
1855 schoenebeck 1001 }
1856     }
1857 schoenebeck 53 }
1858    
1859     /**
1860 schoenebeck 244 * Reacts on MIDI system exclusive messages.
1861     *
1862 schoenebeck 271 * @param itSysexEvent - sysex data size and time stamp of the sysex event
1863 schoenebeck 244 */
1864 schoenebeck 271 void Engine::ProcessSysex(Pool<Event>::Iterator& itSysexEvent) {
1865 schoenebeck 970 RingBuffer<uint8_t,false>::NonVolatileReader reader = pSysexBuffer->get_non_volatile_reader();
1866 schoenebeck 244
1867     uint8_t exclusive_status, id;
1868     if (!reader.pop(&exclusive_status)) goto free_sysex_data;
1869     if (!reader.pop(&id)) goto free_sysex_data;
1870     if (exclusive_status != 0xF0) goto free_sysex_data;
1871    
1872     switch (id) {
1873     case 0x41: { // Roland
1874 schoenebeck 493 dmsg(3,("Roland Sysex\n"));
1875 schoenebeck 244 uint8_t device_id, model_id, cmd_id;
1876     if (!reader.pop(&device_id)) goto free_sysex_data;
1877     if (!reader.pop(&model_id)) goto free_sysex_data;
1878     if (!reader.pop(&cmd_id)) goto free_sysex_data;
1879     if (model_id != 0x42 /*GS*/) goto free_sysex_data;
1880     if (cmd_id != 0x12 /*DT1*/) goto free_sysex_data;
1881    
1882     // command address
1883     uint8_t addr[3]; // 2 byte addr MSB, followed by 1 byte addr LSB)
1884 schoenebeck 970 const RingBuffer<uint8_t,false>::NonVolatileReader checksum_reader = reader; // so we can calculate the check sum later
1885 schoenebeck 244 if (reader.read(&addr[0], 3) != 3) goto free_sysex_data;
1886     if (addr[0] == 0x40 && addr[1] == 0x00) { // System Parameters
1887 schoenebeck 493 dmsg(3,("\tSystem Parameter\n"));
1888 schoenebeck 244 }
1889     else if (addr[0] == 0x40 && addr[1] == 0x01) { // Common Parameters
1890 schoenebeck 493 dmsg(3,("\tCommon Parameter\n"));
1891 schoenebeck 244 }
1892     else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x10) { // Part Parameters (1)
1893 schoenebeck 493 dmsg(3,("\tPart Parameter\n"));
1894     switch (addr[2]) {
1895 schoenebeck 244 case 0x40: { // scale tuning
1896 schoenebeck 493 dmsg(3,("\t\tScale Tuning\n"));
1897 schoenebeck 244 uint8_t scale_tunes[12]; // detuning of all 12 semitones of an octave
1898     if (reader.read(&scale_tunes[0], 12) != 12) goto free_sysex_data;
1899     uint8_t checksum;
1900 schoenebeck 493 if (!reader.pop(&checksum)) goto free_sysex_data;
1901 schoenebeck 563 #if CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1902     if (GSCheckSum(checksum_reader, 12)) goto free_sysex_data;
1903     #endif // CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1904 schoenebeck 244 for (int i = 0; i < 12; i++) scale_tunes[i] -= 64;
1905     AdjustScale((int8_t*) scale_tunes);
1906 schoenebeck 493 dmsg(3,("\t\t\tNew scale applied.\n"));
1907 schoenebeck 244 break;
1908     }
1909     }
1910     }
1911     else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x20) { // Part Parameters (2)
1912     }
1913     else if (addr[0] == 0x41) { // Drum Setup Parameters
1914     }
1915     break;
1916     }
1917     }
1918    
1919     free_sysex_data: // finally free sysex data
1920 schoenebeck 271 pSysexBuffer->increment_read_ptr(itSysexEvent->Param.Sysex.Size);
1921 schoenebeck 244 }
1922    
1923     /**
1924     * Calculates the Roland GS sysex check sum.
1925     *
1926     * @param AddrReader - reader which currently points to the first GS
1927     * command address byte of the GS sysex message in
1928     * question
1929     * @param DataSize - size of the GS message data (in bytes)
1930     */
1931 schoenebeck 970 uint8_t Engine::GSCheckSum(const RingBuffer<uint8_t,false>::NonVolatileReader AddrReader, uint DataSize) {
1932     RingBuffer<uint8_t,false>::NonVolatileReader reader = AddrReader;
1933 schoenebeck 244 uint bytes = 3 /*addr*/ + DataSize;
1934     uint8_t addr_and_data[bytes];
1935     reader.read(&addr_and_data[0], bytes);
1936     uint8_t sum = 0;
1937     for (uint i = 0; i < bytes; i++) sum += addr_and_data[i];
1938     return 128 - sum % 128;
1939     }
1940    
1941     /**
1942     * Allows to tune each of the twelve semitones of an octave.
1943     *
1944     * @param ScaleTunes - detuning of all twelve semitones (in cents)
1945     */
1946     void Engine::AdjustScale(int8_t ScaleTunes[12]) {
1947     memcpy(&this->ScaleTuning[0], &ScaleTunes[0], 12); //TODO: currently not sample accurate
1948     }
1949    
1950     /**
1951 schoenebeck 473 * Releases all voices on an engine channel. All voices will go into
1952     * the release stage and thus it might take some time (e.g. dependant to
1953     * their envelope release time) until they actually die.
1954     *
1955     * @param pEngineChannel - engine channel on which all voices should be released
1956     * @param itReleaseEvent - event which caused this releasing of all voices
1957     */
1958     void Engine::ReleaseAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itReleaseEvent) {
1959     RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1960     while (iuiKey) {
1961     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1962     ++iuiKey;
1963     // append a 'release' event to the key's own event list
1964     RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1965     if (itNewEvent) {
1966     *itNewEvent = *itReleaseEvent; // copy original event (to the key's event list)
1967     itNewEvent->Type = Event::type_release; // transform event type
1968     }
1969     else dmsg(1,("Event pool emtpy!\n"));
1970     }
1971     }
1972    
1973     /**
1974     * Kills all voices on an engine channel as soon as possible. Voices
1975     * won't get into release state, their volume level will be ramped down
1976     * as fast as possible.
1977     *
1978     * @param pEngineChannel - engine channel on which all voices should be killed
1979     * @param itKillEvent - event which caused this killing of all voices
1980     */
1981     void Engine::KillAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itKillEvent) {
1982     RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1983     RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
1984     while (iuiKey != end) { // iterate through all active keys
1985     midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1986     ++iuiKey;
1987     RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
1988     RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
1989     for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
1990     itVoice->Kill(itKillEvent);
1991 schoenebeck 663 --VoiceSpawnsLeft; //FIXME: just a temporary workaround, we should check the cause in StealVoice() instead
1992 schoenebeck 473 }
1993     }
1994     }
1995    
1996 iliev 776 /**
1997     * Determines whether the specified voice should be released.
1998     *
1999     * @param pEngineChannel - The engine channel on which the voice should be checked
2000     * @param Key - The key number
2001     * @returns true if the specified should be released, false otherwise.
2002     */
2003     bool Engine::ShouldReleaseVoice(EngineChannel* pEngineChannel, int Key) {
2004     if (pEngineChannel->SustainPedal) return false;
2005    
2006     if (pEngineChannel->SostenutoPedal) {
2007     for (int i = 0; i < SostenutoKeyCount; i++)
2008     if (Key == SostenutoKeys[i]) return false;
2009     }
2010    
2011     return true;
2012     }
2013    
2014 schoenebeck 53 uint Engine::VoiceCount() {
2015     return ActiveVoiceCount;
2016     }
2017    
2018     uint Engine::VoiceCountMax() {
2019     return ActiveVoiceCountMax;
2020     }
2021    
2022     bool Engine::DiskStreamSupported() {
2023     return true;
2024     }
2025    
2026     uint Engine::DiskStreamCount() {
2027     return (pDiskThread) ? pDiskThread->ActiveStreamCount : 0;
2028     }
2029    
2030     uint Engine::DiskStreamCountMax() {
2031     return (pDiskThread) ? pDiskThread->ActiveStreamCountMax : 0;
2032     }
2033    
2034     String Engine::DiskStreamBufferFillBytes() {
2035     return pDiskThread->GetBufferFillBytes();
2036     }
2037    
2038     String Engine::DiskStreamBufferFillPercentage() {
2039     return pDiskThread->GetBufferFillPercentage();
2040     }
2041    
2042 senkov 112 String Engine::EngineName() {
2043 schoenebeck 475 return LS_GIG_ENGINE_NAME;
2044 senkov 112 }
2045    
2046 schoenebeck 53 String Engine::Description() {
2047 schoenebeck 1555 return "Gigasampler Format Engine";
2048 schoenebeck 53 }
2049    
2050     String Engine::Version() {
2051 persson 1700 String s = "$Revision: 1.88 $";
2052 schoenebeck 123 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
2053 schoenebeck 53 }
2054    
2055 schoenebeck 947 InstrumentManager* Engine::GetInstrumentManager() {
2056     return &instruments;
2057     }
2058    
2059 persson 831 // static constant initializers
2060 persson 1644 const Engine::FloatTable Engine::VolumeCurve(InitVolumeCurve());
2061     const Engine::FloatTable Engine::PanCurve(InitPanCurve());
2062     const Engine::FloatTable Engine::CrossfadeCurve(InitCrossfadeCurve());
2063 persson 831
2064     float* Engine::InitVolumeCurve() {
2065     // line-segment approximation
2066     const float segments[] = {
2067     0, 0, 2, 0.0046, 16, 0.016, 31, 0.051, 45, 0.115, 54.5, 0.2,
2068     64.5, 0.39, 74, 0.74, 92, 1.03, 114, 1.94, 119.2, 2.2, 127, 2.2
2069     };
2070     return InitCurve(segments);
2071     }
2072    
2073     float* Engine::InitPanCurve() {
2074     // line-segment approximation
2075     const float segments[] = {
2076     0, 0, 1, 0,
2077     2, 0.05, 31.5, 0.7, 51, 0.851, 74.5, 1.12,
2078     127, 1.41, 128, 1.41
2079     };
2080     return InitCurve(segments, 129);
2081     }
2082    
2083 persson 832 float* Engine::InitCrossfadeCurve() {
2084     // line-segment approximation
2085     const float segments[] = {
2086     0, 0, 1, 0.03, 10, 0.1, 51, 0.58, 127, 1
2087     };
2088     return InitCurve(segments);
2089     }
2090    
2091 persson 831 float* Engine::InitCurve(const float* segments, int size) {
2092     float* y = new float[size];
2093     for (int x = 0 ; x < size ; x++) {
2094     if (x > segments[2]) segments += 2;
2095     y[x] = segments[1] + (x - segments[0]) *
2096     (segments[3] - segments[1]) / (segments[2] - segments[0]);
2097     }
2098     return y;
2099     }
2100    
2101 schoenebeck 53 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC