/[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 1933 - (hide annotations) (download)
Thu Jul 9 17:37:41 2009 UTC (14 years, 9 months ago) by persson
File size: 111460 byte(s)
* fixed low-level ConditionServer usage bug that caused lockups on
  Windows

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

  ViewVC Help
Powered by ViewVC