/[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 1843 - (hide annotations) (download)
Sat Feb 21 17:08:18 2009 UTC (15 years, 1 month ago) by iliev
File size: 110500 byte(s)
* fixed orphaned pointers when setting maximum voices limit (bug #118)

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

  ViewVC Help
Powered by ViewVC