/[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 705 - (show annotations) (download)
Wed Jul 20 21:43:23 2005 UTC (14 years, 11 months ago) by schoenebeck
File size: 68582 byte(s)
* support for muting sampler channels and solo mode of the same, two new
  LSCP commands ("SET CHANNEL MUTE" and "SET CHANNEL SOLO") and two new
  fields ("MUTE" and "SOLO") for command "GET CHANNEL INFO" were
  introduced for this (patch by Grigor Iliev, a bit adjusted)

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 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 #if defined(__APPLE__)
33 # include <stdlib.h>
34 #else
35 # include <malloc.h>
36 #endif
37
38 namespace LinuxSampler { namespace gig {
39
40 InstrumentResourceManager Engine::instruments;
41
42 std::map<AudioOutputDevice*,Engine*> Engine::engines;
43
44 /**
45 * Get a gig::Engine object for the given gig::EngineChannel and the
46 * given AudioOutputDevice. All engine channels which are connected to
47 * the same audio output device will use the same engine instance. This
48 * method will be called by a gig::EngineChannel whenever it's
49 * connecting to a audio output device.
50 *
51 * @param pChannel - engine channel which acquires an engine object
52 * @param pDevice - the audio output device \a pChannel is connected to
53 */
54 Engine* Engine::AcquireEngine(LinuxSampler::gig::EngineChannel* pChannel, AudioOutputDevice* pDevice) {
55 Engine* pEngine = NULL;
56 // check if there's already an engine for the given audio output device
57 if (engines.count(pDevice)) {
58 dmsg(4,("Using existing gig::Engine.\n"));
59 pEngine = engines[pDevice];
60 } else { // create a new engine (and disk thread) instance for the given audio output device
61 dmsg(4,("Creating new gig::Engine.\n"));
62 pEngine = (Engine*) EngineFactory::Create("gig");
63 pEngine->Connect(pDevice);
64 engines[pDevice] = pEngine;
65 }
66 // register engine channel to the engine instance
67 pEngine->engineChannels.add(pChannel);
68 // remember index in the ArrayList
69 pChannel->iEngineIndexSelf = pEngine->engineChannels.size() - 1;
70 dmsg(4,("This gig::Engine has now %d EngineChannels.\n",pEngine->engineChannels.size()));
71 return pEngine;
72 }
73
74 /**
75 * Once an engine channel is disconnected from an audio output device,
76 * it wil immediately call this method to unregister itself from the
77 * engine instance and if that engine instance is not used by any other
78 * engine channel anymore, then that engine instance will be destroyed.
79 *
80 * @param pChannel - engine channel which wants to disconnect from it's
81 * engine instance
82 * @param pDevice - audio output device \a pChannel was connected to
83 */
84 void Engine::FreeEngine(LinuxSampler::gig::EngineChannel* pChannel, AudioOutputDevice* pDevice) {
85 dmsg(4,("Disconnecting EngineChannel from gig::Engine.\n"));
86 Engine* pEngine = engines[pDevice];
87 // unregister EngineChannel from the Engine instance
88 pEngine->engineChannels.remove(pChannel);
89 // if the used Engine instance is not used anymore, then destroy it
90 if (pEngine->engineChannels.empty()) {
91 pDevice->Disconnect(pEngine);
92 engines.erase(pDevice);
93 delete pEngine;
94 dmsg(4,("Destroying gig::Engine.\n"));
95 }
96 else dmsg(4,("This gig::Engine has now %d EngineChannels.\n",pEngine->engineChannels.size()));
97 }
98
99 /**
100 * Constructor
101 */
102 Engine::Engine() {
103 pAudioOutputDevice = NULL;
104 pDiskThread = NULL;
105 pEventGenerator = NULL;
106 pSysexBuffer = new RingBuffer<uint8_t>(CONFIG_SYSEX_BUFFER_SIZE, 0);
107 pEventQueue = new RingBuffer<Event>(CONFIG_MAX_EVENTS_PER_FRAGMENT, 0);
108 pEventPool = new Pool<Event>(CONFIG_MAX_EVENTS_PER_FRAGMENT);
109 pVoicePool = new Pool<Voice>(CONFIG_MAX_VOICES);
110 pVoiceStealingQueue = new RTList<Event>(pEventPool);
111 pGlobalEvents = new RTList<Event>(pEventPool);
112 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
113 iterVoice->SetEngine(this);
114 }
115 pVoicePool->clear();
116
117 pSynthesisParameters[0] = NULL; // we allocate when an audio device is connected
118 pBasicFilterParameters = NULL;
119 pMainFilterParameters = NULL;
120
121 ResetInternal();
122 ResetScaleTuning();
123 }
124
125 /**
126 * Destructor
127 */
128 Engine::~Engine() {
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 (pMainFilterParameters) delete[] pMainFilterParameters;
143 if (pBasicFilterParameters) delete[] pBasicFilterParameters;
144 if (pSynthesisParameters[0]) free(pSynthesisParameters[0]);
145 if (pVoiceStealingQueue) delete pVoiceStealingQueue;
146 if (pSysexBuffer) delete pSysexBuffer;
147 EngineFactory::Destroy(this);
148 }
149
150 void Engine::Enable() {
151 dmsg(3,("gig::Engine: enabling\n"));
152 EngineDisabled.PushAndUnlock(false, 2); // set condition object 'EngineDisabled' to false (wait max. 2s)
153 dmsg(3,("gig::Engine: enabled (val=%d)\n", EngineDisabled.GetUnsafe()));
154 }
155
156 void Engine::Disable() {
157 dmsg(3,("gig::Engine: disabling\n"));
158 bool* pWasDisabled = EngineDisabled.PushAndUnlock(true, 2); // wait max. 2s
159 if (!pWasDisabled) dmsg(3,("gig::Engine warning: Timeout waiting to disable engine.\n"));
160 }
161
162 void Engine::DisableAndLock() {
163 dmsg(3,("gig::Engine: disabling\n"));
164 bool* pWasDisabled = EngineDisabled.Push(true, 2); // wait max. 2s
165 if (!pWasDisabled) dmsg(3,("gig::Engine warning: Timeout waiting to disable engine.\n"));
166 }
167
168 /**
169 * Reset all voices and disk thread and clear input event queue and all
170 * control and status variables.
171 */
172 void Engine::Reset() {
173 DisableAndLock();
174 ResetInternal();
175 ResetScaleTuning();
176 Enable();
177 }
178
179 /**
180 * Reset all voices and disk thread and clear input event queue and all
181 * control and status variables. This method is not thread safe!
182 */
183 void Engine::ResetInternal() {
184 ActiveVoiceCount = 0;
185 ActiveVoiceCountMax = 0;
186
187 // reset voice stealing parameters
188 pVoiceStealingQueue->clear();
189 itLastStolenVoice = RTList<Voice>::Iterator();
190 itLastStolenVoiceGlobally = RTList<Voice>::Iterator();
191 iuiLastStolenKey = RTList<uint>::Iterator();
192 iuiLastStolenKeyGlobally = RTList<uint>::Iterator();
193 pLastStolenChannel = NULL;
194
195 // reset all voices
196 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
197 iterVoice->Reset();
198 }
199 pVoicePool->clear();
200
201 // reset disk thread
202 if (pDiskThread) pDiskThread->Reset();
203
204 // delete all input events
205 pEventQueue->init();
206 }
207
208 /**
209 * Reset to normal, chromatic scale (means equal tempered).
210 */
211 void Engine::ResetScaleTuning() {
212 memset(&ScaleTuning[0], 0x00, 12);
213 }
214
215 /**
216 * Connect this engine instance with the given audio output device.
217 * This method will be called when an Engine instance is created.
218 * All of the engine's data structures which are dependant to the used
219 * audio output device / driver will be (re)allocated and / or
220 * adjusted appropriately.
221 *
222 * @param pAudioOut - audio output device to connect to
223 */
224 void Engine::Connect(AudioOutputDevice* pAudioOut) {
225 pAudioOutputDevice = pAudioOut;
226
227 ResetInternal();
228
229 // inform audio driver for the need of two channels
230 try {
231 pAudioOutputDevice->AcquireChannels(2); // gig engine only stereo
232 }
233 catch (AudioOutputException e) {
234 String msg = "Audio output device unable to provide 2 audio channels, cause: " + e.Message();
235 throw LinuxSamplerException(msg);
236 }
237
238 this->MaxSamplesPerCycle = pAudioOutputDevice->MaxSamplesPerCycle();
239 this->SampleRate = pAudioOutputDevice->SampleRate();
240
241 // FIXME: audio drivers with varying fragment sizes might be a problem here
242 MaxFadeOutPos = MaxSamplesPerCycle - int(double(SampleRate) * CONFIG_EG_MIN_RELEASE_TIME) - 1;
243 if (MaxFadeOutPos < 0) {
244 std::cerr << "gig::Engine: WARNING, CONFIG_EG_MIN_RELEASE_TIME "
245 << "too big for current audio fragment size & sampling rate! "
246 << "May lead to click sounds if voice stealing chimes in!\n" << std::flush;
247 // force volume ramp downs at the beginning of each fragment
248 MaxFadeOutPos = 0;
249 // lower minimum release time
250 const float minReleaseTime = (float) MaxSamplesPerCycle / (float) SampleRate;
251 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
252 iterVoice->pEG1->CalculateFadeOutCoeff(minReleaseTime, SampleRate);
253 }
254 pVoicePool->clear();
255 }
256
257 // (re)create disk thread
258 if (this->pDiskThread) {
259 dmsg(1,("Stopping disk thread..."));
260 this->pDiskThread->StopThread();
261 delete this->pDiskThread;
262 dmsg(1,("OK\n"));
263 }
264 this->pDiskThread = new DiskThread(((pAudioOut->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6); //FIXME: assuming stereo
265 if (!pDiskThread) {
266 dmsg(0,("gig::Engine new diskthread = NULL\n"));
267 exit(EXIT_FAILURE);
268 }
269
270 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
271 iterVoice->pDiskThread = this->pDiskThread;
272 dmsg(3,("d"));
273 }
274 pVoicePool->clear();
275
276 // (re)create event generator
277 if (pEventGenerator) delete pEventGenerator;
278 pEventGenerator = new EventGenerator(pAudioOut->SampleRate());
279
280 // (re)allocate synthesis parameter matrix
281 if (pSynthesisParameters[0]) free(pSynthesisParameters[0]);
282
283 #if defined(__APPLE__)
284 pSynthesisParameters[0] = (float *) malloc(Event::destination_count * sizeof(float) * pAudioOut->MaxSamplesPerCycle());
285 #else
286 pSynthesisParameters[0] = (float *) memalign(16,(Event::destination_count * sizeof(float) * pAudioOut->MaxSamplesPerCycle()));
287 #endif
288 for (int dst = 1; dst < Event::destination_count; dst++)
289 pSynthesisParameters[dst] = pSynthesisParameters[dst - 1] + pAudioOut->MaxSamplesPerCycle();
290
291 // (re)allocate biquad filter parameter sequence
292 if (pBasicFilterParameters) delete[] pBasicFilterParameters;
293 if (pMainFilterParameters) delete[] pMainFilterParameters;
294 pBasicFilterParameters = new biquad_param_t[pAudioOut->MaxSamplesPerCycle()];
295 pMainFilterParameters = new biquad_param_t[pAudioOut->MaxSamplesPerCycle()];
296
297 dmsg(1,("Starting disk thread..."));
298 pDiskThread->StartThread();
299 dmsg(1,("OK\n"));
300
301 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
302 if (!iterVoice->pDiskThread) {
303 dmsg(0,("Engine -> voice::trigger: !pDiskThread\n"));
304 exit(EXIT_FAILURE);
305 }
306 }
307 }
308
309 /**
310 * Clear all engine global event lists.
311 */
312 void Engine::ClearEventLists() {
313 pGlobalEvents->clear();
314 }
315
316 /**
317 * Copy all events from the engine's global input queue buffer to the
318 * engine's internal event list. This will be done at the beginning of
319 * each audio cycle (that is each RenderAudio() call) to distinguish
320 * all global events which have to be processed in the current audio
321 * cycle. These events are usually just SysEx messages. Every
322 * EngineChannel has it's own input event queue buffer and event list
323 * to handle common events like NoteOn, NoteOff and ControlChange
324 * events.
325 *
326 * @param Samples - number of sample points to be processed in the
327 * current audio cycle
328 */
329 void Engine::ImportEvents(uint Samples) {
330 RingBuffer<Event>::NonVolatileReader eventQueueReader = pEventQueue->get_non_volatile_reader();
331 Event* pEvent;
332 while (true) {
333 // get next event from input event queue
334 if (!(pEvent = eventQueueReader.pop())) break;
335 // if younger event reached, ignore that and all subsequent ones for now
336 if (pEvent->FragmentPos() >= Samples) {
337 eventQueueReader--;
338 dmsg(2,("Younger Event, pos=%d ,Samples=%d!\n",pEvent->FragmentPos(),Samples));
339 pEvent->ResetFragmentPos();
340 break;
341 }
342 // copy event to internal event list
343 if (pGlobalEvents->poolIsEmpty()) {
344 dmsg(1,("Event pool emtpy!\n"));
345 break;
346 }
347 *pGlobalEvents->allocAppend() = *pEvent;
348 }
349 eventQueueReader.free(); // free all copied events from input queue
350 }
351
352 /**
353 * Let this engine proceed to render the given amount of sample points. The
354 * calculated audio data of all voices of this engine will be placed into
355 * the engine's audio sum buffer which has to be copied and eventually be
356 * converted to the appropriate value range by the audio output class (e.g.
357 * AlsaIO or JackIO) right after.
358 *
359 * @param Samples - number of sample points to be rendered
360 * @returns 0 on success
361 */
362 int Engine::RenderAudio(uint Samples) {
363 dmsg(5,("RenderAudio(Samples=%d)\n", Samples));
364
365 // return if engine disabled
366 if (EngineDisabled.Pop()) {
367 dmsg(5,("gig::Engine: engine disabled (val=%d)\n",EngineDisabled.GetUnsafe()));
368 return 0;
369 }
370
371 // update time of start and end of this audio fragment (as events' time stamps relate to this)
372 pEventGenerator->UpdateFragmentTime(Samples);
373
374 // We only allow a maximum of CONFIG_MAX_VOICES voices to be spawned
375 // in each audio fragment. All subsequent request for spawning new
376 // voices in the same audio fragment will be ignored.
377 VoiceSpawnsLeft = CONFIG_MAX_VOICES;
378
379 // get all events from the engine's global input event queue which belong to the current fragment
380 // (these are usually just SysEx messages)
381 ImportEvents(Samples);
382
383 // process engine global events (these are currently only MIDI System Exclusive messages)
384 {
385 RTList<Event>::Iterator itEvent = pGlobalEvents->first();
386 RTList<Event>::Iterator end = pGlobalEvents->end();
387 for (; itEvent != end; ++itEvent) {
388 switch (itEvent->Type) {
389 case Event::type_sysex:
390 dmsg(5,("Engine: Sysex received\n"));
391 ProcessSysex(itEvent);
392 break;
393 }
394 }
395 }
396
397 // reset internal voice counter (just for statistic of active voices)
398 ActiveVoiceCountTemp = 0;
399
400 // handle events on all engine channels
401 for (int i = 0; i < engineChannels.size(); i++) {
402 if (!engineChannels[i]->pInstrument) continue; // ignore if no instrument loaded
403 ProcessEvents(engineChannels[i], Samples);
404 }
405
406 // render all 'normal', active voices on all engine channels
407 for (int i = 0; i < engineChannels.size(); i++) {
408 if (!engineChannels[i]->pInstrument) continue; // ignore if no instrument loaded
409 RenderActiveVoices(engineChannels[i], Samples);
410 }
411
412 // now that all ordinary voices on ALL engine channels are rendered, render new stolen voices
413 RenderStolenVoices(Samples);
414
415 // handle cleanup on all engine channels for the next audio fragment
416 for (int i = 0; i < engineChannels.size(); i++) {
417 if (!engineChannels[i]->pInstrument) continue; // ignore if no instrument loaded
418 PostProcess(engineChannels[i]);
419 }
420
421
422 // empty the engine's event list for the next audio fragment
423 ClearEventLists();
424
425 // reset voice stealing for the next audio fragment
426 pVoiceStealingQueue->clear();
427
428 // just some statistics about this engine instance
429 ActiveVoiceCount = ActiveVoiceCountTemp;
430 if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;
431
432 FrameTime += Samples;
433
434 return 0;
435 }
436
437 /**
438 * Dispatch and handle all events in this audio fragment for the given
439 * engine channel.
440 *
441 * @param pEngineChannel - engine channel on which events should be
442 * processed
443 * @param Samples - amount of sample points to be processed in
444 * this audio fragment cycle
445 */
446 void Engine::ProcessEvents(EngineChannel* pEngineChannel, uint Samples) {
447 // get all events from the engine channels's input event queue which belong to the current fragment
448 // (these are the common events like NoteOn, NoteOff, ControlChange, etc.)
449 pEngineChannel->ImportEvents(Samples);
450
451 // process events
452 {
453 RTList<Event>::Iterator itEvent = pEngineChannel->pEvents->first();
454 RTList<Event>::Iterator end = pEngineChannel->pEvents->end();
455 for (; itEvent != end; ++itEvent) {
456 switch (itEvent->Type) {
457 case Event::type_note_on:
458 dmsg(5,("Engine: Note on received\n"));
459 ProcessNoteOn((EngineChannel*)itEvent->pEngineChannel, itEvent);
460 break;
461 case Event::type_note_off:
462 dmsg(5,("Engine: Note off received\n"));
463 ProcessNoteOff((EngineChannel*)itEvent->pEngineChannel, itEvent);
464 break;
465 case Event::type_control_change:
466 dmsg(5,("Engine: MIDI CC received\n"));
467 ProcessControlChange((EngineChannel*)itEvent->pEngineChannel, itEvent);
468 break;
469 case Event::type_pitchbend:
470 dmsg(5,("Engine: Pitchbend received\n"));
471 ProcessPitchbend((EngineChannel*)itEvent->pEngineChannel, itEvent);
472 break;
473 }
474 }
475 }
476
477 // reset voice stealing for the next engine channel (or next audio fragment)
478 itLastStolenVoice = RTList<Voice>::Iterator();
479 itLastStolenVoiceGlobally = RTList<Voice>::Iterator();
480 iuiLastStolenKey = RTList<uint>::Iterator();
481 iuiLastStolenKeyGlobally = RTList<uint>::Iterator();
482 pLastStolenChannel = NULL;
483 }
484
485 /**
486 * Render all 'normal' voices (that is voices which were not stolen in
487 * this fragment) on the given engine channel.
488 *
489 * @param pEngineChannel - engine channel on which audio should be
490 * rendered
491 * @param Samples - amount of sample points to be rendered in
492 * this audio fragment cycle
493 */
494 void Engine::RenderActiveVoices(EngineChannel* pEngineChannel, uint Samples) {
495 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
496
497 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
498 RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
499 while (iuiKey != end) { // iterate through all active keys
500 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
501 ++iuiKey;
502
503 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
504 RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
505 for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
506 // now render current voice
507 itVoice->Render(Samples);
508 if (itVoice->IsActive()) ActiveVoiceCountTemp++; // still active
509 else { // voice reached end, is now inactive
510 FreeVoice(pEngineChannel, itVoice); // remove voice from the list of active voices
511 }
512 }
513 }
514 }
515
516 /**
517 * Render all stolen voices (only voices which were stolen in this
518 * fragment) on the given engine channel. Stolen voices are rendered
519 * after all normal voices have been rendered; this is needed to render
520 * audio of those voices which were selected for voice stealing until
521 * the point were the stealing (that is the take over of the voice)
522 * actually happened.
523 *
524 * @param pEngineChannel - engine channel on which audio should be
525 * rendered
526 * @param Samples - amount of sample points to be rendered in
527 * this audio fragment cycle
528 */
529 void Engine::RenderStolenVoices(uint Samples) {
530 RTList<Event>::Iterator itVoiceStealEvent = pVoiceStealingQueue->first();
531 RTList<Event>::Iterator end = pVoiceStealingQueue->end();
532 for (; itVoiceStealEvent != end; ++itVoiceStealEvent) {
533 EngineChannel* pEngineChannel = (EngineChannel*) itVoiceStealEvent->pEngineChannel;
534 Pool<Voice>::Iterator itNewVoice =
535 LaunchVoice(pEngineChannel, itVoiceStealEvent, itVoiceStealEvent->Param.Note.Layer, itVoiceStealEvent->Param.Note.ReleaseTrigger, false, false);
536 if (itNewVoice) {
537 itNewVoice->Render(Samples);
538 if (itNewVoice->IsActive()) ActiveVoiceCountTemp++; // still active
539 else { // voice reached end, is now inactive
540 FreeVoice(pEngineChannel, itNewVoice); // remove voice from the list of active voices
541 }
542 }
543 else dmsg(1,("gig::Engine: ERROR, voice stealing didn't work out!\n"));
544
545 // we need to clear the key's event list explicitly here in case key was never active
546 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoiceStealEvent->Param.Note.Key];
547 pKey->VoiceTheftsQueued--;
548 if (!pKey->Active && !pKey->VoiceTheftsQueued) pKey->pEvents->clear();
549 }
550 }
551
552 /**
553 * Free all keys which have turned inactive in this audio fragment, from
554 * the list of active keys and clear all event lists on that engine
555 * channel.
556 *
557 * @param pEngineChannel - engine channel to cleanup
558 */
559 void Engine::PostProcess(EngineChannel* pEngineChannel) {
560 // free all keys which have no active voices left
561 {
562 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
563 RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
564 while (iuiKey != end) { // iterate through all active keys
565 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
566 ++iuiKey;
567 if (pKey->pActiveVoices->isEmpty()) FreeKey(pEngineChannel, pKey);
568 #if CONFIG_DEVMODE
569 else { // just a sanity check for debugging
570 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
571 RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
572 for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
573 if (itVoice->itKillEvent) {
574 dmsg(1,("gig::Engine: ERROR, killed voice survived !!!\n"));
575 }
576 }
577 }
578 #endif // CONFIG_DEVMODE
579 }
580 }
581
582 // empty the engine channel's own event lists
583 pEngineChannel->ClearEventLists();
584 }
585
586 /**
587 * Will be called by the MIDI input device whenever a MIDI system
588 * exclusive message has arrived.
589 *
590 * @param pData - pointer to sysex data
591 * @param Size - lenght of sysex data (in bytes)
592 */
593 void Engine::SendSysex(void* pData, uint Size) {
594 Event event = pEventGenerator->CreateEvent();
595 event.Type = Event::type_sysex;
596 event.Param.Sysex.Size = Size;
597 event.pEngineChannel = NULL; // as Engine global event
598 if (pEventQueue->write_space() > 0) {
599 if (pSysexBuffer->write_space() >= Size) {
600 // copy sysex data to input buffer
601 uint toWrite = Size;
602 uint8_t* pPos = (uint8_t*) pData;
603 while (toWrite) {
604 const uint writeNow = RTMath::Min(toWrite, pSysexBuffer->write_space_to_end());
605 pSysexBuffer->write(pPos, writeNow);
606 toWrite -= writeNow;
607 pPos += writeNow;
608
609 }
610 // finally place sysex event into input event queue
611 pEventQueue->push(&event);
612 }
613 else dmsg(1,("Engine: Sysex message too large (%d byte) for input buffer (%d byte)!",Size,CONFIG_SYSEX_BUFFER_SIZE));
614 }
615 else dmsg(1,("Engine: Input event queue full!"));
616 }
617
618 /**
619 * Assigns and triggers a new voice for the respective MIDI key.
620 *
621 * @param pEngineChannel - engine channel on which this event occured on
622 * @param itNoteOnEvent - key, velocity and time stamp of the event
623 */
624 void Engine::ProcessNoteOn(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
625 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
626
627 const int key = itNoteOnEvent->Param.Note.Key;
628
629 // Change key dimension value if key is in keyswitching area
630 {
631 const ::gig::Instrument* pInstrument = pEngineChannel->pInstrument;
632 if (key >= pInstrument->DimensionKeyRange.low && key <= pInstrument->DimensionKeyRange.high)
633 pEngineChannel->CurrentKeyDimension = ((key - pInstrument->DimensionKeyRange.low) * 128) /
634 (pInstrument->DimensionKeyRange.high - pInstrument->DimensionKeyRange.low + 1);
635 }
636
637 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key];
638
639 pKey->KeyPressed = true; // the MIDI key was now pressed down
640 pKey->Velocity = itNoteOnEvent->Param.Note.Velocity;
641 pKey->NoteOnTime = FrameTime + itNoteOnEvent->FragmentPos(); // will be used to calculate note length
642
643 // cancel release process of voices on this key if needed
644 if (pKey->Active && !pEngineChannel->SustainPedal) {
645 RTList<Event>::Iterator itCancelReleaseEvent = pKey->pEvents->allocAppend();
646 if (itCancelReleaseEvent) {
647 *itCancelReleaseEvent = *itNoteOnEvent; // copy event
648 itCancelReleaseEvent->Type = Event::type_cancel_release; // transform event type
649 }
650 else dmsg(1,("Event pool emtpy!\n"));
651 }
652
653 // move note on event to the key's own event list
654 RTList<Event>::Iterator itNoteOnEventOnKeyList = itNoteOnEvent.moveToEndOf(pKey->pEvents);
655
656 // allocate and trigger new voice(s) for the key
657 {
658 // first, get total amount of required voices (dependant on amount of layers)
659 ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOnEventOnKeyList->Param.Note.Key);
660 if (pRegion) {
661 int voicesRequired = pRegion->Layers;
662 // now launch the required amount of voices
663 for (int i = 0; i < voicesRequired; i++)
664 LaunchVoice(pEngineChannel, itNoteOnEventOnKeyList, i, false, true, true);
665 }
666 }
667
668 // if neither a voice was spawned or postponed then remove note on event from key again
669 if (!pKey->Active && !pKey->VoiceTheftsQueued)
670 pKey->pEvents->free(itNoteOnEventOnKeyList);
671
672 pKey->RoundRobinIndex++;
673 }
674
675 /**
676 * Releases the voices on the given key if sustain pedal is not pressed.
677 * If sustain is pressed, the release of the note will be postponed until
678 * sustain pedal will be released or voice turned inactive by itself (e.g.
679 * due to completion of sample playback).
680 *
681 * @param pEngineChannel - engine channel on which this event occured on
682 * @param itNoteOffEvent - key, velocity and time stamp of the event
683 */
684 void Engine::ProcessNoteOff(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOffEvent) {
685 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
686
687 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itNoteOffEvent->Param.Note.Key];
688 pKey->KeyPressed = false; // the MIDI key was now released
689
690 // release voices on this key if needed
691 if (pKey->Active && !pEngineChannel->SustainPedal) {
692 itNoteOffEvent->Type = Event::type_release; // transform event type
693
694 // move event to the key's own event list
695 RTList<Event>::Iterator itNoteOffEventOnKeyList = itNoteOffEvent.moveToEndOf(pKey->pEvents);
696
697 // spawn release triggered voice(s) if needed
698 if (pKey->ReleaseTrigger) {
699 // first, get total amount of required voices (dependant on amount of layers)
700 ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key);
701 if (pRegion) {
702 int voicesRequired = pRegion->Layers;
703
704 // MIDI note-on velocity is used instead of note-off velocity
705 itNoteOffEventOnKeyList->Param.Note.Velocity = pKey->Velocity;
706
707 // now launch the required amount of voices
708 for (int i = 0; i < voicesRequired; i++)
709 LaunchVoice(pEngineChannel, itNoteOffEventOnKeyList, i, true, false, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples
710 }
711 pKey->ReleaseTrigger = false;
712 }
713
714 // if neither a voice was spawned or postponed then remove note off event from key again
715 if (!pKey->Active && !pKey->VoiceTheftsQueued)
716 pKey->pEvents->free(itNoteOffEventOnKeyList);
717 }
718 }
719
720 /**
721 * Moves pitchbend event from the general (input) event list to the pitch
722 * event list.
723 *
724 * @param pEngineChannel - engine channel on which this event occured on
725 * @param itPitchbendEvent - absolute pitch value and time stamp of the event
726 */
727 void Engine::ProcessPitchbend(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itPitchbendEvent) {
728 pEngineChannel->Pitch = itPitchbendEvent->Param.Pitch.Pitch; // store current pitch value
729 itPitchbendEvent.moveToEndOf(pEngineChannel->pSynthesisEvents[Event::destination_vco]);
730 }
731
732 /**
733 * Allocates and triggers a new voice. This method will usually be
734 * called by the ProcessNoteOn() method and by the voices itself
735 * (e.g. to spawn further voices on the same key for layered sounds).
736 *
737 * @param pEngineChannel - engine channel on which this event occured on
738 * @param itNoteOnEvent - key, velocity and time stamp of the event
739 * @param iLayer - layer index for the new voice (optional - only
740 * in case of layered sounds of course)
741 * @param ReleaseTriggerVoice - if new voice is a release triggered voice
742 * (optional, default = false)
743 * @param VoiceStealing - if voice stealing should be performed
744 * when there is no free voice
745 * (optional, default = true)
746 * @param HandleKeyGroupConflicts - if voices should be killed due to a
747 * key group conflict
748 * @returns pointer to new voice or NULL if there was no free voice or
749 * if the voice wasn't triggered (for example when no region is
750 * defined for the given key).
751 */
752 Pool<Voice>::Iterator Engine::LaunchVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing, bool HandleKeyGroupConflicts) {
753 int MIDIKey = itNoteOnEvent->Param.Note.Key;
754 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[MIDIKey];
755 ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(MIDIKey);
756
757 // if nothing defined for this key
758 if (!pRegion) return Pool<Voice>::Iterator(); // nothing to do
759
760 // only mark the first voice of a layered voice (group) to be in a
761 // key group, so the layered voices won't kill each other
762 int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;
763
764 // handle key group (a.k.a. exclusive group) conflicts
765 if (HandleKeyGroupConflicts) {
766 if (iKeyGroup) { // if this voice / key belongs to a key group
767 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[iKeyGroup];
768 if (*ppKeyGroup) { // if there's already an active key in that key group
769 midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[**ppKeyGroup];
770 // kill all voices on the (other) key
771 RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
772 RTList<Voice>::Iterator end = pOtherKey->pActiveVoices->end();
773 for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
774 if (itVoiceToBeKilled->Type != Voice::type_release_trigger) {
775 itVoiceToBeKilled->Kill(itNoteOnEvent);
776 --VoiceSpawnsLeft; //FIXME: just a hack, we should better check in StealVoice() if the voice was killed due to key conflict
777 }
778 }
779 }
780 }
781 }
782
783 Voice::type_t VoiceType = Voice::type_normal;
784
785 // get current dimension values to select the right dimension region
786 //TODO: for stolen voices this dimension region selection block is processed twice, this should be changed
787 //FIXME: controller values for selecting the dimension region here are currently not sample accurate
788 uint DimValues[8] = { 0 };
789 for (int i = pRegion->Dimensions - 1; i >= 0; i--) {
790 switch (pRegion->pDimensionDefinitions[i].dimension) {
791 case ::gig::dimension_samplechannel:
792 DimValues[i] = 0; //TODO: we currently ignore this dimension
793 break;
794 case ::gig::dimension_layer:
795 DimValues[i] = iLayer;
796 break;
797 case ::gig::dimension_velocity:
798 DimValues[i] = itNoteOnEvent->Param.Note.Velocity;
799 break;
800 case ::gig::dimension_channelaftertouch:
801 DimValues[i] = 0; //TODO: we currently ignore this dimension
802 break;
803 case ::gig::dimension_releasetrigger:
804 VoiceType = (ReleaseTriggerVoice) ? Voice::type_release_trigger : (!iLayer) ? Voice::type_release_trigger_required : Voice::type_normal;
805 DimValues[i] = (uint) ReleaseTriggerVoice;
806 break;
807 case ::gig::dimension_keyboard:
808 DimValues[i] = (uint) pEngineChannel->CurrentKeyDimension;
809 break;
810 case ::gig::dimension_roundrobin:
811 DimValues[i] = (uint) pEngineChannel->pMIDIKeyInfo[MIDIKey].RoundRobinIndex; // incremented for each note on
812 break;
813 case ::gig::dimension_random:
814 RandomSeed = RandomSeed * 1103515245 + 12345; // classic pseudo random number generator
815 DimValues[i] = (uint) RandomSeed >> (32 - pRegion->pDimensionDefinitions[i].bits); // highest bits are most random
816 break;
817 case ::gig::dimension_modwheel:
818 DimValues[i] = pEngineChannel->ControllerTable[1];
819 break;
820 case ::gig::dimension_breath:
821 DimValues[i] = pEngineChannel->ControllerTable[2];
822 break;
823 case ::gig::dimension_foot:
824 DimValues[i] = pEngineChannel->ControllerTable[4];
825 break;
826 case ::gig::dimension_portamentotime:
827 DimValues[i] = pEngineChannel->ControllerTable[5];
828 break;
829 case ::gig::dimension_effect1:
830 DimValues[i] = pEngineChannel->ControllerTable[12];
831 break;
832 case ::gig::dimension_effect2:
833 DimValues[i] = pEngineChannel->ControllerTable[13];
834 break;
835 case ::gig::dimension_genpurpose1:
836 DimValues[i] = pEngineChannel->ControllerTable[16];
837 break;
838 case ::gig::dimension_genpurpose2:
839 DimValues[i] = pEngineChannel->ControllerTable[17];
840 break;
841 case ::gig::dimension_genpurpose3:
842 DimValues[i] = pEngineChannel->ControllerTable[18];
843 break;
844 case ::gig::dimension_genpurpose4:
845 DimValues[i] = pEngineChannel->ControllerTable[19];
846 break;
847 case ::gig::dimension_sustainpedal:
848 DimValues[i] = pEngineChannel->ControllerTable[64];
849 break;
850 case ::gig::dimension_portamento:
851 DimValues[i] = pEngineChannel->ControllerTable[65];
852 break;
853 case ::gig::dimension_sostenutopedal:
854 DimValues[i] = pEngineChannel->ControllerTable[66];
855 break;
856 case ::gig::dimension_softpedal:
857 DimValues[i] = pEngineChannel->ControllerTable[67];
858 break;
859 case ::gig::dimension_genpurpose5:
860 DimValues[i] = pEngineChannel->ControllerTable[80];
861 break;
862 case ::gig::dimension_genpurpose6:
863 DimValues[i] = pEngineChannel->ControllerTable[81];
864 break;
865 case ::gig::dimension_genpurpose7:
866 DimValues[i] = pEngineChannel->ControllerTable[82];
867 break;
868 case ::gig::dimension_genpurpose8:
869 DimValues[i] = pEngineChannel->ControllerTable[83];
870 break;
871 case ::gig::dimension_effect1depth:
872 DimValues[i] = pEngineChannel->ControllerTable[91];
873 break;
874 case ::gig::dimension_effect2depth:
875 DimValues[i] = pEngineChannel->ControllerTable[92];
876 break;
877 case ::gig::dimension_effect3depth:
878 DimValues[i] = pEngineChannel->ControllerTable[93];
879 break;
880 case ::gig::dimension_effect4depth:
881 DimValues[i] = pEngineChannel->ControllerTable[94];
882 break;
883 case ::gig::dimension_effect5depth:
884 DimValues[i] = pEngineChannel->ControllerTable[95];
885 break;
886 case ::gig::dimension_none:
887 std::cerr << "gig::Engine::LaunchVoice() Error: dimension=none\n" << std::flush;
888 break;
889 default:
890 std::cerr << "gig::Engine::LaunchVoice() Error: Unknown dimension\n" << std::flush;
891 }
892 }
893 ::gig::DimensionRegion* pDimRgn = pRegion->GetDimensionRegionByValue(DimValues);
894
895 // no need to continue if sample is silent
896 if (!pDimRgn->pSample || !pDimRgn->pSample->SamplesTotal) return Pool<Voice>::Iterator();
897
898 // allocate a new voice for the key
899 Pool<Voice>::Iterator itNewVoice = pKey->pActiveVoices->allocAppend();
900 if (itNewVoice) {
901 // launch the new voice
902 if (itNewVoice->Trigger(pEngineChannel, itNoteOnEvent, pEngineChannel->Pitch, pDimRgn, VoiceType, iKeyGroup) < 0) {
903 dmsg(4,("Voice not triggered\n"));
904 pKey->pActiveVoices->free(itNewVoice);
905 }
906 else { // on success
907 --VoiceSpawnsLeft;
908 if (!pKey->Active) { // mark as active key
909 pKey->Active = true;
910 pKey->itSelf = pEngineChannel->pActiveKeys->allocAppend();
911 *pKey->itSelf = itNoteOnEvent->Param.Note.Key;
912 }
913 if (itNewVoice->KeyGroup) {
914 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[itNewVoice->KeyGroup];
915 *ppKeyGroup = &*pKey->itSelf; // put key as the (new) active key to its key group
916 }
917 if (itNewVoice->Type == Voice::type_release_trigger_required) pKey->ReleaseTrigger = true; // mark key for the need of release triggered voice(s)
918 return itNewVoice; // success
919 }
920 }
921 else if (VoiceStealing) {
922 // try to steal one voice
923 int result = StealVoice(pEngineChannel, itNoteOnEvent);
924 if (!result) { // voice stolen successfully
925 // put note-on event into voice-stealing queue, so it will be reprocessed after killed voice died
926 RTList<Event>::Iterator itStealEvent = pVoiceStealingQueue->allocAppend();
927 if (itStealEvent) {
928 *itStealEvent = *itNoteOnEvent; // copy event
929 itStealEvent->Param.Note.Layer = iLayer;
930 itStealEvent->Param.Note.ReleaseTrigger = ReleaseTriggerVoice;
931 pKey->VoiceTheftsQueued++;
932 }
933 else dmsg(1,("Voice stealing queue full!\n"));
934 }
935 }
936
937 return Pool<Voice>::Iterator(); // no free voice or error
938 }
939
940 /**
941 * Will be called by LaunchVoice() method in case there are no free
942 * voices left. This method will select and kill one old voice for
943 * voice stealing and postpone the note-on event until the selected
944 * voice actually died.
945 *
946 * @param pEngineChannel - engine channel on which this event occured on
947 * @param itNoteOnEvent - key, velocity and time stamp of the event
948 * @returns 0 on success, a value < 0 if no active voice could be picked for voice stealing
949 */
950 int Engine::StealVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
951 if (VoiceSpawnsLeft <= 0) {
952 dmsg(1,("Max. voice thefts per audio fragment reached (you may raise CONFIG_MAX_VOICES).\n"));
953 return -1;
954 }
955 if (!pEventPool->poolIsEmpty()) {
956
957 RTList<Voice>::Iterator itSelectedVoice;
958
959 // Select one voice for voice stealing
960 switch (CONFIG_VOICE_STEAL_ALGO) {
961
962 // try to pick the oldest voice on the key where the new
963 // voice should be spawned, if there is no voice on that
964 // key, or no voice left to kill, then procceed with
965 // 'oldestkey' algorithm
966 case voice_steal_algo_oldestvoiceonkey: {
967 midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key];
968 itSelectedVoice = pSelectedKey->pActiveVoices->first();
969 // proceed iterating if voice was created in this fragment cycle
970 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
971 // if we haven't found a voice then proceed with algorithm 'oldestkey'
972 if (itSelectedVoice && itSelectedVoice->IsStealable()) break;
973 } // no break - intentional !
974
975 // try to pick the oldest voice on the oldest active key
976 // from the same engine channel
977 // (caution: must stay after 'oldestvoiceonkey' algorithm !)
978 case voice_steal_algo_oldestkey: {
979 // if we already stole in this fragment, try to proceed on same key
980 if (this->itLastStolenVoice) {
981 itSelectedVoice = this->itLastStolenVoice;
982 do {
983 ++itSelectedVoice;
984 } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
985 // found a "stealable" voice ?
986 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
987 // remember which voice we stole, so we can simply proceed on next voice stealing
988 this->itLastStolenVoice = itSelectedVoice;
989 break; // selection succeeded
990 }
991 }
992 // get (next) oldest key
993 RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKey) ? ++this->iuiLastStolenKey : pEngineChannel->pActiveKeys->first();
994 while (iuiSelectedKey) {
995 midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[*iuiSelectedKey];
996 itSelectedVoice = pSelectedKey->pActiveVoices->first();
997 // proceed iterating if voice was created in this fragment cycle
998 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
999 // found a "stealable" voice ?
1000 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1001 // remember which voice on which key we stole, so we can simply proceed on next voice stealing
1002 this->iuiLastStolenKey = iuiSelectedKey;
1003 this->itLastStolenVoice = itSelectedVoice;
1004 break; // selection succeeded
1005 }
1006 ++iuiSelectedKey; // get next oldest key
1007 }
1008 break;
1009 }
1010
1011 // don't steal anything
1012 case voice_steal_algo_none:
1013 default: {
1014 dmsg(1,("No free voice (voice stealing disabled)!\n"));
1015 return -1;
1016 }
1017 }
1018
1019 // if we couldn't steal a voice from the same engine channel then
1020 // steal oldest voice on the oldest key from any other engine channel
1021 // (the smaller engine channel number, the higher priority)
1022 if (!itSelectedVoice || !itSelectedVoice->IsStealable()) {
1023 EngineChannel* pSelectedChannel;
1024 int iChannelIndex;
1025 // select engine channel
1026 if (pLastStolenChannel) {
1027 pSelectedChannel = pLastStolenChannel;
1028 iChannelIndex = pSelectedChannel->iEngineIndexSelf;
1029 } else { // pick the engine channel followed by this engine channel
1030 iChannelIndex = (pEngineChannel->iEngineIndexSelf + 1) % engineChannels.size();
1031 pSelectedChannel = engineChannels[iChannelIndex];
1032 }
1033
1034 // if we already stole in this fragment, try to proceed on same key
1035 if (this->itLastStolenVoiceGlobally) {
1036 itSelectedVoice = this->itLastStolenVoiceGlobally;
1037 do {
1038 ++itSelectedVoice;
1039 } while (itSelectedVoice && !itSelectedVoice->IsStealable()); // proceed iterating if voice was created in this fragment cycle
1040 }
1041
1042 #if CONFIG_DEVMODE
1043 EngineChannel* pBegin = pSelectedChannel; // to detect endless loop
1044 #endif // CONFIG_DEVMODE
1045
1046 // did we find a 'stealable' voice?
1047 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1048 // remember which voice we stole, so we can simply proceed on next voice stealing
1049 this->itLastStolenVoiceGlobally = itSelectedVoice;
1050 } else while (true) { // iterate through engine channels
1051 // get (next) oldest key
1052 RTList<uint>::Iterator iuiSelectedKey = (this->iuiLastStolenKeyGlobally) ? ++this->iuiLastStolenKeyGlobally : pSelectedChannel->pActiveKeys->first();
1053 this->iuiLastStolenKeyGlobally = RTList<uint>::Iterator(); // to prevent endless loop (see line above)
1054 while (iuiSelectedKey) {
1055 midi_key_info_t* pSelectedKey = &pSelectedChannel->pMIDIKeyInfo[*iuiSelectedKey];
1056 itSelectedVoice = pSelectedKey->pActiveVoices->first();
1057 // proceed iterating if voice was created in this fragment cycle
1058 while (itSelectedVoice && !itSelectedVoice->IsStealable()) ++itSelectedVoice;
1059 // found a "stealable" voice ?
1060 if (itSelectedVoice && itSelectedVoice->IsStealable()) {
1061 // remember which voice on which key on which engine channel we stole, so we can simply proceed on next voice stealing
1062 this->iuiLastStolenKeyGlobally = iuiSelectedKey;
1063 this->itLastStolenVoiceGlobally = itSelectedVoice;
1064 this->pLastStolenChannel = pSelectedChannel;
1065 goto stealable_voice_found; // selection succeeded
1066 }
1067 ++iuiSelectedKey; // get next key on current engine channel
1068 }
1069 // get next engine channel
1070 iChannelIndex = (iChannelIndex + 1) % engineChannels.size();
1071 pSelectedChannel = engineChannels[iChannelIndex];
1072
1073 #if CONFIG_DEVMODE
1074 if (pSelectedChannel == pBegin) {
1075 dmsg(1,("FATAL ERROR: voice stealing endless loop!\n"));
1076 dmsg(1,("VoiceSpawnsLeft=%d.\n", VoiceSpawnsLeft));
1077 dmsg(1,("Exiting.\n"));
1078 exit(-1);
1079 }
1080 #endif // CONFIG_DEVMODE
1081 }
1082 }
1083
1084 // jump point if a 'stealable' voice was found
1085 stealable_voice_found:
1086
1087 #if CONFIG_DEVMODE
1088 if (!itSelectedVoice->IsActive()) {
1089 dmsg(1,("gig::Engine: ERROR, tried to steal a voice which was not active !!!\n"));
1090 return -1;
1091 }
1092 #endif // CONFIG_DEVMODE
1093
1094 // now kill the selected voice
1095 itSelectedVoice->Kill(itNoteOnEvent);
1096
1097 --VoiceSpawnsLeft;
1098
1099 return 0; // success
1100 }
1101 else {
1102 dmsg(1,("Event pool emtpy!\n"));
1103 return -1;
1104 }
1105 }
1106
1107 /**
1108 * Removes the given voice from the MIDI key's list of active voices.
1109 * This method will be called when a voice went inactive, e.g. because
1110 * it finished to playback its sample, finished its release stage or
1111 * just was killed.
1112 *
1113 * @param pEngineChannel - engine channel on which this event occured on
1114 * @param itVoice - points to the voice to be freed
1115 */
1116 void Engine::FreeVoice(EngineChannel* pEngineChannel, Pool<Voice>::Iterator& itVoice) {
1117 if (itVoice) {
1118 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoice->MIDIKey];
1119
1120 uint keygroup = itVoice->KeyGroup;
1121
1122 // free the voice object
1123 pVoicePool->free(itVoice);
1124
1125 // if no other voices left and member of a key group, remove from key group
1126 if (pKey->pActiveVoices->isEmpty() && keygroup) {
1127 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[keygroup];
1128 if (*ppKeyGroup == &*pKey->itSelf) *ppKeyGroup = NULL; // remove key from key group
1129 }
1130 }
1131 else std::cerr << "Couldn't release voice! (!itVoice)\n" << std::flush;
1132 }
1133
1134 /**
1135 * Called when there's no more voice left on a key, this call will
1136 * update the key info respectively.
1137 *
1138 * @param pEngineChannel - engine channel on which this event occured on
1139 * @param pKey - key which is now inactive
1140 */
1141 void Engine::FreeKey(EngineChannel* pEngineChannel, midi_key_info_t* pKey) {
1142 if (pKey->pActiveVoices->isEmpty()) {
1143 pKey->Active = false;
1144 pEngineChannel->pActiveKeys->free(pKey->itSelf); // remove key from list of active keys
1145 pKey->itSelf = RTList<uint>::Iterator();
1146 pKey->ReleaseTrigger = false;
1147 pKey->pEvents->clear();
1148 dmsg(3,("Key has no more voices now\n"));
1149 }
1150 else dmsg(1,("gig::Engine: Oops, tried to free a key which contains voices.\n"));
1151 }
1152
1153 /**
1154 * Reacts on supported control change commands (e.g. pitch bend wheel,
1155 * modulation wheel, aftertouch).
1156 *
1157 * @param pEngineChannel - engine channel on which this event occured on
1158 * @param itControlChangeEvent - controller, value and time stamp of the event
1159 */
1160 void Engine::ProcessControlChange(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itControlChangeEvent) {
1161 dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));
1162
1163 // update controller value in the engine channel's controller table
1164 pEngineChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;
1165
1166 // move event from the unsorted event list to the control change event list
1167 Pool<Event>::Iterator itControlChangeEventOnCCList = itControlChangeEvent.moveToEndOf(pEngineChannel->pCCEvents);
1168
1169 switch (itControlChangeEventOnCCList->Param.CC.Controller) {
1170 case 7: { // volume
1171 //TODO: not sample accurate yet
1172 pEngineChannel->GlobalVolume = (float) itControlChangeEventOnCCList->Param.CC.Value / 127.0f;
1173 pEngineChannel->bStatusChanged = true; // engine channel status has changed, so set notify flag
1174 break;
1175 }
1176 case 10: { // panpot
1177 //TODO: not sample accurate yet
1178 const int pan = (int) itControlChangeEventOnCCList->Param.CC.Value - 64;
1179 pEngineChannel->GlobalPanLeft = 1.0f - float(RTMath::Max(pan, 0)) / 63.0f;
1180 pEngineChannel->GlobalPanRight = 1.0f - float(RTMath::Min(pan, 0)) / -64.0f;
1181 break;
1182 }
1183 case 64: { // sustain
1184 if (itControlChangeEventOnCCList->Param.CC.Value >= 64 && !pEngineChannel->SustainPedal) {
1185 dmsg(4,("PEDAL DOWN\n"));
1186 pEngineChannel->SustainPedal = true;
1187
1188 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1189
1190 // cancel release process of voices if necessary
1191 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1192 for (; iuiKey; ++iuiKey) {
1193 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1194 if (!pKey->KeyPressed) {
1195 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1196 if (itNewEvent) {
1197 *itNewEvent = *itControlChangeEventOnCCList; // copy event to the key's own event list
1198 itNewEvent->Type = Event::type_cancel_release; // transform event type
1199 }
1200 else dmsg(1,("Event pool emtpy!\n"));
1201 }
1202 }
1203 }
1204 if (itControlChangeEventOnCCList->Param.CC.Value < 64 && pEngineChannel->SustainPedal) {
1205 dmsg(4,("PEDAL UP\n"));
1206 pEngineChannel->SustainPedal = false;
1207
1208 if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted
1209
1210 // release voices if their respective key is not pressed
1211 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1212 for (; iuiKey; ++iuiKey) {
1213 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1214 if (!pKey->KeyPressed) {
1215 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1216 if (itNewEvent) {
1217 *itNewEvent = *itControlChangeEventOnCCList; // copy event to the key's own event list
1218 itNewEvent->Type = Event::type_release; // transform event type
1219 }
1220 else dmsg(1,("Event pool emtpy!\n"));
1221 }
1222 }
1223 }
1224 break;
1225 }
1226
1227
1228 // Channel Mode Messages
1229
1230 case 120: { // all sound off
1231 KillAllVoices(pEngineChannel, itControlChangeEventOnCCList);
1232 break;
1233 }
1234 case 121: { // reset all controllers
1235 pEngineChannel->ResetControllers();
1236 break;
1237 }
1238 case 123: { // all notes off
1239 ReleaseAllVoices(pEngineChannel, itControlChangeEventOnCCList);
1240 break;
1241 }
1242 }
1243 }
1244
1245 /**
1246 * Reacts on MIDI system exclusive messages.
1247 *
1248 * @param itSysexEvent - sysex data size and time stamp of the sysex event
1249 */
1250 void Engine::ProcessSysex(Pool<Event>::Iterator& itSysexEvent) {
1251 RingBuffer<uint8_t>::NonVolatileReader reader = pSysexBuffer->get_non_volatile_reader();
1252
1253 uint8_t exclusive_status, id;
1254 if (!reader.pop(&exclusive_status)) goto free_sysex_data;
1255 if (!reader.pop(&id)) goto free_sysex_data;
1256 if (exclusive_status != 0xF0) goto free_sysex_data;
1257
1258 switch (id) {
1259 case 0x41: { // Roland
1260 dmsg(3,("Roland Sysex\n"));
1261 uint8_t device_id, model_id, cmd_id;
1262 if (!reader.pop(&device_id)) goto free_sysex_data;
1263 if (!reader.pop(&model_id)) goto free_sysex_data;
1264 if (!reader.pop(&cmd_id)) goto free_sysex_data;
1265 if (model_id != 0x42 /*GS*/) goto free_sysex_data;
1266 if (cmd_id != 0x12 /*DT1*/) goto free_sysex_data;
1267
1268 // command address
1269 uint8_t addr[3]; // 2 byte addr MSB, followed by 1 byte addr LSB)
1270 const RingBuffer<uint8_t>::NonVolatileReader checksum_reader = reader; // so we can calculate the check sum later
1271 if (reader.read(&addr[0], 3) != 3) goto free_sysex_data;
1272 if (addr[0] == 0x40 && addr[1] == 0x00) { // System Parameters
1273 dmsg(3,("\tSystem Parameter\n"));
1274 }
1275 else if (addr[0] == 0x40 && addr[1] == 0x01) { // Common Parameters
1276 dmsg(3,("\tCommon Parameter\n"));
1277 }
1278 else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x10) { // Part Parameters (1)
1279 dmsg(3,("\tPart Parameter\n"));
1280 switch (addr[2]) {
1281 case 0x40: { // scale tuning
1282 dmsg(3,("\t\tScale Tuning\n"));
1283 uint8_t scale_tunes[12]; // detuning of all 12 semitones of an octave
1284 if (reader.read(&scale_tunes[0], 12) != 12) goto free_sysex_data;
1285 uint8_t checksum;
1286 if (!reader.pop(&checksum)) goto free_sysex_data;
1287 #if CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1288 if (GSCheckSum(checksum_reader, 12)) goto free_sysex_data;
1289 #endif // CONFIG_ASSERT_GS_SYSEX_CHECKSUM
1290 for (int i = 0; i < 12; i++) scale_tunes[i] -= 64;
1291 AdjustScale((int8_t*) scale_tunes);
1292 dmsg(3,("\t\t\tNew scale applied.\n"));
1293 break;
1294 }
1295 }
1296 }
1297 else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x20) { // Part Parameters (2)
1298 }
1299 else if (addr[0] == 0x41) { // Drum Setup Parameters
1300 }
1301 break;
1302 }
1303 }
1304
1305 free_sysex_data: // finally free sysex data
1306 pSysexBuffer->increment_read_ptr(itSysexEvent->Param.Sysex.Size);
1307 }
1308
1309 /**
1310 * Calculates the Roland GS sysex check sum.
1311 *
1312 * @param AddrReader - reader which currently points to the first GS
1313 * command address byte of the GS sysex message in
1314 * question
1315 * @param DataSize - size of the GS message data (in bytes)
1316 */
1317 uint8_t Engine::GSCheckSum(const RingBuffer<uint8_t>::NonVolatileReader AddrReader, uint DataSize) {
1318 RingBuffer<uint8_t>::NonVolatileReader reader = AddrReader;
1319 uint bytes = 3 /*addr*/ + DataSize;
1320 uint8_t addr_and_data[bytes];
1321 reader.read(&addr_and_data[0], bytes);
1322 uint8_t sum = 0;
1323 for (uint i = 0; i < bytes; i++) sum += addr_and_data[i];
1324 return 128 - sum % 128;
1325 }
1326
1327 /**
1328 * Allows to tune each of the twelve semitones of an octave.
1329 *
1330 * @param ScaleTunes - detuning of all twelve semitones (in cents)
1331 */
1332 void Engine::AdjustScale(int8_t ScaleTunes[12]) {
1333 memcpy(&this->ScaleTuning[0], &ScaleTunes[0], 12); //TODO: currently not sample accurate
1334 }
1335
1336 /**
1337 * Releases all voices on an engine channel. All voices will go into
1338 * the release stage and thus it might take some time (e.g. dependant to
1339 * their envelope release time) until they actually die.
1340 *
1341 * @param pEngineChannel - engine channel on which all voices should be released
1342 * @param itReleaseEvent - event which caused this releasing of all voices
1343 */
1344 void Engine::ReleaseAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itReleaseEvent) {
1345 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1346 while (iuiKey) {
1347 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1348 ++iuiKey;
1349 // append a 'release' event to the key's own event list
1350 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
1351 if (itNewEvent) {
1352 *itNewEvent = *itReleaseEvent; // copy original event (to the key's event list)
1353 itNewEvent->Type = Event::type_release; // transform event type
1354 }
1355 else dmsg(1,("Event pool emtpy!\n"));
1356 }
1357 }
1358
1359 /**
1360 * Kills all voices on an engine channel as soon as possible. Voices
1361 * won't get into release state, their volume level will be ramped down
1362 * as fast as possible.
1363 *
1364 * @param pEngineChannel - engine channel on which all voices should be killed
1365 * @param itKillEvent - event which caused this killing of all voices
1366 */
1367 void Engine::KillAllVoices(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itKillEvent) {
1368 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
1369 RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
1370 while (iuiKey != end) { // iterate through all active keys
1371 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
1372 ++iuiKey;
1373 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
1374 RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
1375 for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
1376 itVoice->Kill(itKillEvent);
1377 --VoiceSpawnsLeft; //FIXME: just a temporary workaround, we should check the cause in StealVoice() instead
1378 }
1379 }
1380 }
1381
1382 /**
1383 * Initialize the parameter sequence for the modulation destination given by
1384 * by 'dst' with the constant value given by val.
1385 */
1386 void Engine::ResetSynthesisParameters(Event::destination_t dst, float val) {
1387 int maxsamples = pAudioOutputDevice->MaxSamplesPerCycle();
1388 float* m = &pSynthesisParameters[dst][0];
1389 for (int i = 0; i < maxsamples; i += 4) {
1390 m[i] = val;
1391 m[i+1] = val;
1392 m[i+2] = val;
1393 m[i+3] = val;
1394 }
1395 }
1396
1397 uint Engine::VoiceCount() {
1398 return ActiveVoiceCount;
1399 }
1400
1401 uint Engine::VoiceCountMax() {
1402 return ActiveVoiceCountMax;
1403 }
1404
1405 bool Engine::DiskStreamSupported() {
1406 return true;
1407 }
1408
1409 uint Engine::DiskStreamCount() {
1410 return (pDiskThread) ? pDiskThread->ActiveStreamCount : 0;
1411 }
1412
1413 uint Engine::DiskStreamCountMax() {
1414 return (pDiskThread) ? pDiskThread->ActiveStreamCountMax : 0;
1415 }
1416
1417 String Engine::DiskStreamBufferFillBytes() {
1418 return pDiskThread->GetBufferFillBytes();
1419 }
1420
1421 String Engine::DiskStreamBufferFillPercentage() {
1422 return pDiskThread->GetBufferFillPercentage();
1423 }
1424
1425 String Engine::EngineName() {
1426 return LS_GIG_ENGINE_NAME;
1427 }
1428
1429 String Engine::Description() {
1430 return "Gigasampler Engine";
1431 }
1432
1433 String Engine::Version() {
1434 String s = "$Revision: 1.50 $";
1435 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
1436 }
1437
1438 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC