/[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 1248 - (show annotations) (download)
Fri Jun 22 10:10:06 2007 UTC (16 years, 9 months ago) by persson
File size: 87321 byte(s)
* fixed some minor memory leaks

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 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
530 RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
531 while (iuiKey != end) { // iterate through all active keys
532 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
533 ++iuiKey;
534
535 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
536 RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
537 for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
538 // now render current voice
539 itVoice->Render(Samples);
540 if (itVoice->IsActive()) ActiveVoiceCountTemp++; // still active
541 else { // voice reached end, is now inactive
542 FreeVoice(pEngineChannel, itVoice); // remove voice from the list of active voices
543 }
544 }
545 }
546 }
547
548 /**
549 * Render all stolen voices (only voices which were stolen in this
550 * fragment) on the given engine channel. Stolen voices are rendered
551 * after all normal voices have been rendered; this is needed to render
552 * audio of those voices which were selected for voice stealing until
553 * the point were the stealing (that is the take over of the voice)
554 * actually happened.
555 *
556 * @param pEngineChannel - engine channel on which audio should be
557 * rendered
558 * @param Samples - amount of sample points to be rendered in
559 * this audio fragment cycle
560 */
561 void Engine::RenderStolenVoices(uint Samples) {
562 RTList<Event>::Iterator itVoiceStealEvent = pVoiceStealingQueue->first();
563 RTList<Event>::Iterator end = pVoiceStealingQueue->end();
564 for (; itVoiceStealEvent != end; ++itVoiceStealEvent) {
565 EngineChannel* pEngineChannel = (EngineChannel*) itVoiceStealEvent->pEngineChannel;
566 if (!pEngineChannel->pInstrument) continue; // ignore if no instrument loaded
567 Pool<Voice>::Iterator itNewVoice =
568 LaunchVoice(pEngineChannel, itVoiceStealEvent, itVoiceStealEvent->Param.Note.Layer, itVoiceStealEvent->Param.Note.ReleaseTrigger, false, false);
569 if (itNewVoice) {
570 itNewVoice->Render(Samples);
571 if (itNewVoice->IsActive()) ActiveVoiceCountTemp++; // still active
572 else { // voice reached end, is now inactive
573 FreeVoice(pEngineChannel, itNewVoice); // remove voice from the list of active voices
574 }
575 }
576 else dmsg(1,("gig::Engine: ERROR, voice stealing didn't work out!\n"));
577
578 // we need to clear the key's event list explicitly here in case key was never active
579 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoiceStealEvent->Param.Note.Key];
580 pKey->VoiceTheftsQueued--;
581 if (!pKey->Active && !pKey->VoiceTheftsQueued) pKey->pEvents->clear();
582 }
583 }
584
585 /**
586 * Will be called in case the respective engine channel sports FX send
587 * channels. In this particular case, engine channel local buffers are
588 * used to render and mix all voices to. This method is responsible for
589 * copying the audio data from those local buffers to the master audio
590 * output channels as well as to the FX send audio output channels with
591 * their respective FX send levels.
592 *
593 * @param pEngineChannel - engine channel from which audio should be
594 * routed
595 * @param Samples - amount of sample points to be routed in
596 * this audio fragment cycle
597 */
598 void Engine::RouteAudio(EngineChannel* pEngineChannel, uint Samples) {
599 // route master signal
600 {
601 AudioChannel* pDstL = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelLeft);
602 AudioChannel* pDstR = pAudioOutputDevice->Channel(pEngineChannel->AudioDeviceChannelRight);
603 pEngineChannel->pChannelLeft->MixTo(pDstL, Samples);
604 pEngineChannel->pChannelRight->MixTo(pDstR, Samples);
605 }
606 // route FX send signal
607 {
608 for (int iFxSend = 0; iFxSend < pEngineChannel->GetFxSendCount(); iFxSend++) {
609 FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
610 // left channel
611 const int iDstL = pFxSend->DestinationChannel(0);
612 if (iDstL < 0) {
613 dmsg(1,("Engine::RouteAudio() Error: invalid FX send (L) destination channel"));
614 } else {
615 AudioChannel* pDstL = pAudioOutputDevice->Channel(iDstL);
616 if (!pDstL) {
617 dmsg(1,("Engine::RouteAudio() Error: invalid FX send (L) destination channel"));
618 } else pEngineChannel->pChannelLeft->MixTo(pDstL, Samples, pFxSend->Level());
619 }
620 // right channel
621 const int iDstR = pFxSend->DestinationChannel(1);
622 if (iDstR < 0) {
623 dmsg(1,("Engine::RouteAudio() Error: invalid FX send (R) destination channel"));
624 } else {
625 AudioChannel* pDstR = pAudioOutputDevice->Channel(iDstR);
626 if (!pDstR) {
627 dmsg(1,("Engine::RouteAudio() Error: invalid FX send (R) destination channel"));
628 } else pEngineChannel->pChannelRight->MixTo(pDstR, Samples, pFxSend->Level());
629 }
630 }
631 }
632 // reset buffers with silence (zero out) for the next audio cycle
633 pEngineChannel->pChannelLeft->Clear();
634 pEngineChannel->pChannelRight->Clear();
635 }
636
637 /**
638 * Free all keys which have turned inactive in this audio fragment, from
639 * the list of active keys and clear all event lists on that engine
640 * channel.
641 *
642 * @param pEngineChannel - engine channel to cleanup
643 */
644 void Engine::PostProcess(EngineChannel* pEngineChannel) {
645 // free all keys which have no active voices left
646 {
647 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
648 RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
649 while (iuiKey != end) { // iterate through all active keys
650 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
651 ++iuiKey;
652 if (pKey->pActiveVoices->isEmpty()) FreeKey(pEngineChannel, pKey);
653 #if CONFIG_DEVMODE
654 else { // just a sanity check for debugging
655 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
656 RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
657 for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
658 if (itVoice->itKillEvent) {
659 dmsg(1,("gig::Engine: ERROR, killed voice survived !!!\n"));
660 }
661 }
662 }
663 #endif // CONFIG_DEVMODE
664 }
665 }
666
667 // empty the engine channel's own event lists
668 pEngineChannel->ClearEventLists();
669 }
670
671 /**
672 * Will be called by the MIDI input device whenever a MIDI system
673 * exclusive message has arrived.
674 *
675 * @param pData - pointer to sysex data
676 * @param Size - lenght of sysex data (in bytes)
677 */
678 void Engine::SendSysex(void* pData, uint Size) {
679 Event event = pEventGenerator->CreateEvent();
680 event.Type = Event::type_sysex;
681 event.Param.Sysex.Size = Size;
682 event.pEngineChannel = NULL; // as Engine global event
683 if (pEventQueue->write_space() > 0) {
684 if (pSysexBuffer->write_space() >= Size) {
685 // copy sysex data to input buffer
686 uint toWrite = Size;
687 uint8_t* pPos = (uint8_t*) pData;
688 while (toWrite) {
689 const uint writeNow = RTMath::Min(toWrite, pSysexBuffer->write_space_to_end());
690 pSysexBuffer->write(pPos, writeNow);
691 toWrite -= writeNow;
692 pPos += writeNow;
693
694 }
695 // finally place sysex event into input event queue
696 pEventQueue->push(&event);
697 }
698 else dmsg(1,("Engine: Sysex message too large (%d byte) for input buffer (%d byte)!",Size,CONFIG_SYSEX_BUFFER_SIZE));
699 }
700 else dmsg(1,("Engine: Input event queue full!"));
701 }
702
703 /**
704 * Assigns and triggers a new voice for the respective MIDI key.
705 *
706 * @param pEngineChannel - engine channel on which this event occured on
707 * @param itNoteOnEvent - key, velocity and time stamp of the event
708 */
709 void Engine::ProcessNoteOn(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
710 #if !CONFIG_PROCESS_MUTED_CHANNELS
711 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
712 #endif
713
714 if (!pEngineChannel->pInstrument) return; // ignore if no instrument loaded
715
716 //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
717 itNoteOnEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
718
719 const int key = itNoteOnEvent->Param.Note.Key;
720 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key];
721
722 // move note on event to the key's own event list
723 RTList<Event>::Iterator itNoteOnEventOnKeyList = itNoteOnEvent.moveToEndOf(pKey->pEvents);
724
725 // if Solo Mode then kill all already active voices
726 if (pEngineChannel->SoloMode) {
727 Pool<uint>::Iterator itYoungestKey = pEngineChannel->pActiveKeys->last();
728 if (itYoungestKey) {
729 const int iYoungestKey = *itYoungestKey;
730 const midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[iYoungestKey];
731 if (pOtherKey->Active) {
732 // get final portamento position of currently active voice
733 if (pEngineChannel->PortamentoMode) {
734 RTList<Voice>::Iterator itVoice = pOtherKey->pActiveVoices->last();
735 if (itVoice) itVoice->UpdatePortamentoPos(itNoteOnEventOnKeyList);
736 }
737 // kill all voices on the (other) key
738 RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
739 RTList<Voice>::Iterator end = pOtherKey->pActiveVoices->end();
740 for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
741 if (itVoiceToBeKilled->Type != Voice::type_release_trigger)
742 itVoiceToBeKilled->Kill(itNoteOnEventOnKeyList);
743 }
744 }
745 }
746 // set this key as 'currently active solo key'
747 pEngineChannel->SoloKey = key;
748 }
749
750 // Change key dimension value if key is in keyswitching area
751 {
752 const ::gig::Instrument* pInstrument = pEngineChannel->pInstrument;
753 if (key >= pInstrument->DimensionKeyRange.low && key <= pInstrument->DimensionKeyRange.high)
754 pEngineChannel->CurrentKeyDimension = float(key - pInstrument->DimensionKeyRange.low) /
755 (pInstrument->DimensionKeyRange.high - pInstrument->DimensionKeyRange.low + 1);
756 }
757
758 pKey->KeyPressed = true; // the MIDI key was now pressed down
759 pKey->Velocity = itNoteOnEventOnKeyList->Param.Note.Velocity;
760 pKey->NoteOnTime = FrameTime + itNoteOnEventOnKeyList->FragmentPos(); // will be used to calculate note length
761
762 // cancel release process of voices on this key if needed
763 if (pKey->Active && !pEngineChannel->SustainPedal) {
764 RTList<Event>::Iterator itCancelReleaseEvent = pKey->pEvents->allocAppend();
765 if (itCancelReleaseEvent) {
766 *itCancelReleaseEvent = *itNoteOnEventOnKeyList; // copy event
767 itCancelReleaseEvent->Type = Event::type_cancel_release; // transform event type
768 }
769 else dmsg(1,("Event pool emtpy!\n"));
770 }
771
772 // allocate and trigger new voice(s) for the key
773 {
774 // first, get total amount of required voices (dependant on amount of layers)
775 ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOnEventOnKeyList->Param.Note.Key);
776 if (pRegion) {
777 int voicesRequired = pRegion->Layers;
778 // now launch the required amount of voices
779 for (int i = 0; i < voicesRequired; i++)
780 LaunchVoice(pEngineChannel, itNoteOnEventOnKeyList, i, false, true, true);
781 }
782 }
783
784 // if neither a voice was spawned or postponed then remove note on event from key again
785 if (!pKey->Active && !pKey->VoiceTheftsQueued)
786 pKey->pEvents->free(itNoteOnEventOnKeyList);
787
788 if (!pEngineChannel->SoloMode || pEngineChannel->PortamentoPos < 0.0f) pEngineChannel->PortamentoPos = (float) key;
789 pKey->RoundRobinIndex++;
790 }
791
792 /**
793 * Releases the voices on the given key if sustain pedal is not pressed.
794 * If sustain is pressed, the release of the note will be postponed until
795 * sustain pedal will be released or voice turned inactive by itself (e.g.
796 * due to completion of sample playback).
797 *
798 * @param pEngineChannel - engine channel on which this event occured on
799 * @param itNoteOffEvent - key, velocity and time stamp of the event
800 */
801 void Engine::ProcessNoteOff(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOffEvent) {
802 #if !CONFIG_PROCESS_MUTED_CHANNELS
803 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
804 #endif
805
806 //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
807 itNoteOffEvent->Param.Note.Key += pEngineChannel->GlobalTranspose;
808
809 const int iKey = itNoteOffEvent->Param.Note.Key;
810 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[iKey];
811 pKey->KeyPressed = false; // the MIDI key was now released
812
813 // move event to the key's own event list
814 RTList<Event>::Iterator itNoteOffEventOnKeyList = itNoteOffEvent.moveToEndOf(pKey->pEvents);
815
816 bool bShouldRelease = pKey->Active && ShouldReleaseVoice(pEngineChannel, itNoteOffEventOnKeyList->Param.Note.Key);
817
818 // in case Solo Mode is enabled, kill all voices on this key and respawn a voice on the highest pressed key (if any)
819 if (pEngineChannel->SoloMode && pEngineChannel->pInstrument) { //TODO: this feels like too much code just for handling solo mode :P
820 bool bOtherKeysPressed = false;
821 if (iKey == pEngineChannel->SoloKey) {
822 pEngineChannel->SoloKey = -1;
823 // if there's still a key pressed down, respawn a voice (group) on the highest key
824 for (int i = 127; i > 0; i--) {
825 midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[i];
826 if (pOtherKey->KeyPressed) {
827 bOtherKeysPressed = true;
828 // make the other key the new 'currently active solo key'
829 pEngineChannel->SoloKey = i;
830 // get final portamento position of currently active voice
831 if (pEngineChannel->PortamentoMode) {
832 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
833 if (itVoice) itVoice->UpdatePortamentoPos(itNoteOffEventOnKeyList);
834 }
835 // create a pseudo note on event
836 RTList<Event>::Iterator itPseudoNoteOnEvent = pOtherKey->pEvents->allocAppend();
837 if (itPseudoNoteOnEvent) {
838 // copy event
839 *itPseudoNoteOnEvent = *itNoteOffEventOnKeyList;
840 // transform event to a note on event
841 itPseudoNoteOnEvent->Type = Event::type_note_on;
842 itPseudoNoteOnEvent->Param.Note.Key = i;
843 itPseudoNoteOnEvent->Param.Note.Velocity = pOtherKey->Velocity;
844 // allocate and trigger new voice(s) for the other key
845 {
846 // first, get total amount of required voices (dependant on amount of layers)
847 ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(i);
848 if (pRegion) {
849 int voicesRequired = pRegion->Layers;
850 // now launch the required amount of voices
851 for (int iLayer = 0; iLayer < voicesRequired; iLayer++)
852 LaunchVoice(pEngineChannel, itPseudoNoteOnEvent, iLayer, false, true, false);
853 }
854 }
855 // if neither a voice was spawned or postponed then remove note on event from key again
856 if (!pOtherKey->Active && !pOtherKey->VoiceTheftsQueued)
857 pOtherKey->pEvents->free(itPseudoNoteOnEvent);
858
859 } else dmsg(1,("Could not respawn voice, no free event left\n"));
860 break; // done
861 }
862 }
863 }
864 if (bOtherKeysPressed) {
865 if (pKey->Active) { // kill all voices on this key
866 bShouldRelease = false; // no need to release, as we kill it here
867 RTList<Voice>::Iterator itVoiceToBeKilled = pKey->pActiveVoices->first();
868 RTList<Voice>::Iterator end = pKey->pActiveVoices->end();
869 for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
870 if (itVoiceToBeKilled->Type != Voice::type_release_trigger)
871 itVoiceToBeKilled->Kill(itNoteOffEventOnKeyList);
872 }
873 }
874 } else pEngineChannel->PortamentoPos = -1.0f;
875 }
876
877 // if no solo mode (the usual case) or if solo mode and no other key pressed, then release voices on this key if needed
878 if (bShouldRelease) {
879 itNoteOffEventOnKeyList->Type = Event::type_release; // transform event type
880
881 // spawn release triggered voice(s) if needed
882 if (pKey->ReleaseTrigger && pEngineChannel->pInstrument) {
883 // first, get total amount of required voices (dependant on amount of layers)
884 ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key);
885 if (pRegion) {
886 int voicesRequired = pRegion->Layers;
887
888 // MIDI note-on velocity is used instead of note-off velocity
889 itNoteOffEventOnKeyList->Param.Note.Velocity = pKey->Velocity;
890
891 // now launch the required amount of voices
892 for (int i = 0; i < voicesRequired; i++)
893 LaunchVoice(pEngineChannel, itNoteOffEventOnKeyList, i, true, false, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples
894 }
895 pKey->ReleaseTrigger = false;
896 }
897 }
898
899 // if neither a voice was spawned or postponed on this key then remove note off event from key again
900 if (!pKey->Active && !pKey->VoiceTheftsQueued)
901 pKey->pEvents->free(itNoteOffEventOnKeyList);
902 }
903
904 /**
905 * Moves pitchbend event from the general (input) event list to the engine
906 * channel's event list. It will actually processed later by the
907 * respective voice.
908 *
909 * @param pEngineChannel - engine channel on which this event occured on
910 * @param itPitchbendEvent - absolute pitch value and time stamp of the event
911 */
912 void Engine::ProcessPitchbend(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itPitchbendEvent) {
913 pEngineChannel->Pitch = itPitchbendEvent->Param.Pitch.Pitch; // store current pitch value
914 }
915
916 /**
917 * Allocates and triggers a new voice. This method will usually be
918 * called by the ProcessNoteOn() method and by the voices itself
919 * (e.g. to spawn further voices on the same key for layered sounds).
920 *
921 * @param pEngineChannel - engine channel on which this event occured on
922 * @param itNoteOnEvent - key, velocity and time stamp of the event
923 * @param iLayer - layer index for the new voice (optional - only
924 * in case of layered sounds of course)
925 * @param ReleaseTriggerVoice - if new voice is a release triggered voice
926 * (optional, default = false)
927 * @param VoiceStealing - if voice stealing should be performed
928 * when there is no free voice
929 * (optional, default = true)
930 * @param HandleKeyGroupConflicts - if voices should be killed due to a
931 * key group conflict
932 * @returns pointer to new voice or NULL if there was no free voice or
933 * if the voice wasn't triggered (for example when no region is
934 * defined for the given key).
935 */
936 Pool<Voice>::Iterator Engine::LaunchVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing, bool HandleKeyGroupConflicts) {
937 int MIDIKey = itNoteOnEvent->Param.Note.Key;
938 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[MIDIKey];
939 ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(MIDIKey);
940
941 // if nothing defined for this key
942 if (!pRegion) return Pool<Voice>::Iterator(); // nothing to do
943
944 // only mark the first voice of a layered voice (group) to be in a
945 // key group, so the layered voices won't kill each other
946 int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;
947
948 // handle key group (a.k.a. exclusive group) conflicts
949 if (HandleKeyGroupConflicts) {
950 if (iKeyGroup) { // if this voice / key belongs to a key group
951 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[iKeyGroup];
952 if (*ppKeyGroup) { // if there's already an active key in that key group
953 midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[**ppKeyGroup];
954 // kill all voices on the (other) key
955 RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
956 RTList<Voice>::Iterator end = pOtherKey->pActiveVoices->end();
957 for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
958 if (itVoiceToBeKilled->Type != Voice::type_release_trigger) {
959 itVoiceToBeKilled->Kill(itNoteOnEvent);
960 --VoiceSpawnsLeft; //FIXME: just a hack, we should better check in StealVoice() if the voice was killed due to key conflict
961 }
962 }
963 }
964 }
965 }
966
967 Voice::type_t VoiceType = Voice::type_normal;
968
969 // get current dimension values to select the right dimension region
970 //TODO: for stolen voices this dimension region selection block is processed twice, this should be changed
971 //FIXME: controller values for selecting the dimension region here are currently not sample accurate
972 uint DimValues[8] = { 0 };
973 for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
974 switch (pRegion->pDimensionDefinitions[i].dimension) {
975 case ::gig::dimension_samplechannel:
976 DimValues[i] = 0; //TODO: we currently ignore this dimension
977 break;
978 case ::gig::dimension_layer:
979 DimValues[i] = iLayer;
980 break;
981 case ::gig::dimension_velocity:
982 DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
983 break;
984 case ::gig::dimension_channelaftertouch:
985 DimValues[i] = pEngineChannel->ControllerTable[128];
986 break;
987 case ::gig::dimension_releasetrigger:
988 VoiceType = (ReleaseTriggerVoice) ? Voice::type_release_trigger : (!iLayer) ? Voice::type_release_trigger_required : Voice::type_normal;
989 DimValues[i] = (uint) ReleaseTriggerVoice;
990 break;
991 case ::gig::dimension_keyboard:
992 DimValues[i] = (uint) (pEngineChannel->CurrentKeyDimension * pRegion->pDimensionDefinitions[i].zones);
993 break;
994 case ::gig::dimension_roundrobin:
995 DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on
996 break;
997 case ::gig::dimension_random:
998 RandomSeed = RandomSeed * 1103515245 + 12345; // classic pseudo random number generator
999 DimValues[i] = (uint) RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random
1000 break;
1001 case ::gig::dimension_modwheel:
1002 DimValues[i] = pEngineChannel->ControllerTable[1];
1003 break;
1004 case ::gig::dimension_breath:
1005 DimValues[i] = pEngineChannel->ControllerTable[2];
1006 break;
1007 case ::gig::dimension_foot:
1008 DimValues[i] = pEngineChannel->ControllerTable[4];
1009 break;
1010 case ::gig::dimension_portamentotime:
1011 DimValues[i] = pEngineChannel->ControllerTable[5];
1012 break;
1013 case ::gig::dimension_effect1:
1014 DimValues[i] = pEngineChannel->ControllerTable[12];
1015 break;
1016 case ::gig::dimension_effect2:
1017 DimValues[i] = pEngineChannel->ControllerTable[13];
1018 break;
1019 case ::gig::dimension_genpurpose1:
1020 DimValues[i] = pEngineChannel->ControllerTable[16];
1021 break;
1022 case ::gig::dimension_genpurpose2:
1023 DimValues[i] = pEngineChannel->ControllerTable[17];
1024 break;
1025 case ::gig::dimension_genpurpose3:
1026 DimValues[i] = pEngineChannel->ControllerTable[18];
1027 break;
1028 case ::gig::dimension_genpurpose4:
1029 DimValues[i] = pEngineChannel->ControllerTable[19];
1030 break;
1031 case ::gig::dimension_sustainpedal:
1032 DimValues[i] = pEngineChannel->ControllerTable[64];
1033 break;
1034 case ::gig::dimension_portamento:
1035 DimValues[i] = pEngineChannel->ControllerTable[65];
1036 break;
1037 case ::gig::dimension_sostenutopedal:
1038 DimValues[i] = pEngineChannel->ControllerTable[66];
1039 break;
1040 case ::gig::dimension_softpedal:
1041 DimValues[i] = pEngineChannel->ControllerTable[67];
1042 break;
1043 case ::gig::dimension_genpurpose5:
1044 DimValues[i] = pEngineChannel->ControllerTable[80];
1045 break;
1046 case ::gig::dimension_genpurpose6:
1047 DimValues[i] = pEngineChannel->ControllerTable[81];
1048 break;
1049 case ::gig::dimension_genpurpose7:
1050 DimValues[i] = pEngineChannel->ControllerTable[82];
1051 break;
1052 case ::gig::dimension_genpurpose8:
1053 DimValues[i] = pEngineChannel->ControllerTable[83];
1054 break;
1055 case ::gig::dimension_effect1depth:
1056 DimValues[i] = pEngineChannel->ControllerTable[91];
1057 break;
1058 case ::gig::dimension_effect2depth:
1059 DimValues[i] = pEngineChannel->ControllerTable[92];
1060 break;
1061 case ::gig::dimension_effect3depth:
1062 DimValues[i] = pEngineChannel->ControllerTable[93];
1063 break;
1064 case ::gig::dimension_effect4depth:
1065 DimValues[i] = pEngineChannel->ControllerTable[94];
1066 break;
1067 case ::gig::dimension_effect5depth:
1068 DimValues[i] = pEngineChannel->ControllerTable[95];
1069 break;
1070 case ::gig::dimension_none:
1071 std::cerr << "gig::Engine::LaunchVoice() Error: dimension=none\n" << std::flush;
1072 break;
1073 default:
1074 std::cerr << "gig::Engine::LaunchVoice() Error: Unknown dimension\n" << std::flush;
1075 }
1076 }
1077
1078 // return if this is a release triggered voice and there is no
1079 // releasetrigger dimension (could happen if an instrument
1080 // change has occured between note on and off)
1081 if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
1082
1083 ::gig::DimensionRegion* pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
1084
1085 // no need to continue if sample is silent
1086 if (!pDimRgn->pSample || !pDimRgn->pSample->SamplesTotal) return Pool<Voice>::Iterator();
1087
1088 // allocate a new voice for the key
1089 Pool<Voice>::Iterator itNewVoice = pKey->pActiveVoices->allocAppend();
1090 if (itNewVoice) {
1091 // launch the new voice
1092 if (itNewVoice->Trigger(pEngineChannel, itNoteOnEvent, pEngineChannel->Pitch, pDimRgn, VoiceType, iKeyGroup) < 0) {
1093 dmsg(4,("Voice not triggered\n"));
1094 pKey->pActiveVoices->free(itNewVoice);
1095 }
1096 else { // on success
1097 --VoiceSpawnsLeft;
1098 if (!pKey->Active) { // mark as active key
1099 pKey->Active = true;
1100 pKey->itSelf = pEngineChannel->pActiveKeys->allocAppend();
1101 *pKey->itSelf = itNoteOnEvent->Param.Note.Key;
1102 }
1103 if (itNewVoice->KeyGroup) {
1104 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[itNewVoice->KeyGroup];
1105 *ppKeyGroup = &*pKey->itSelf; // put key as the (new) active key to its key group
1106 }
1107 if (itNewVoice->Type == Voice::type_release_trigger_required) pKey->ReleaseTrigger = true; // mark key for the need of release triggered voice(s)
1108 return itNewVoice; // success
1109 }
1110 }
1111 else if (VoiceStealing) {
1112 // try to steal one voice
1113 int result = StealVoice(pEngineChannel, itNoteOnEvent);
1114 if (!result) { // voice stolen successfully
1115 // put note-on event into voice-stealing queue, so it will be reprocessed after killed voice died
1116 RTList<Event>::Iterator itStealEvent = pVoiceStealingQueue->allocAppend();
1117 if (itStealEvent) {
1118 *itStealEvent = *itNoteOnEvent; // copy event
1119 itStealEvent->Param.Note.Layer = iLayer;
1120 itStealEvent->Param.Note.ReleaseTrigger = ReleaseTriggerVoice;
1121 pKey->VoiceTheftsQueued++;
1122 }
1123 else dmsg(1,("Voice stealing queue full!\n"));
1124 }
1125 }
1126
1127 return Pool<Voice>::Iterator(); // no free voice or error
1128 }
1129
1130 /**
1131 * Will be called by LaunchVoice() method in case there are no free
1132 * voices left. This method will select and kill one old voice for
1133 * voice stealing and postpone the note-on event until the selected
1134 * voice actually died.
1135 *
1136 * @param pEngineChannel - engine channel on which this event occured on
1137 * @param itNoteOnEvent - key, velocity and time stamp of the event
1138 * @returns 0 on success, a value < 0 if no active voice could be picked for voice stealing
1139 */
1140 int Engine::StealVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
1141 if (VoiceSpawnsLeft <= 0) {
1142 dmsg(1,("Max. voice thefts per audio fragment reached (you may raise CONFIG_MAX_VOICES).\n"));
1143 return -1;
1144 }
1145 if (!pEventPool->poolIsEmpty()) {
1146
1147 RTList<Voice>::Iterator itSelectedVoice;
1148
1149 // Select one voice for voice stealing
1150 switch (CONFIG_VOICE_STEAL_ALGO) {
1151
1152 // try to pick the oldest voice on the key where the new
1153 // voice should be spawned, if there is no voice on that
1154 // key, or no voice left to kill, then procceed with
1155 // 'oldestkey' algorithm
1156 case voice_steal_algo_oldestvoiceonkey: {
1157 midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key];
1158 itSelectedVoice = pSelectedKey->pActiveVoices->first();
1159 // proceed iterating if voice was created in this fragment cycle
1160 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1161 // if we haven't found a voice then proceed with algorithm 'oldestkey'
1162 if (itSelectedVoice && itSelectedVoice->IsStealable()) break;
1163 } // no break - intentional !
1164
1165 // try to pick the oldest voice on the oldest active key
1166 // from the same engine channel
1167 // (caution: must stay after 'oldestvoiceonkey' algorithm !)
1168 case voice_steal_algo_oldestkey: {
1169 // if we already stole in this fragment, try to proceed on same key
1170 if (this->itLastStolenVoice) {
1171 itSelectedVoice = this->itLastStolenVoice;
1172 do {
1173 ++itSelectedVoice;
1174 } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1175 // found a "stealable" voice ?
1176 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1177 // remember which voice we stole, so we can simply proceed on next voice stealing
1178 this->itLastStolenVoice = itSelectedVoice;
1179 break; // selection succeeded
1180 }
1181 }
1182 // get (next) oldest key
1183 RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKey) ? ++this->iuiLastStolenKey : pEngineChannel->pActiveKeys->first();
1184 while (iuiSelectedKey) {
1185 midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[*iuiSelectedKey];
1186 itSelectedVoice = pSelectedKey->pActiveVoices->first();
1187 // proceed iterating if voice was created in this fragment cycle
1188 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1189 // found a "stealable" voice ?
1190 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1191 // remember which voice on which key we stole, so we can simply proceed on next voice stealing
1192 this->iuiLastStolenKey = iuiSelectedKey;
1193 this->itLastStolenVoice = itSelectedVoice;
1194 break; // selection succeeded
1195 }
1196 ++iuiSelectedKey; // get next oldest key
1197 }
1198 break;
1199 }
1200
1201 // don't steal anything
1202 case voice_steal_algo_none:
1203 default: {
1204 dmsg(1,("No free voice (voice stealing disabled)!\n"));
1205 return -1;
1206 }
1207 }
1208
1209 // if we couldn't steal a voice from the same engine channel then
1210 // steal oldest voice on the oldest key from any other engine channel
1211 // (the smaller engine channel number, the higher priority)
1212 if (!itSelectedVoice || !itSelectedVoice->IsStealable()) {
1213 EngineChannel* pSelectedChannel;
1214 int iChannelIndex;
1215 // select engine channel
1216 if (pLastStolenChannel) {
1217 pSelectedChannel = pLastStolenChannel;
1218 iChannelIndex = pSelectedChannel->iEngineIndexSelf;
1219 } else { // pick the engine channel followed by this engine channel
1220 iChannelIndex = (pEngineChannel->iEngineIndexSelf + 1) % engineChannels.size();
1221 pSelectedChannel = engineChannels[iChannelIndex];
1222 }
1223
1224 // if we already stole in this fragment, try to proceed on same key
1225 if (this->itLastStolenVoiceGlobally) {
1226 itSelectedVoice = this->itLastStolenVoiceGlobally;
1227 do {
1228 ++itSelectedVoice;
1229 } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1230 }
1231
1232 #if CONFIG_DEVMODE
1233 EngineChannel* pBegin = pSelectedChannel; // to detect endless loop
1234 #endif // CONFIG_DEVMODE
1235
1236 // did we find a 'stealable' voice?
1237 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1238 // remember which voice we stole, so we can simply proceed on next voice stealing
1239 this->itLastStolenVoiceGlobally = itSelectedVoice;
1240 } else while (true) { // iterate through engine channels
1241 // get (next) oldest key
1242 RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKeyGlobally) ? ++this->iuiLastStolenKeyGlobally : pSelectedChannel->pActiveKeys->first();
1243 this->iuiLastStolenKeyGlobally = RTList<uint>::Iterator(); // to prevent endless loop (see line above)
1244 while (iuiSelectedKey) {
1245 midi_key_info_t* pSelectedKey = &pSelectedChannel->pMIDIKeyInfo[*iuiSelectedKey];
1246 itSelectedVoice = pSelectedKey->pActiveVoices->first();
1247 // proceed iterating if voice was created in this fragment cycle
1248 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1249 // found a "stealable" voice ?
1250 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1251 // remember which voice on which key on which engine channel we stole, so we can simply proceed on next voice stealing
1252 this->iuiLastStolenKeyGlobally = iuiSelectedKey;
1253 this->itLastStolenVoiceGlobally = itSelectedVoice;
1254 this->pLastStolenChannel = pSelectedChannel;
1255 goto stealable_voice_found; // selection succeeded
1256 }
1257 ++iuiSelectedKey; // get next key on current engine channel
1258 }
1259 // get next engine channel
1260 iChannelIndex = (iChannelIndex + 1) % engineChannels.size();
1261 pSelectedChannel = engineChannels[iChannelIndex];
1262
1263 #if CONFIG_DEVMODE
1264 if (pSelectedChannel == pBegin) {
1265 dmsg(1,("FATAL ERROR: voice stealing endless loop!\n"));
1266 dmsg(1,("VoiceSpawnsLeft=%d.\n", VoiceSpawnsLeft));
1267 dmsg(1,("Exiting.\n"));
1268 exit(-1);
1269 }
1270 #endif // CONFIG_DEVMODE
1271 }
1272 }
1273
1274 // jump point if a 'stealable' voice was found
1275 stealable_voice_found:
1276
1277 #if CONFIG_DEVMODE
1278 if (!itSelectedVoice->IsActive()) {
1279 dmsg(1,("gig::Engine: ERROR, tried to steal a voice which was not active !!!\n"));
1280 return -1;
1281 }
1282 #endif // CONFIG_DEVMODE
1283
1284 // now kill the selected voice
1285 itSelectedVoice->Kill(itNoteOnEvent);
1286
1287 --VoiceSpawnsLeft;
1288
1289 return 0; // success
1290 }
1291 else {
1292 dmsg(1,("Event pool emtpy!\n"));
1293 return -1;
1294 }
1295 }
1296
1297 /**
1298 * Removes the given voice from the MIDI key's list of active voices.
1299 * This method will be called when a voice went inactive, e.g. because
1300 * it finished to playback its sample, finished its release stage or
1301 * just was killed.
1302 *
1303 * @param pEngineChannel - engine channel on which this event occured on
1304 * @param itVoice - points to the voice to be freed
1305 */
1306 void Engine::FreeVoice(EngineChannel* pEngineChannel, Pool<Voice>::Iterator& itVoice) {
1307 if (itVoice) {
1308 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoice->MIDIKey];
1309
1310 uint keygroup = itVoice->KeyGroup;
1311
1312 // if the sample and dimension region belong to an
1313 // instrument that is unloaded, tell the disk thread to
1314 // release them
1315 if (itVoice->Orphan) {
1316 pDiskThread->OrderDeletionOfDimreg(itVoice->pDimRgn);
1317 }
1318
1319 // free the voice object
1320 pVoicePool->free(itVoice);
1321
1322 // if no other voices left and member of a key group, remove from key group
1323 if (pKey->pActiveVoices->isEmpty() && keygroup) {
1324 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[keygroup];
1325 if (*ppKeyGroup == &*pKey->itSelf) *ppKeyGroup = NULL; // remove key from key group
1326 }
1327 }
1328 else std::cerr << "Couldn't release voice! (!itVoice)\n" << std::flush;
1329 }
1330
1331 /**
1332 * Called when there's no more voice left on a key, this call will
1333 * update the key info respectively.
1334 *
1335 * @param pEngineChannel - engine channel on which this event occured on
1336 * @param pKey - key which is now inactive
1337 */
1338 void Engine::FreeKey(EngineChannel* pEngineChannel, midi_key_info_t* pKey) {
1339 if (pKey->pActiveVoices->isEmpty()) {
1340 pKey->Active = false;
1341 pEngineChannel->pActiveKeys->free(pKey->itSelf); // remove key from list of active keys
1342 pKey->itSelf = RTList<uint>::Iterator();
1343 pKey->ReleaseTrigger = false;
1344 pKey->pEvents->clear();
1345 dmsg(3,("Key has no more voices now\n"));
1346 }
1347 else dmsg(1,("gig::Engine: Oops, tried to free a key which contains voices.\n"));
1348 }
1349
1350 /**
1351 * Reacts on supported control change commands (e.g. pitch bend wheel,
1352 * modulation wheel, aftertouch).
1353 *
1354 * @param pEngineChannel - engine channel on which this event occured on
1355 * @param itControlChangeEvent - controller, value and time stamp of the event
1356 */
1357 void Engine::ProcessControlChange(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itControlChangeEvent) {
1358 dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));
1359
1360 // update controller value in the engine channel's controller table
1361 pEngineChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;
1362
1363 // handle hard coded MIDI controllers
1364 switch (itControlChangeEvent->Param.CC.Controller) {
1365 case 5: { // portamento time
1366 pEngineChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN;
1367 break;
1368 }
1369 case 6: { // data entry (currently only used for RPN controllers)
1370 if (pEngineChannel->GetMidiRpnController() == 2) { // coarse tuning in half tones
1371 int transpose = (int) itControlChangeEvent->Param.CC.Value - 64;
1372 // limit to +- two octaves for now
1373 transpose = RTMath::Min(transpose, 24);
1374 transpose = RTMath::Max(transpose, -24);
1375 pEngineChannel->GlobalTranspose = transpose;
1376 // workaround, so we won't have hanging notes
1377 ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1378 }
1379 // to avoid other MIDI CC #6 messages to be misenterpreted as RPN controller data
1380 pEngineChannel->ResetMidiRpnController();
1381 break;
1382 }
1383 case 7: { // volume
1384 //TODO: not sample accurate yet
1385 pEngineChannel->MidiVolume = VolumeCurve[itControlChangeEvent->Param.CC.Value];
1386 pEngineChannel->bStatusChanged = true; // engine channel status has changed, so set notify flag
1387 break;
1388 }
1389 case 10: { // panpot
1390 //TODO: not sample accurate yet
1391 pEngineChannel->GlobalPanLeft = PanCurve[128 - itControlChangeEvent->Param.CC.Value];
1392 pEngineChannel->GlobalPanRight = PanCurve[itControlChangeEvent->Param.CC.Value];
1393 break;
1394 }
1395 case 64: { // sustain
1396 if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SustainPedal) {
1397 dmsg(4,("DAMPER (RIGHT) PEDAL DOWN\n"));
1398 pEngineChannel->SustainPedal = true;
1399
1400 #if !CONFIG_PROCESS_MUTED_CHANNELS
1401 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1402 #endif
1403
1404 // cancel release process of voices if necessary
1405 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1406 for (; iuiKey; ++iuiKey) {
1407 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1408 if (!pKey->KeyPressed) {
1409 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1410 if (itNewEvent) {
1411 *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1412 itNewEvent->Type = Event::type_cancel_release; // transform event type
1413 }
1414 else dmsg(1,("Event pool emtpy!\n"));
1415 }
1416 }
1417 }
1418 if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SustainPedal) {
1419 dmsg(4,("DAMPER (RIGHT) PEDAL UP\n"));
1420 pEngineChannel->SustainPedal = false;
1421
1422 #if !CONFIG_PROCESS_MUTED_CHANNELS
1423 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1424 #endif
1425
1426 // release voices if their respective key is not pressed
1427 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1428 for (; iuiKey; ++iuiKey) {
1429 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1430 if (!pKey->KeyPressed && ShouldReleaseVoice(pEngineChannel, *iuiKey)) {
1431 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1432 if (itNewEvent) {
1433 *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1434 itNewEvent->Type = Event::type_release; // transform event type
1435 }
1436 else dmsg(1,("Event pool emtpy!\n"));
1437 }
1438 }
1439 }
1440 break;
1441 }
1442 case 65: { // portamento on / off
1443 KillAllVoices(pEngineChannel, itControlChangeEvent);
1444 pEngineChannel->PortamentoMode = itControlChangeEvent->Param.CC.Value >= 64;
1445 break;
1446 }
1447 case 66: { // sostenuto
1448 if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SostenutoPedal) {
1449 dmsg(4,("SOSTENUTO (CENTER) PEDAL DOWN\n"));
1450 pEngineChannel->SostenutoPedal = true;
1451
1452 #if !CONFIG_PROCESS_MUTED_CHANNELS
1453 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1454 #endif
1455
1456 SostenutoKeyCount = 0;
1457 // Remeber the pressed keys
1458 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1459 for (; iuiKey; ++iuiKey) {
1460 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1461 if (pKey->KeyPressed && SostenutoKeyCount < 128) SostenutoKeys[SostenutoKeyCount++] = *iuiKey;
1462 }
1463 }
1464 if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SostenutoPedal) {
1465 dmsg(4,("SOSTENUTO (CENTER) PEDAL UP\n"));
1466 pEngineChannel->SostenutoPedal = false;
1467
1468 #if !CONFIG_PROCESS_MUTED_CHANNELS
1469 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1470 #endif
1471
1472 // release voices if the damper pedal is up and their respective key is not pressed
1473 for (int i = 0; i < SostenutoKeyCount; i++) {
1474 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[SostenutoKeys[i]];
1475 if (!pKey->KeyPressed && !pEngineChannel->SustainPedal) {
1476 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1477 if (itNewEvent) {
1478 *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
1479 itNewEvent->Type = Event::type_release; // transform event type
1480 }
1481 else dmsg(1,("Event pool emtpy!\n"));
1482 }
1483 }
1484 }
1485 break;
1486 }
1487 case 100: { // RPN controller LSB
1488 pEngineChannel->SetMidiRpnControllerLsb(itControlChangeEvent->Param.CC.Value);
1489 break;
1490 }
1491 case 101: { // RPN controller MSB
1492 pEngineChannel->SetMidiRpnControllerMsb(itControlChangeEvent->Param.CC.Value);
1493 break;
1494 }
1495
1496
1497 // Channel Mode Messages
1498
1499 case 120: { // all sound off
1500 KillAllVoices(pEngineChannel, itControlChangeEvent);
1501 break;
1502 }
1503 case 121: { // reset all controllers
1504 pEngineChannel->ResetControllers();
1505 break;
1506 }
1507 case 123: { // all notes off
1508 #if CONFIG_PROCESS_ALL_NOTES_OFF
1509 ReleaseAllVoices(pEngineChannel, itControlChangeEvent);
1510 #endif // CONFIG_PROCESS_ALL_NOTES_OFF
1511 break;
1512 }
1513 case 126: { // mono mode on
1514 KillAllVoices(pEngineChannel, itControlChangeEvent);
1515 pEngineChannel->SoloMode = true;
1516 break;
1517 }
1518 case 127: { // poly mode on
1519 KillAllVoices(pEngineChannel, itControlChangeEvent);
1520 pEngineChannel->SoloMode = false;
1521 break;
1522 }
1523 }
1524
1525 // handle FX send controllers
1526 if (!pEngineChannel->fxSends.empty()) {
1527 for (int iFxSend = 0; iFxSend < pEngineChannel->GetFxSendCount(); iFxSend++) {
1528 FxSend* pFxSend = pEngineChannel->GetFxSend(iFxSend);
1529 if (pFxSend->MidiController() == itControlChangeEvent->Param.CC.Controller)
1530 pFxSend->SetLevel(itControlChangeEvent->Param.CC.Value);
1531 pFxSend->SetInfoChanged(true);
1532 }
1533 }
1534 }
1535
1536 /**
1537 * Reacts on MIDI system exclusive messages.
1538 *
1539 * @param itSysexEvent - sysex data size and time stamp of the sysex event
1540 */
1541 void Engine::ProcessSysex(Pool<Event>::Iterator& itSysexEvent) {
1542 RingBuffer<uint8_t,false>::NonVolatileReader reader = pSysexBuffer->get_non_volatile_reader();
1543
1544 uint8_t exclusive_status, id;
1545 if (!reader.pop(&exclusive_status)) goto free_sysex_data;
1546 if (!reader.pop(&id)) goto free_sysex_data;
1547 if (exclusive_status != 0xF0) goto free_sysex_data;
1548
1549 switch (id) {
1550 case 0x41: { // Roland
1551 dmsg(3,("Roland Sysex\n"));
1552 uint8_t device_id, model_id, cmd_id;
1553 if (!reader.pop(&device_id)) goto free_sysex_data;
1554 if (!reader.pop(&model_id)) goto free_sysex_data;
1555 if (!reader.pop(&cmd_id)) goto free_sysex_data;
1556 if (model_id != 0x42 /*GS*/) goto free_sysex_data;
1557 if (cmd_id != 0x12 /*DT1*/) goto free_sysex_data;
1558
1559 // command address
1560 uint8_t addr[3]; // 2 byte addr MSB, followed by 1 byte addr LSB)
1561 const RingBuffer<uint8_t,false>::NonVolatileReader checksum_reader = reader; // so we can calculate the check sum later
1562 if (reader.read(&addr[0], 3) != 3) goto free_sysex_data;
1563 if (addr[0] == 0x40 && addr[1] == 0x00) { // System Parameters
1564 dmsg(3,("\tSystem Parameter\n"));
1565 }
1566 else if (addr[0] == 0x40 && addr[1] == 0x01) { // Common Parameters
1567 dmsg(3,("\tCommon Parameter\n"));
1568 }
1569 else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x10) { // Part Parameters (1)
1570 dmsg(3,("\tPart Parameter\n"));
1571 switch (addr[2]) {
1572 case 0x40: { // scale tuning
1573 dmsg(3,("\t\tScale Tuning\n"));
1574 uint8_t scale_tunes[12]; // detuning of all 12 semitones of an octave
1575 if (reader.read(&scale_tunes[0], 12) != 12) goto free_sysex_data;
1576 uint8_t checksum;
1577 if (!reader.pop(&checksum)) goto free_sysex_data;
1578 #if CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1579 if (GSCheckSum(checksum_reader, 12)) goto free_sysex_data;
1580 #endif // CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1581 for (int i = 0; i < 12; i++) scale_tunes[i] -= 64;
1582 AdjustScale((int8_t*) scale_tunes);
1583 dmsg(3,("\t\t\tNew scale applied.\n"));
1584 break;
1585 }
1586 }
1587 }
1588 else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x20) { // Part Parameters (2)
1589 }
1590 else if (addr[0] == 0x41) { // Drum Setup Parameters
1591 }
1592 break;
1593 }
1594 }
1595
1596 free_sysex_data: // finally free sysex data
1597 pSysexBuffer->increment_read_ptr(itSysexEvent->Param.Sysex.Size);
1598 }
1599
1600 /**
1601 * Calculates the Roland GS sysex check sum.
1602 *
1603 * @param AddrReader - reader which currently points to the first GS
1604 * command address byte of the GS sysex message in
1605 * question
1606 * @param DataSize - size of the GS message data (in bytes)
1607 */
1608 uint8_t Engine::GSCheckSum(const RingBuffer<uint8_t,false>::NonVolatileReader AddrReader, uint DataSize) {
1609 RingBuffer<uint8_t,false>::NonVolatileReader reader = AddrReader;
1610 uint bytes = 3 /*addr*/ + DataSize;
1611 uint8_t addr_and_data[bytes];
1612 reader.read(&addr_and_data[0], bytes);
1613 uint8_t sum = 0;
1614 for (uint i = 0; i < bytes; i++) sum += addr_and_data[i];
1615 return 128 - sum % 128;
1616 }
1617
1618 /**
1619 * Allows to tune each of the twelve semitones of an octave.
1620 *
1621 * @param ScaleTunes - detuning of all twelve semitones (in cents)
1622 */
1623 void Engine::AdjustScale(int8_t ScaleTunes[12]) {
1624 memcpy(&this->ScaleTuning[0], &ScaleTunes[0], 12); //TODO: currently not sample accurate
1625 }
1626
1627 /**
1628 * Releases all voices on an engine channel. All voices will go into
1629 * the release stage and thus it might take some time (e.g. dependant to
1630 * their envelope release time) until they actually die.
1631 *
1632 * @param pEngineChannel - engine channel on which all voices should be released
1633 * @param itReleaseEvent - event which caused this releasing of all voices
1634 */
1635 void Engine::ReleaseAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itReleaseEvent) {
1636 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1637 while (iuiKey) {
1638 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1639 ++iuiKey;
1640 // append a 'release' event to the key's own event list
1641 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1642 if (itNewEvent) {
1643 *itNewEvent = *itReleaseEvent; // copy original event (to the key's event list)
1644 itNewEvent->Type = Event::type_release; // transform event type
1645 }
1646 else dmsg(1,("Event pool emtpy!\n"));
1647 }
1648 }
1649
1650 /**
1651 * Kills all voices on an engine channel as soon as possible. Voices
1652 * won't get into release state, their volume level will be ramped down
1653 * as fast as possible.
1654 *
1655 * @param pEngineChannel - engine channel on which all voices should be killed
1656 * @param itKillEvent - event which caused this killing of all voices
1657 */
1658 void Engine::KillAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itKillEvent) {
1659 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1660 RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
1661 while (iuiKey != end) { // iterate through all active keys
1662 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1663 ++iuiKey;
1664 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
1665 RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
1666 for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
1667 itVoice->Kill(itKillEvent);
1668 --VoiceSpawnsLeft; //FIXME: just a temporary workaround, we should check the cause in StealVoice() instead
1669 }
1670 }
1671 }
1672
1673 /**
1674 * Determines whether the specified voice should be released.
1675 *
1676 * @param pEngineChannel - The engine channel on which the voice should be checked
1677 * @param Key - The key number
1678 * @returns true if the specified should be released, false otherwise.
1679 */
1680 bool Engine::ShouldReleaseVoice(EngineChannel* pEngineChannel, int Key) {
1681 if (pEngineChannel->SustainPedal) return false;
1682
1683 if (pEngineChannel->SostenutoPedal) {
1684 for (int i = 0; i < SostenutoKeyCount; i++)
1685 if (Key == SostenutoKeys[i]) return false;
1686 }
1687
1688 return true;
1689 }
1690
1691 uint Engine::VoiceCount() {
1692 return ActiveVoiceCount;
1693 }
1694
1695 uint Engine::VoiceCountMax() {
1696 return ActiveVoiceCountMax;
1697 }
1698
1699 bool Engine::DiskStreamSupported() {
1700 return true;
1701 }
1702
1703 uint Engine::DiskStreamCount() {
1704 return (pDiskThread) ? pDiskThread->ActiveStreamCount : 0;
1705 }
1706
1707 uint Engine::DiskStreamCountMax() {
1708 return (pDiskThread) ? pDiskThread->ActiveStreamCountMax : 0;
1709 }
1710
1711 String Engine::DiskStreamBufferFillBytes() {
1712 return pDiskThread->GetBufferFillBytes();
1713 }
1714
1715 String Engine::DiskStreamBufferFillPercentage() {
1716 return pDiskThread->GetBufferFillPercentage();
1717 }
1718
1719 String Engine::EngineName() {
1720 return LS_GIG_ENGINE_NAME;
1721 }
1722
1723 String Engine::Description() {
1724 return "Gigasampler Engine";
1725 }
1726
1727 String Engine::Version() {
1728 String s = "$Revision: 1.77 $";
1729 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
1730 }
1731
1732 InstrumentManager* Engine::GetInstrumentManager() {
1733 return &instruments;
1734 }
1735
1736 // static constant initializers
1737 const float* Engine::VolumeCurve(InitVolumeCurve());
1738 const float* Engine::PanCurve(InitPanCurve());
1739 const float* Engine::CrossfadeCurve(InitCrossfadeCurve());
1740
1741 float* Engine::InitVolumeCurve() {
1742 // line-segment approximation
1743 const float segments[] = {
1744 0, 0, 2, 0.0046, 16, 0.016, 31, 0.051, 45, 0.115, 54.5, 0.2,
1745 64.5, 0.39, 74, 0.74, 92, 1.03, 114, 1.94, 119.2, 2.2, 127, 2.2
1746 };
1747 return InitCurve(segments);
1748 }
1749
1750 float* Engine::InitPanCurve() {
1751 // line-segment approximation
1752 const float segments[] = {
1753 0, 0, 1, 0,
1754 2, 0.05, 31.5, 0.7, 51, 0.851, 74.5, 1.12,
1755 127, 1.41, 128, 1.41
1756 };
1757 return InitCurve(segments, 129);
1758 }
1759
1760 float* Engine::InitCrossfadeCurve() {
1761 // line-segment approximation
1762 const float segments[] = {
1763 0, 0, 1, 0.03, 10, 0.1, 51, 0.58, 127, 1
1764 };
1765 return InitCurve(segments);
1766 }
1767
1768 float* Engine::InitCurve(const float* segments, int size) {
1769 float* y = new float[size];
1770 for (int x = 0 ; x < size ; x++) {
1771 if (x > segments[2]) segments += 2;
1772 y[x] = segments[1] + (x - segments[0]) *
1773 (segments[3] - segments[1]) / (segments[2] - segments[0]);
1774 }
1775 return y;
1776 }
1777
1778 /**
1779 * Changes the instrument for an engine channel.
1780 *
1781 * @param pEngineChannel - engine channel on which the instrument
1782 * should be changed
1783 * @param pInstrument - new instrument
1784 * @returns a list of dimension regions from the old instrument
1785 * that are still in use
1786 */
1787 ::gig::DimensionRegion** Engine::ChangeInstrument(EngineChannel* pEngineChannel, ::gig::Instrument* pInstrument) {
1788 instrument_change_command_t command;
1789 command.pEngineChannel = pEngineChannel;
1790 command.pInstrument = pInstrument;
1791 InstrumentChangeQueue->push(&command);
1792
1793 // wait for the audio thread to confirm that the instrument
1794 // change has been done
1795 instrument_change_reply_t reply;
1796 while (InstrumentChangeReplyQueue->pop(&reply) == 0) {
1797 usleep(10000);
1798 }
1799 return pDimRegionsInUse;
1800 }
1801
1802 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC