/[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 438 - (show annotations) (download)
Wed Mar 9 22:12:15 2005 UTC (19 years ago) by persson
File size: 48019 byte(s)
* 24-bit decompression now supports the 20 and 18 bit formats
* support for "random" and "round robin" dimensions
* removed a warning printout for empty samples during instrument
  loading

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

  ViewVC Help
Powered by ViewVC