/[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 1750 - (hide annotations) (download)
Thu Jul 10 15:00:38 2008 UTC (15 years, 9 months ago) by schoenebeck
File size: 106598 byte(s)
* added support for chromatic / drumkit mode Roland GS Sysex message
  which is usally used to switch a part between chromatic sounds and
  drumkit sounds (as opposed to their common default setting of MIDI
  part 10 being a drumkit part and all other ones chromatic parts), in
  LS however one can switch between the first 16 MIDI instrument maps
  of all ones defined for the sampler
* bumped version to 0.5.1.6cvs

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

  ViewVC Help
Powered by ViewVC