/[svn]/linuxsampler/trunk/src/engines/gig/Engine.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/gig/Engine.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1297 - (show annotations) (download)
Thu Aug 16 15:55:21 2007 UTC (16 years, 7 months ago) by iliev
File size: 88144 byte(s)
* bugfix: the active stream/voice count statistic was incorrect

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

  ViewVC Help
Powered by ViewVC