/[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 1893 - (hide annotations) (download)
Sat May 2 18:57:49 2009 UTC (14 years, 11 months ago) by schoenebeck
File size: 111419 byte(s)
* fixed crash which occured when max. voices / streams limits were altered
  while voices were still active

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

  ViewVC Help
Powered by ViewVC