/[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 1723 - (hide annotations) (download)
Sun Apr 20 08:53:39 2008 UTC (12 years, 2 months ago) by schoenebeck
File size: 104041 byte(s)
* allow pan control of engine channels on C++ API level
* export denormals-are-zero mode feature to C++ API

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

  ViewVC Help
Powered by ViewVC