/[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 466 - (show annotations) (download)
Tue Mar 15 19:27:01 2005 UTC (19 years ago) by schoenebeck
File size: 48735 byte(s)
* fixed another crash under heavy load which was accidently introduced with
  the previous commit - events have to be processed completely on all
  engine channels before audio is rendered (fixes bug #7)

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 Engine::Engine() {
100 pAudioOutputDevice = NULL;
101 pDiskThread = NULL;
102 pEventGenerator = NULL;
103 pSysexBuffer = new RingBuffer<uint8_t>(SYSEX_BUFFER_SIZE, 0);
104 pEventQueue = new RingBuffer<Event>(MAX_EVENTS_PER_FRAGMENT, 0);
105 pEventPool = new Pool<Event>(MAX_EVENTS_PER_FRAGMENT);
106 pVoicePool = new Pool<Voice>(MAX_AUDIO_VOICES);
107 pVoiceStealingQueue = new RTList<Event>(pEventPool);
108 pGlobalEvents = new RTList<Event>(pEventPool);
109 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
110 iterVoice->SetEngine(this);
111 }
112 pVoicePool->clear();
113
114 pSynthesisParameters[0] = NULL; // we allocate when an audio device is connected
115 pBasicFilterParameters = NULL;
116 pMainFilterParameters = NULL;
117
118 ResetInternal();
119 }
120
121 Engine::~Engine() {
122 if (pDiskThread) {
123 dmsg(1,("Stopping disk thread..."));
124 pDiskThread->StopThread();
125 delete pDiskThread;
126 dmsg(1,("OK\n"));
127 }
128 if (pEventQueue) delete pEventQueue;
129 if (pEventPool) delete pEventPool;
130 if (pVoicePool) {
131 pVoicePool->clear();
132 delete pVoicePool;
133 }
134 if (pEventGenerator) delete pEventGenerator;
135 if (pMainFilterParameters) delete[] pMainFilterParameters;
136 if (pBasicFilterParameters) delete[] pBasicFilterParameters;
137 if (pSynthesisParameters[0]) free(pSynthesisParameters[0]);
138 if (pVoiceStealingQueue) delete pVoiceStealingQueue;
139 if (pSysexBuffer) delete pSysexBuffer;
140 EngineFactory::Destroy(this);
141 }
142
143 void Engine::Enable() {
144 dmsg(3,("gig::Engine: enabling\n"));
145 EngineDisabled.PushAndUnlock(false, 2); // set condition object 'EngineDisabled' to false (wait max. 2s)
146 dmsg(3,("gig::Engine: enabled (val=%d)\n", EngineDisabled.GetUnsafe()));
147 }
148
149 void Engine::Disable() {
150 dmsg(3,("gig::Engine: disabling\n"));
151 bool* pWasDisabled = EngineDisabled.PushAndUnlock(true, 2); // wait max. 2s
152 if (!pWasDisabled) dmsg(3,("gig::Engine warning: Timeout waiting to disable engine.\n"));
153 }
154
155 void Engine::DisableAndLock() {
156 dmsg(3,("gig::Engine: disabling\n"));
157 bool* pWasDisabled = EngineDisabled.Push(true, 2); // wait max. 2s
158 if (!pWasDisabled) dmsg(3,("gig::Engine warning: Timeout waiting to disable engine.\n"));
159 }
160
161 /**
162 * Reset all voices and disk thread and clear input event queue and all
163 * control and status variables.
164 */
165 void Engine::Reset() {
166 DisableAndLock();
167 ResetInternal();
168 Enable();
169 }
170
171 /**
172 * Reset all voices and disk thread and clear input event queue and all
173 * control and status variables. This method is not thread safe!
174 */
175 void Engine::ResetInternal() {
176 ActiveVoiceCount = 0;
177 ActiveVoiceCountMax = 0;
178
179 // reset voice stealing parameters
180 pVoiceStealingQueue->clear();
181 itLastStolenVoice = RTList<Voice>::Iterator();
182 iuiLastStolenKey = RTList<uint>::Iterator();
183 pLastStolenChannel = NULL;
184
185 // reset to normal chromatic scale (means equal temper)
186 memset(&ScaleTuning[0], 0x00, 12);
187
188 // reset all voices
189 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
190 iterVoice->Reset();
191 }
192 pVoicePool->clear();
193
194 // reset disk thread
195 if (pDiskThread) pDiskThread->Reset();
196
197 // delete all input events
198 pEventQueue->init();
199 }
200
201 void Engine::Connect(AudioOutputDevice* pAudioOut) {
202 pAudioOutputDevice = pAudioOut;
203
204 ResetInternal();
205
206 // inform audio driver for the need of two channels
207 try {
208 pAudioOutputDevice->AcquireChannels(2); // gig engine only stereo
209 }
210 catch (AudioOutputException e) {
211 String msg = "Audio output device unable to provide 2 audio channels, cause: " + e.Message();
212 throw LinuxSamplerException(msg);
213 }
214
215 this->MaxSamplesPerCycle = pAudioOutputDevice->MaxSamplesPerCycle();
216 this->SampleRate = pAudioOutputDevice->SampleRate();
217
218 // FIXME: audio drivers with varying fragment sizes might be a problem here
219 MaxFadeOutPos = MaxSamplesPerCycle - int(double(SampleRate) * EG_MIN_RELEASE_TIME) - 1;
220 if (MaxFadeOutPos < 0)
221 throw LinuxSamplerException("EG_MIN_RELEASE_TIME in EGADSR.h too big for current audio fragment size / sampling rate!");
222
223 // (re)create disk thread
224 if (this->pDiskThread) {
225 dmsg(1,("Stopping disk thread..."));
226 this->pDiskThread->StopThread();
227 delete this->pDiskThread;
228 dmsg(1,("OK\n"));
229 }
230 this->pDiskThread = new DiskThread(((pAudioOut->MaxSamplesPerCycle() << MAX_PITCH) << 1) + 6); //FIXME: assuming stereo
231 if (!pDiskThread) {
232 dmsg(0,("gig::Engine new diskthread = NULL\n"));
233 exit(EXIT_FAILURE);
234 }
235
236 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
237 iterVoice->pDiskThread = this->pDiskThread;
238 dmsg(3,("d"));
239 }
240 pVoicePool->clear();
241
242 // (re)create event generator
243 if (pEventGenerator) delete pEventGenerator;
244 pEventGenerator = new EventGenerator(pAudioOut->SampleRate());
245
246 // (re)allocate synthesis parameter matrix
247 if (pSynthesisParameters[0]) free(pSynthesisParameters[0]);
248
249 #if defined(__APPLE__)
250 pSynthesisParameters[0] = (float *) malloc(Event::destination_count * sizeof(float) * pAudioOut->MaxSamplesPerCycle());
251 #else
252 pSynthesisParameters[0] = (float *) memalign(16,(Event::destination_count * sizeof(float) * pAudioOut->MaxSamplesPerCycle()));
253 #endif
254 for (int dst = 1; dst < Event::destination_count; dst++)
255 pSynthesisParameters[dst] = pSynthesisParameters[dst - 1] + pAudioOut->MaxSamplesPerCycle();
256
257 // (re)allocate biquad filter parameter sequence
258 if (pBasicFilterParameters) delete[] pBasicFilterParameters;
259 if (pMainFilterParameters) delete[] pMainFilterParameters;
260 pBasicFilterParameters = new biquad_param_t[pAudioOut->MaxSamplesPerCycle()];
261 pMainFilterParameters = new biquad_param_t[pAudioOut->MaxSamplesPerCycle()];
262
263 dmsg(1,("Starting disk thread..."));
264 pDiskThread->StartThread();
265 dmsg(1,("OK\n"));
266
267 for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
268 if (!iterVoice->pDiskThread) {
269 dmsg(0,("Engine -> voice::trigger: !pDiskThread\n"));
270 exit(EXIT_FAILURE);
271 }
272 }
273 }
274
275 void Engine::ClearEventLists() {
276 pGlobalEvents->clear();
277 }
278
279 /**
280 * Copy all events from the engine's global input queue buffer to the
281 * engine's internal event list. This will be done at the beginning of
282 * each audio cycle (that is each RenderAudio() call) to distinguish
283 * all global events which have to be processed in the current audio
284 * cycle. These events are usually just SysEx messages. Every
285 * EngineChannel has it's own input event queue buffer and event list
286 * to handle common events like NoteOn, NoteOff and ControlChange
287 * events.
288 *
289 * @param Samples - number of sample points to be processed in the
290 * current audio cycle
291 */
292 void Engine::ImportEvents(uint Samples) {
293 RingBuffer<Event>::NonVolatileReader eventQueueReader = pEventQueue->get_non_volatile_reader();
294 Event* pEvent;
295 while (true) {
296 // get next event from input event queue
297 if (!(pEvent = eventQueueReader.pop())) break;
298 // if younger event reached, ignore that and all subsequent ones for now
299 if (pEvent->FragmentPos() >= Samples) {
300 eventQueueReader--;
301 dmsg(2,("Younger Event, pos=%d ,Samples=%d!\n",pEvent->FragmentPos(),Samples));
302 pEvent->ResetFragmentPos();
303 break;
304 }
305 // copy event to internal event list
306 if (pGlobalEvents->poolIsEmpty()) {
307 dmsg(1,("Event pool emtpy!\n"));
308 break;
309 }
310 *pGlobalEvents->allocAppend() = *pEvent;
311 }
312 eventQueueReader.free(); // free all copied events from input queue
313 }
314
315 /**
316 * Let this engine proceed to render the given amount of sample points. The
317 * calculated audio data of all voices of this engine will be placed into
318 * the engine's audio sum buffer which has to be copied and eventually be
319 * converted to the appropriate value range by the audio output class (e.g.
320 * AlsaIO or JackIO) right after.
321 *
322 * @param Samples - number of sample points to be rendered
323 * @returns 0 on success
324 */
325 int Engine::RenderAudio(uint Samples) {
326 dmsg(5,("RenderAudio(Samples=%d)\n", Samples));
327
328 // return if engine disabled
329 if (EngineDisabled.Pop()) {
330 dmsg(5,("gig::Engine: engine disabled (val=%d)\n",EngineDisabled.GetUnsafe()));
331 return 0;
332 }
333
334 // update time of start and end of this audio fragment (as events' time stamps relate to this)
335 pEventGenerator->UpdateFragmentTime(Samples);
336
337 // get all events from the engine's global input event queue which belong to the current fragment
338 // (these are usually just SysEx messages)
339 ImportEvents(Samples);
340
341 // process engine global events (these are currently only MIDI System Exclusive messages)
342 {
343 RTList<Event>::Iterator itEvent = pGlobalEvents->first();
344 RTList<Event>::Iterator end = pGlobalEvents->end();
345 for (; itEvent != end; ++itEvent) {
346 switch (itEvent->Type) {
347 case Event::type_sysex:
348 dmsg(5,("Engine: Sysex received\n"));
349 ProcessSysex(itEvent);
350 break;
351 }
352 }
353 }
354
355 // We only allow a maximum of MAX_AUDIO_VOICES voices to be stolen
356 // in each audio fragment. All subsequent request for spawning new
357 // voices in the same audio fragment will be ignored.
358 VoiceTheftsLeft = MAX_AUDIO_VOICES;
359
360 // reset internal voice counter (just for statistic of active voices)
361 ActiveVoiceCountTemp = 0;
362
363
364 // handle events on all engine channels
365 for (int i = 0; i < engineChannels.size(); i++) {
366 if (!engineChannels[i]->pInstrument) continue; // ignore if no instrument loaded
367 ProcessEvents(engineChannels[i], Samples);
368 }
369
370 // render all 'normal', active voices on all engine channels
371 for (int i = 0; i < engineChannels.size(); i++) {
372 if (!engineChannels[i]->pInstrument) continue; // ignore if no instrument loaded
373 RenderActiveVoices(engineChannels[i], Samples);
374 }
375
376 // now that all ordinary voices on ALL engine channels are rendered, render new stolen voices
377 RenderStolenVoices(Samples);
378
379 // handle cleanup on all engine channels for the next audio fragment
380 for (int i = 0; i < engineChannels.size(); i++) {
381 if (!engineChannels[i]->pInstrument) continue; // ignore if no instrument loaded
382 PostProcess(engineChannels[i]);
383 }
384
385
386 // empty the engine's event list for the next audio fragment
387 ClearEventLists();
388
389 // reset voice stealing for the next audio fragment
390 pVoiceStealingQueue->clear();
391 itLastStolenVoice = RTList<Voice>::Iterator();
392 iuiLastStolenKey = RTList<uint>::Iterator();
393 pLastStolenChannel = NULL;
394
395 // just some statistics about this engine instance
396 ActiveVoiceCount = ActiveVoiceCountTemp;
397 if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;
398
399 return 0;
400 }
401
402 void Engine::ProcessEvents(EngineChannel* pEngineChannel, uint Samples) {
403 // get all events from the engine channels's input event queue which belong to the current fragment
404 // (these are the common events like NoteOn, NoteOff, ControlChange, etc.)
405 pEngineChannel->ImportEvents(Samples);
406
407 // process events
408 {
409 RTList<Event>::Iterator itEvent = pEngineChannel->pEvents->first();
410 RTList<Event>::Iterator end = pEngineChannel->pEvents->end();
411 for (; itEvent != end; ++itEvent) {
412 switch (itEvent->Type) {
413 case Event::type_note_on:
414 dmsg(5,("Engine: Note on received\n"));
415 ProcessNoteOn((EngineChannel*)itEvent->pEngineChannel, itEvent);
416 break;
417 case Event::type_note_off:
418 dmsg(5,("Engine: Note off received\n"));
419 ProcessNoteOff((EngineChannel*)itEvent->pEngineChannel, itEvent);
420 break;
421 case Event::type_control_change:
422 dmsg(5,("Engine: MIDI CC received\n"));
423 ProcessControlChange((EngineChannel*)itEvent->pEngineChannel, itEvent);
424 break;
425 case Event::type_pitchbend:
426 dmsg(5,("Engine: Pitchbend received\n"));
427 ProcessPitchbend((EngineChannel*)itEvent->pEngineChannel, itEvent);
428 break;
429 }
430 }
431 }
432 }
433
434 void Engine::RenderActiveVoices(EngineChannel* pEngineChannel, uint Samples) {
435 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
436 RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
437 while (iuiKey != end) { // iterate through all active keys
438 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
439 ++iuiKey;
440
441 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
442 RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
443 for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
444 // now render current voice
445 itVoice->Render(Samples);
446 if (itVoice->IsActive()) ActiveVoiceCountTemp++; // still active
447 else { // voice reached end, is now inactive
448 FreeVoice(pEngineChannel, itVoice); // remove voice from the list of active voices
449 }
450 }
451 }
452 }
453
454 void Engine::RenderStolenVoices(uint Samples) {
455 RTList<Event>::Iterator itVoiceStealEvent = pVoiceStealingQueue->first();
456 RTList<Event>::Iterator end = pVoiceStealingQueue->end();
457 for (; itVoiceStealEvent != end; ++itVoiceStealEvent) {
458 EngineChannel* pEngineChannel = (EngineChannel*) itVoiceStealEvent->pEngineChannel;
459 Pool<Voice>::Iterator itNewVoice =
460 LaunchVoice(pEngineChannel, itVoiceStealEvent, itVoiceStealEvent->Param.Note.Layer, itVoiceStealEvent->Param.Note.ReleaseTrigger, false);
461 if (itNewVoice) {
462 itNewVoice->Render(Samples);
463 if (itNewVoice->IsActive()) ActiveVoiceCountTemp++; // still active
464 else { // voice reached end, is now inactive
465 FreeVoice(pEngineChannel, itNewVoice); // remove voice from the list of active voices
466 }
467 }
468 else dmsg(1,("gig::Engine: ERROR, voice stealing didn't work out!\n"));
469 }
470 }
471
472 void Engine::PostProcess(EngineChannel* pEngineChannel) {
473 // free all keys which have no active voices left
474 {
475 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
476 RTList<uint>::Iterator end = pEngineChannel->pActiveKeys->end();
477 while (iuiKey != end) { // iterate through all active keys
478 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
479 ++iuiKey;
480 if (pKey->pActiveVoices->isEmpty()) FreeKey(pEngineChannel, pKey);
481 #if DEVMODE
482 else { // FIXME: should be removed before the final release (purpose: just a sanity check for debugging)
483 RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first();
484 RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end();
485 for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key
486 if (itVoice->itKillEvent) {
487 dmsg(1,("gig::Engine: ERROR, killed voice survived !!!\n"));
488 }
489 }
490 }
491 #endif // DEVMODE
492 }
493 }
494
495 // empty the engine channel's own event lists
496 pEngineChannel->ClearEventLists();
497 }
498
499 /**
500 * Will be called by the MIDI input device whenever a MIDI system
501 * exclusive message has arrived.
502 *
503 * @param pData - pointer to sysex data
504 * @param Size - lenght of sysex data (in bytes)
505 */
506 void Engine::SendSysex(void* pData, uint Size) {
507 Event event = pEventGenerator->CreateEvent();
508 event.Type = Event::type_sysex;
509 event.Param.Sysex.Size = Size;
510 event.pEngineChannel = NULL; // as Engine global event
511 if (pEventQueue->write_space() > 0) {
512 if (pSysexBuffer->write_space() >= Size) {
513 // copy sysex data to input buffer
514 uint toWrite = Size;
515 uint8_t* pPos = (uint8_t*) pData;
516 while (toWrite) {
517 const uint writeNow = RTMath::Min(toWrite, pSysexBuffer->write_space_to_end());
518 pSysexBuffer->write(pPos, writeNow);
519 toWrite -= writeNow;
520 pPos += writeNow;
521
522 }
523 // finally place sysex event into input event queue
524 pEventQueue->push(&event);
525 }
526 else dmsg(1,("Engine: Sysex message too large (%d byte) for input buffer (%d byte)!",Size,SYSEX_BUFFER_SIZE));
527 }
528 else dmsg(1,("Engine: Input event queue full!"));
529 }
530
531 /**
532 * Assigns and triggers a new voice for the respective MIDI key.
533 *
534 * @param pEngineChannel - engine channel on which this event occured on
535 * @param itNoteOnEvent - key, velocity and time stamp of the event
536 */
537 void Engine::ProcessNoteOn(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
538
539 const int key = itNoteOnEvent->Param.Note.Key;
540
541 // Change key dimension value if key is in keyswitching area
542 {
543 const ::gig::Instrument* pInstrument = pEngineChannel->pInstrument;
544 if (key >= pInstrument->DimensionKeyRange.low && key <= pInstrument->DimensionKeyRange.high)
545 pEngineChannel->CurrentKeyDimension = ((key - pInstrument->DimensionKeyRange.low) * 128) /
546 (pInstrument->DimensionKeyRange.high - pInstrument->DimensionKeyRange.low + 1);
547 }
548
549 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key];
550
551 pKey->KeyPressed = true; // the MIDI key was now pressed down
552
553 // cancel release process of voices on this key if needed
554 if (pKey->Active && !pEngineChannel->SustainPedal) {
555 RTList<Event>::Iterator itCancelReleaseEvent = pKey->pEvents->allocAppend();
556 if (itCancelReleaseEvent) {
557 *itCancelReleaseEvent = *itNoteOnEvent; // copy event
558 itCancelReleaseEvent->Type = Event::type_cancel_release; // transform event type
559 }
560 else dmsg(1,("Event pool emtpy!\n"));
561 }
562
563 // move note on event to the key's own event list
564 RTList<Event>::Iterator itNoteOnEventOnKeyList = itNoteOnEvent.moveToEndOf(pKey->pEvents);
565
566 // allocate and trigger new voice(s) for the key
567 {
568 // first, get total amount of required voices (dependant on amount of layers)
569 ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOnEventOnKeyList->Param.Note.Key);
570 if (pRegion) {
571 int voicesRequired = pRegion->Layers;
572 // now launch the required amount of voices
573 for (int i = 0; i < voicesRequired; i++)
574 LaunchVoice(pEngineChannel, itNoteOnEventOnKeyList, i, false, true);
575 }
576 }
577
578 pKey->RoundRobinIndex++;
579 }
580
581 /**
582 * Releases the voices on the given key if sustain pedal is not pressed.
583 * If sustain is pressed, the release of the note will be postponed until
584 * sustain pedal will be released or voice turned inactive by itself (e.g.
585 * due to completion of sample playback).
586 *
587 * @param pEngineChannel - engine channel on which this event occured on
588 * @param itNoteOffEvent - key, velocity and time stamp of the event
589 */
590 void Engine::ProcessNoteOff(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOffEvent) {
591 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itNoteOffEvent->Param.Note.Key];
592
593 pKey->KeyPressed = false; // the MIDI key was now released
594
595 // release voices on this key if needed
596 if (pKey->Active && !pEngineChannel->SustainPedal) {
597 itNoteOffEvent->Type = Event::type_release; // transform event type
598 }
599
600 // move event to the key's own event list
601 RTList<Event>::Iterator itNoteOffEventOnKeyList = itNoteOffEvent.moveToEndOf(pKey->pEvents);
602
603 // spawn release triggered voice(s) if needed
604 if (pKey->ReleaseTrigger) {
605 // first, get total amount of required voices (dependant on amount of layers)
606 ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key);
607 if (pRegion) {
608 int voicesRequired = pRegion->Layers;
609 // now launch the required amount of voices
610 for (int i = 0; i < voicesRequired; i++)
611 LaunchVoice(pEngineChannel, itNoteOffEventOnKeyList, i, true, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples
612 }
613 pKey->ReleaseTrigger = false;
614 }
615 }
616
617 /**
618 * Moves pitchbend event from the general (input) event list to the pitch
619 * event list.
620 *
621 * @param pEngineChannel - engine channel on which this event occured on
622 * @param itPitchbendEvent - absolute pitch value and time stamp of the event
623 */
624 void Engine::ProcessPitchbend(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itPitchbendEvent) {
625 pEngineChannel->Pitch = itPitchbendEvent->Param.Pitch.Pitch; // store current pitch value
626 itPitchbendEvent.moveToEndOf(pEngineChannel->pSynthesisEvents[Event::destination_vco]);
627 }
628
629 /**
630 * Allocates and triggers a new voice. This method will usually be
631 * called by the ProcessNoteOn() method and by the voices itself
632 * (e.g. to spawn further voices on the same key for layered sounds).
633 *
634 * @param pEngineChannel - engine channel on which this event occured on
635 * @param itNoteOnEvent - key, velocity and time stamp of the event
636 * @param iLayer - layer index for the new voice (optional - only
637 * in case of layered sounds of course)
638 * @param ReleaseTriggerVoice - if new voice is a release triggered voice
639 * (optional, default = false)
640 * @param VoiceStealing - if voice stealing should be performed
641 * when there is no free voice
642 * (optional, default = true)
643 * @returns pointer to new voice or NULL if there was no free voice or
644 * if the voice wasn't triggered (for example when no region is
645 * defined for the given key).
646 */
647 Pool<Voice>::Iterator Engine::LaunchVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int iLayer, bool ReleaseTriggerVoice, bool VoiceStealing) {
648 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key];
649
650 // allocate a new voice for the key
651 Pool<Voice>::Iterator itNewVoice = pKey->pActiveVoices->allocAppend();
652 if (itNewVoice) {
653 // launch the new voice
654 if (itNewVoice->Trigger(pEngineChannel, itNoteOnEvent, pEngineChannel->Pitch, pEngineChannel->pInstrument, iLayer, ReleaseTriggerVoice, VoiceStealing) < 0) {
655 dmsg(4,("Voice not triggered\n"));
656 pKey->pActiveVoices->free(itNewVoice);
657 }
658 else { // on success
659 uint** ppKeyGroup = NULL;
660 if (itNewVoice->KeyGroup) { // if this voice / key belongs to a key group
661 ppKeyGroup = &pEngineChannel->ActiveKeyGroups[itNewVoice->KeyGroup];
662 if (*ppKeyGroup) { // if there's already an active key in that key group
663 midi_key_info_t* pOtherKey = &pEngineChannel->pMIDIKeyInfo[**ppKeyGroup];
664 // kill all voices on the (other) key
665 RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();
666 RTList<Voice>::Iterator end = pOtherKey->pActiveVoices->end();
667 for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {
668 if (itVoiceToBeKilled->Type != Voice::type_release_trigger) itVoiceToBeKilled->Kill(itNoteOnEvent);
669 }
670 }
671 }
672 if (!pKey->Active) { // mark as active key
673 pKey->Active = true;
674 pKey->itSelf = pEngineChannel->pActiveKeys->allocAppend();
675 *pKey->itSelf = itNoteOnEvent->Param.Note.Key;
676 }
677 if (itNewVoice->KeyGroup) {
678 *ppKeyGroup = &*pKey->itSelf; // put key as the (new) active key to its key group
679 }
680 if (itNewVoice->Type == Voice::type_release_trigger_required) pKey->ReleaseTrigger = true; // mark key for the need of release triggered voice(s)
681 return itNewVoice; // success
682 }
683 }
684 else if (VoiceStealing) {
685
686 // try to steal one voice
687 StealVoice(pEngineChannel, itNoteOnEvent);
688
689 // put note-on event into voice-stealing queue, so it will be reprocessed after killed voice died
690 RTList<Event>::Iterator itStealEvent = pVoiceStealingQueue->allocAppend();
691 if (itStealEvent) {
692 *itStealEvent = *itNoteOnEvent; // copy event
693 itStealEvent->Param.Note.Layer = iLayer;
694 itStealEvent->Param.Note.ReleaseTrigger = ReleaseTriggerVoice;
695 }
696 else dmsg(1,("Voice stealing queue full!\n"));
697 }
698
699 return Pool<Voice>::Iterator(); // no free voice or error
700 }
701
702 /**
703 * Will be called by LaunchVoice() method in case there are no free
704 * voices left. This method will select and kill one old voice for
705 * voice stealing and postpone the note-on event until the selected
706 * voice actually died.
707 *
708 * @param pEngineChannel - engine channel on which this event occured on
709 * @param itNoteOnEvent - key, velocity and time stamp of the event
710 */
711 void Engine::StealVoice(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent) {
712 if (!VoiceTheftsLeft) {
713 dmsg(1,("Max. voice thefts per audio fragment reached (you may raise MAX_AUDIO_VOICES).\n"));
714 return;
715 }
716 if (!pEventPool->poolIsEmpty()) {
717
718 RTList<Voice>::Iterator itSelectedVoice;
719
720 // Select one voice for voice stealing
721 switch (VOICE_STEAL_ALGORITHM) {
722
723 // try to pick the oldest voice on the key where the new
724 // voice should be spawned, if there is no voice on that
725 // key, or no voice left to kill there, then procceed with
726 // 'oldestkey' algorithm
727 case voice_steal_algo_oldestvoiceonkey: {
728 #if 0 // FIXME: broken
729 midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key];
730 if (this->itLastStolenVoice) {
731 itSelectedVoice = this->itLastStolenVoice;
732 ++itSelectedVoice;
733 }
734 else { // no voice stolen in this audio fragment cycle yet
735 itSelectedVoice = pSelectedKey->pActiveVoices->first();
736 }
737 if (itSelectedVoice) {
738 iuiSelectedKey = pSelectedKey->itSelf;
739 break; // selection succeeded
740 }
741 #endif
742 } // no break - intentional !
743
744 // try to pick the oldest voice on the oldest active key
745 // (caution: must stay after 'oldestvoiceonkey' algorithm !)
746 case voice_steal_algo_oldestkey: {
747 if (this->itLastStolenVoice) {
748 itSelectedVoice = this->itLastStolenVoice;
749 ++itSelectedVoice;
750 if (itSelectedVoice) break; // selection succeeded
751 RTList<uint>::Iterator iuiSelectedKey = this->iuiLastStolenKey;
752 ++iuiSelectedKey;
753 if (iuiSelectedKey) {
754 this->iuiLastStolenKey = iuiSelectedKey;
755 midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[*iuiSelectedKey];
756 itSelectedVoice = pSelectedKey->pActiveVoices->first();
757 break; // selection succeeded
758 }
759 }
760 break;
761 }
762
763 // don't steal anything
764 case voice_steal_algo_none:
765 default: {
766 dmsg(1,("No free voice (voice stealing disabled)!\n"));
767 return;
768 }
769 }
770
771 // steal oldest voice on the oldest key from this or any other engine channel
772 if (!itSelectedVoice) {
773 EngineChannel* pSelectedChannel = (pLastStolenChannel) ? pLastStolenChannel : pEngineChannel;
774 int iChannelIndex = pSelectedChannel->iEngineIndexSelf;
775 while (true) {
776 RTList<uint>::Iterator iuiSelectedKey = pSelectedChannel->pActiveKeys->first();
777 if (iuiSelectedKey) {
778 midi_key_info_t* pSelectedKey = &pSelectedChannel->pMIDIKeyInfo[*iuiSelectedKey];
779 itSelectedVoice = pSelectedKey->pActiveVoices->first();
780 iuiLastStolenKey = iuiSelectedKey;
781 pLastStolenChannel = pSelectedChannel;
782 break; // selection succeeded
783 }
784 iChannelIndex = (iChannelIndex + 1) % engineChannels.size();
785 pSelectedChannel = engineChannels[iChannelIndex];
786 }
787 }
788
789 //FIXME: can be removed, just a sanity check for debugging
790 if (!itSelectedVoice->IsActive()) dmsg(1,("gig::Engine: ERROR, tried to steal a voice which was not active !!!\n"));
791
792 // now kill the selected voice
793 itSelectedVoice->Kill(itNoteOnEvent);
794
795 // remember which voice we stole, so we can simply proceed for the next voice stealing
796 itLastStolenVoice = itSelectedVoice;
797
798 --VoiceTheftsLeft;
799 }
800 else dmsg(1,("Event pool emtpy!\n"));
801 }
802
803 /**
804 * Removes the given voice from the MIDI key's list of active voices.
805 * This method will be called when a voice went inactive, e.g. because
806 * it finished to playback its sample, finished its release stage or
807 * just was killed.
808 *
809 * @param pEngineChannel - engine channel on which this event occured on
810 * @param itVoice - points to the voice to be freed
811 */
812 void Engine::FreeVoice(EngineChannel* pEngineChannel, Pool<Voice>::Iterator& itVoice) {
813 if (itVoice) {
814 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[itVoice->MIDIKey];
815
816 uint keygroup = itVoice->KeyGroup;
817
818 // free the voice object
819 pVoicePool->free(itVoice);
820
821 // if no other voices left and member of a key group, remove from key group
822 if (pKey->pActiveVoices->isEmpty() && keygroup) {
823 uint** ppKeyGroup = &pEngineChannel->ActiveKeyGroups[keygroup];
824 if (*ppKeyGroup == &*pKey->itSelf) *ppKeyGroup = NULL; // remove key from key group
825 }
826 }
827 else std::cerr << "Couldn't release voice! (!itVoice)\n" << std::flush;
828 }
829
830 /**
831 * Called when there's no more voice left on a key, this call will
832 * update the key info respectively.
833 *
834 * @param pEngineChannel - engine channel on which this event occured on
835 * @param pKey - key which is now inactive
836 */
837 void Engine::FreeKey(EngineChannel* pEngineChannel, midi_key_info_t* pKey) {
838 if (pKey->pActiveVoices->isEmpty()) {
839 pKey->Active = false;
840 pEngineChannel->pActiveKeys->free(pKey->itSelf); // remove key from list of active keys
841 pKey->itSelf = RTList<uint>::Iterator();
842 pKey->ReleaseTrigger = false;
843 pKey->pEvents->clear();
844 dmsg(3,("Key has no more voices now\n"));
845 }
846 else dmsg(1,("gig::Engine: Oops, tried to free a key which contains voices.\n"));
847 }
848
849 /**
850 * Reacts on supported control change commands (e.g. pitch bend wheel,
851 * modulation wheel, aftertouch).
852 *
853 * @param pEngineChannel - engine channel on which this event occured on
854 * @param itControlChangeEvent - controller, value and time stamp of the event
855 */
856 void Engine::ProcessControlChange(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itControlChangeEvent) {
857 dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));
858
859 switch (itControlChangeEvent->Param.CC.Controller) {
860 case 7: { // volume
861 //TODO: not sample accurate yet
862 pEngineChannel->GlobalVolume = (float) itControlChangeEvent->Param.CC.Value / 127.0f;
863 break;
864 }
865 case 10: { // panpot
866 //TODO: not sample accurate yet
867 const int pan = (int) itControlChangeEvent->Param.CC.Value - 64;
868 pEngineChannel->GlobalPanLeft = 1.0f - float(RTMath::Max(pan, 0)) / 63.0f;
869 pEngineChannel->GlobalPanRight = 1.0f - float(RTMath::Min(pan, 0)) / -64.0f;
870 break;
871 }
872 case 64: { // sustain
873 if (itControlChangeEvent->Param.CC.Value >= 64 && !pEngineChannel->SustainPedal) {
874 dmsg(4,("PEDAL DOWN\n"));
875 pEngineChannel->SustainPedal = true;
876
877 // cancel release process of voices if necessary
878 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
879 if (iuiKey) {
880 itControlChangeEvent->Type = Event::type_cancel_release; // transform event type
881 while (iuiKey) {
882 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
883 ++iuiKey;
884 if (!pKey->KeyPressed) {
885 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
886 if (itNewEvent) *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
887 else dmsg(1,("Event pool emtpy!\n"));
888 }
889 }
890 }
891 }
892 if (itControlChangeEvent->Param.CC.Value < 64 && pEngineChannel->SustainPedal) {
893 dmsg(4,("PEDAL UP\n"));
894 pEngineChannel->SustainPedal = false;
895
896 // release voices if their respective key is not pressed
897 RTList<uint>::Iterator iuiKey = pEngineChannel->pActiveKeys->first();
898 if (iuiKey) {
899 itControlChangeEvent->Type = Event::type_release; // transform event type
900 while (iuiKey) {
901 midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[*iuiKey];
902 ++iuiKey;
903 if (!pKey->KeyPressed) {
904 RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
905 if (itNewEvent) *itNewEvent = *itControlChangeEvent; // copy event to the key's own event list
906 else dmsg(1,("Event pool emtpy!\n"));
907 }
908 }
909 }
910 }
911 break;
912 }
913 }
914
915 // update controller value in the engine's controller table
916 pEngineChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;
917
918 // move event from the unsorted event list to the control change event list
919 itControlChangeEvent.moveToEndOf(pEngineChannel->pCCEvents);
920 }
921
922 /**
923 * Reacts on MIDI system exclusive messages.
924 *
925 * @param itSysexEvent - sysex data size and time stamp of the sysex event
926 */
927 void Engine::ProcessSysex(Pool<Event>::Iterator& itSysexEvent) {
928 RingBuffer<uint8_t>::NonVolatileReader reader = pSysexBuffer->get_non_volatile_reader();
929
930 uint8_t exclusive_status, id;
931 if (!reader.pop(&exclusive_status)) goto free_sysex_data;
932 if (!reader.pop(&id)) goto free_sysex_data;
933 if (exclusive_status != 0xF0) goto free_sysex_data;
934
935 switch (id) {
936 case 0x41: { // Roland
937 uint8_t device_id, model_id, cmd_id;
938 if (!reader.pop(&device_id)) goto free_sysex_data;
939 if (!reader.pop(&model_id)) goto free_sysex_data;
940 if (!reader.pop(&cmd_id)) goto free_sysex_data;
941 if (model_id != 0x42 /*GS*/) goto free_sysex_data;
942 if (cmd_id != 0x12 /*DT1*/) goto free_sysex_data;
943
944 // command address
945 uint8_t addr[3]; // 2 byte addr MSB, followed by 1 byte addr LSB)
946 const RingBuffer<uint8_t>::NonVolatileReader checksum_reader = reader; // so we can calculate the check sum later
947 if (reader.read(&addr[0], 3) != 3) goto free_sysex_data;
948 if (addr[0] == 0x40 && addr[1] == 0x00) { // System Parameters
949 }
950 else if (addr[0] == 0x40 && addr[1] == 0x01) { // Common Parameters
951 }
952 else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x10) { // Part Parameters (1)
953 switch (addr[3]) {
954 case 0x40: { // scale tuning
955 uint8_t scale_tunes[12]; // detuning of all 12 semitones of an octave
956 if (reader.read(&scale_tunes[0], 12) != 12) goto free_sysex_data;
957 uint8_t checksum;
958 if (!reader.pop(&checksum)) goto free_sysex_data;
959 if (GSCheckSum(checksum_reader, 12) != checksum) goto free_sysex_data;
960 for (int i = 0; i < 12; i++) scale_tunes[i] -= 64;
961 AdjustScale((int8_t*) scale_tunes);
962 break;
963 }
964 }
965 }
966 else if (addr[0] == 0x40 && (addr[1] & 0xf0) == 0x20) { // Part Parameters (2)
967 }
968 else if (addr[0] == 0x41) { // Drum Setup Parameters
969 }
970 break;
971 }
972 }
973
974 free_sysex_data: // finally free sysex data
975 pSysexBuffer->increment_read_ptr(itSysexEvent->Param.Sysex.Size);
976 }
977
978 /**
979 * Calculates the Roland GS sysex check sum.
980 *
981 * @param AddrReader - reader which currently points to the first GS
982 * command address byte of the GS sysex message in
983 * question
984 * @param DataSize - size of the GS message data (in bytes)
985 */
986 uint8_t Engine::GSCheckSum(const RingBuffer<uint8_t>::NonVolatileReader AddrReader, uint DataSize) {
987 RingBuffer<uint8_t>::NonVolatileReader reader = AddrReader;
988 uint bytes = 3 /*addr*/ + DataSize;
989 uint8_t addr_and_data[bytes];
990 reader.read(&addr_and_data[0], bytes);
991 uint8_t sum = 0;
992 for (uint i = 0; i < bytes; i++) sum += addr_and_data[i];
993 return 128 - sum % 128;
994 }
995
996 /**
997 * Allows to tune each of the twelve semitones of an octave.
998 *
999 * @param ScaleTunes - detuning of all twelve semitones (in cents)
1000 */
1001 void Engine::AdjustScale(int8_t ScaleTunes[12]) {
1002 memcpy(&this->ScaleTuning[0], &ScaleTunes[0], 12); //TODO: currently not sample accurate
1003 }
1004
1005 /**
1006 * Initialize the parameter sequence for the modulation destination given by
1007 * by 'dst' with the constant value given by val.
1008 */
1009 void Engine::ResetSynthesisParameters(Event::destination_t dst, float val) {
1010 int maxsamples = pAudioOutputDevice->MaxSamplesPerCycle();
1011 float* m = &pSynthesisParameters[dst][0];
1012 for (int i = 0; i < maxsamples; i += 4) {
1013 m[i] = val;
1014 m[i+1] = val;
1015 m[i+2] = val;
1016 m[i+3] = val;
1017 }
1018 }
1019
1020 uint Engine::VoiceCount() {
1021 return ActiveVoiceCount;
1022 }
1023
1024 uint Engine::VoiceCountMax() {
1025 return ActiveVoiceCountMax;
1026 }
1027
1028 bool Engine::DiskStreamSupported() {
1029 return true;
1030 }
1031
1032 uint Engine::DiskStreamCount() {
1033 return (pDiskThread) ? pDiskThread->ActiveStreamCount : 0;
1034 }
1035
1036 uint Engine::DiskStreamCountMax() {
1037 return (pDiskThread) ? pDiskThread->ActiveStreamCountMax : 0;
1038 }
1039
1040 String Engine::DiskStreamBufferFillBytes() {
1041 return pDiskThread->GetBufferFillBytes();
1042 }
1043
1044 String Engine::DiskStreamBufferFillPercentage() {
1045 return pDiskThread->GetBufferFillPercentage();
1046 }
1047
1048 String Engine::EngineName() {
1049 return "GigEngine";
1050 }
1051
1052 String Engine::Description() {
1053 return "Gigasampler Engine";
1054 }
1055
1056 String Engine::Version() {
1057 String s = "$Revision: 1.32 $";
1058 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
1059 }
1060
1061 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC