/[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 1041 - (show annotations) (download)
Wed Feb 7 17:45:19 2007 UTC (17 years, 1 month ago) by schoenebeck
File size: 86726 byte(s)
* handle MIDI coarse tuning messages (MIDI RPN #0 MSB, #2 LSB),
  currently lazy implementation, transpose value is simply added on the
  note on/off values instead only at the mandatory places, thus when
  altering transpose while playing, voices can unintendedly survive

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

  ViewVC Help
Powered by ViewVC