/[svn]/linuxsampler/trunk/src/audiothread.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/audiothread.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 32 by schoenebeck, Tue Feb 3 13:21:19 2004 UTC revision 40 by schoenebeck, Tue Mar 30 13:14:58 2004 UTC
# Line 22  Line 22 
22    
23  #include "audiothread.h"  #include "audiothread.h"
24    
25  AudioThread::AudioThread(AudioIO* pAudioIO, DiskThread* pDiskThread, gig::Instrument* pInstrument) {  AudioThread::AudioThread(AudioIO* pAudioIO) {
26      this->pAudioIO     = pAudioIO;      this->pAudioIO     = pAudioIO;
27      this->pDiskThread  = pDiskThread;      this->pDiskThread  = new DiskThread(((pAudioIO->MaxSamplesPerCycle() << MAX_PITCH) << 1) + 6); //FIXME: assuming stereo
28      this->pInstrument  = pInstrument;      this->pInstrument  = NULL;
29      this->Pitch        = 0;      this->Pitch        = 0;
30      Voice::pDiskThread = pDiskThread;      this->SustainPedal = 0;
31        Voice::pDiskThread = this->pDiskThread;
32      Voice::pEngine     = this;      Voice::pEngine     = this;
33      pEventQueue        = new RingBuffer<ModulationSystem::Event>(MAX_EVENTS_PER_FRAGMENT);      pEventQueue        = new RingBuffer<ModulationSystem::Event>(MAX_EVENTS_PER_FRAGMENT);
34      pEventPool         = new RTELMemoryPool<ModulationSystem::Event>(MAX_EVENTS_PER_FRAGMENT);      pEventPool         = new RTELMemoryPool<ModulationSystem::Event>(MAX_EVENTS_PER_FRAGMENT);
35      pVoicePool         = new RTELMemoryPool<Voice>(MAX_AUDIO_VOICES);      pVoicePool         = new RTELMemoryPool<Voice>(MAX_AUDIO_VOICES);
36      pSustainedKeyPool  = new RTELMemoryPool<uint>(128);      pActiveKeys        = new RTELMemoryPool<uint>(128);
37      pEvents            = new RTEList<ModulationSystem::Event>(pEventPool);      pEvents            = new RTEList<ModulationSystem::Event>(pEventPool);
38        pCCEvents          = new RTEList<ModulationSystem::Event>(pEventPool);
39      for (uint i = 0; i < ModulationSystem::destination_count; i++) {      for (uint i = 0; i < ModulationSystem::destination_count; i++) {
40          pCCEvents[i] = new RTEList<ModulationSystem::Event>(pEventPool);          pSynthesisEvents[i] = new RTEList<ModulationSystem::Event>(pEventPool);
41      }      }
42      for (uint i = 0; i < 128; i++) {      for (uint i = 0; i < 128; i++) {
43          pMIDIKeyInfo[i].pActiveVoices    = new RTEList<Voice>(pVoicePool);          pMIDIKeyInfo[i].pActiveVoices = new RTEList<Voice>(pVoicePool);
44          pMIDIKeyInfo[i].pSustainPtr      = NULL;          pMIDIKeyInfo[i].KeyPressed    = false;
45          pMIDIKeyInfo[i].Sustained        = false;          pMIDIKeyInfo[i].Active        = false;
46          pMIDIKeyInfo[i].KeyPressed       = false;          pMIDIKeyInfo[i].pSelf         = NULL;
47          pMIDIKeyInfo[i].pSustainPoolNode = NULL;          pMIDIKeyInfo[i].pEvents       = new RTEList<ModulationSystem::Event>(pEventPool);
48      }      }
49    
50      // FIXME: assuming stereo output      // FIXME: assuming stereo output
# Line 56  AudioThread::AudioThread(AudioIO* pAudio Line 58  AudioThread::AudioThread(AudioIO* pAudio
58      }      }
59      pVoicePool->clear();      pVoicePool->clear();
60    
61      // cache initial samples points (for actually needed samples)      pRIFF       = NULL;
62      dmsg(1,("Caching initial samples..."));      pGig        = NULL;
63      gig::Region* pRgn = this->pInstrument->GetFirstRegion();      pInstrument = NULL;
     while (pRgn) {  
         if (!pRgn->GetSample()->GetCache().Size) {  
             dmsg(2,("C"));  
             CacheInitialSamples(pRgn->GetSample());  
         }  
         for (uint i = 0; i < pRgn->DimensionRegions; i++) {  
             CacheInitialSamples(pRgn->pDimensionRegions[i]->pSample);  
         }  
   
         pRgn = this->pInstrument->GetNextRegion();  
     }  
64    
65      // initialize modulation system      // initialize modulation system
66      ModulationSystem::Initialize(pAudioIO->SampleRate(), pAudioIO->MaxSamplesPerCycle());      ModulationSystem::Initialize(pAudioIO->SampleRate(), pAudioIO->MaxSamplesPerCycle());
67        
68        // set all MIDI controller values to zero
69        memset(ControllerTable, 0x00, 128);
70    
71        SuspensionRequested = false;
72        pthread_mutex_init(&__render_state_mutex, NULL);
73        pthread_cond_init(&__render_exit_condition, NULL);
74    
75      // sustain pedal value      dmsg(1,("Starting disk thread..."));
76      PrevHoldCCValue = 0;      pDiskThread->StartThread();
     SustainPedal    = 0;  
   
77      dmsg(1,("OK\n"));      dmsg(1,("OK\n"));
78  }  }
79    
80  AudioThread::~AudioThread() {  AudioThread::~AudioThread() {
81        if (pDiskThread) {
82            pDiskThread->StopThread();
83            delete pDiskThread;
84        }
85        if (pGig)  delete pGig;
86        if (pRIFF) delete pRIFF;
87      ModulationSystem::Close();      ModulationSystem::Close();
88      for (uint i = 0; i < 128; i++) {      for (uint i = 0; i < 128; i++) {
89          if (pMIDIKeyInfo[i].pActiveVoices) delete pMIDIKeyInfo[i].pActiveVoices;          if (pMIDIKeyInfo[i].pActiveVoices) delete pMIDIKeyInfo[i].pActiveVoices;
90            if (pMIDIKeyInfo[i].pEvents)       delete pMIDIKeyInfo[i].pEvents;
91      }      }
92      for (uint i = 0; i < ModulationSystem::destination_count; i++) {      for (uint i = 0; i < ModulationSystem::destination_count; i++) {
93          if (pCCEvents[i]) delete pCCEvents[i];          if (pSynthesisEvents[i]) delete pSynthesisEvents[i];
94      }      }
95      delete[] pCCEvents;      delete[] pSynthesisEvents;
96      if (pEvents)           delete pEvents;      if (pEvents)     delete pEvents;
97      if (pEventQueue)       delete pEventQueue;      if (pCCEvents)   delete pCCEvents;
98      if (pEventPool)        delete pEventPool;      if (pEventQueue) delete pEventQueue;
99      if (pVoicePool)        delete pVoicePool;      if (pEventPool)  delete pEventPool;
100      if (pSustainedKeyPool) delete pSustainedKeyPool;      if (pVoicePool)  delete pVoicePool;
101        if (pActiveKeys) delete pActiveKeys;
102      delete[] pAudioSumBuffer[0]; // this also frees the right channel buffer      delete[] pAudioSumBuffer[0]; // this also frees the right channel buffer
103        pthread_cond_destroy(&__render_exit_condition);
104        pthread_mutex_destroy(&__render_state_mutex);
105  }  }
106    
107  /**  /**
# Line 110  AudioThread::~AudioThread() { Line 116  AudioThread::~AudioThread() {
116   */   */
117  int AudioThread::RenderAudio(uint Samples) {  int AudioThread::RenderAudio(uint Samples) {
118    
119        // zero out the output sum buffer (left and right channel)
120        memset(pAudioSumBuffer[0], 0, Samples * pAudioIO->Channels() * sizeof(float));
121    
122    
123        // check if rendering process was requested to be interrupted (e.g. to load another instrument)
124        if (SuspensionRequested) {
125            pthread_cond_broadcast(&__render_exit_condition); // wake up anybody waiting for us
126            return 0;
127        }
128    
129    
130      // empty the event lists for the new fragment      // empty the event lists for the new fragment
131      pEvents->clear();      pEvents->clear();
132        pCCEvents->clear();
133      for (uint i = 0; i < ModulationSystem::destination_count; i++) {      for (uint i = 0; i < ModulationSystem::destination_count; i++) {
134          pCCEvents[i]->clear();          pSynthesisEvents[i]->clear();
135      }      }
136    
137      // read and copy events from input queue      // read and copy events from input queue
# Line 155  int AudioThread::RenderAudio(uint Sample Line 173  int AudioThread::RenderAudio(uint Sample
173      }      }
174    
175    
     // zero out the output sum buffer (left and right channel)  
     memset(pAudioSumBuffer[0], 0, Samples * pAudioIO->Channels() * sizeof(float));  
   
   
176      // render audio from all active voices      // render audio from all active voices
177      int active_voices = 0;      int active_voices = 0;
178      for (uint i = 0; i < 128; i++) {      uint* piKey = pActiveKeys->first();
179          midi_key_info_t* pKey = &pMIDIKeyInfo[i];      while (piKey) { // iterate through all active keys
180            midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
181            pActiveKeys->set_current(piKey);
182            piKey = pActiveKeys->next();
183    
184          Voice* pVoiceNext = pKey->pActiveVoices->first();          Voice* pVoiceNext = pKey->pActiveVoices->first();
185          while (pVoiceNext) {          while (pVoiceNext) { // iterate through all voices on this key
186              // already get next voice on key              // already get next voice on key
187              Voice* pVoice = pVoiceNext;              Voice* pVoice = pVoiceNext;
188              pKey->pActiveVoices->set_current(pVoice);              pKey->pActiveVoices->set_current(pVoice);
# Line 177  int AudioThread::RenderAudio(uint Sample Line 195  int AudioThread::RenderAudio(uint Sample
195                  KillVoice(pVoice); // remove voice from the list of active voices                  KillVoice(pVoice); // remove voice from the list of active voices
196              }              }
197          }          }
198            pKey->pEvents->clear(); // free all events on the key
199      }      }
200    
201    
202      // write that to the disk thread class so that it can print it      // write that to the disk thread class so that it can print it
203      // on the console for debugging purposes      // on the console for debugging purposes
204      ActiveVoiceCount = active_voices;      ActiveVoiceCount = active_voices;
# Line 259  void AudioThread::ProcessNoteOn(Modulati Line 279  void AudioThread::ProcessNoteOn(Modulati
279      midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Key];      midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Key];
280    
281      pKey->KeyPressed = true; // the MIDI key was now pressed down      pKey->KeyPressed = true; // the MIDI key was now pressed down
282      Voice* pNewVoice = pKey->pActiveVoices->alloc(); // allocate a new voice for the key  
283        // cancel release process of voices on this key if needed
284        if (pKey->Active && !SustainPedal) {
285            pNoteOnEvent->Type = ModulationSystem::event_type_cancel_release; // transform event type
286            pEvents->move(pNoteOnEvent, pKey->pEvents); // move event to the key's own event list
287        }
288    
289        // allocate a new voice for the key
290        Voice* pNewVoice = pKey->pActiveVoices->alloc();
291      if (pNewVoice) {      if (pNewVoice) {
292          // launch the new voice          // launch the new voice
293          if (pNewVoice->Trigger(pNoteOnEvent->Key, pNoteOnEvent->Velocity, this->Pitch, this->pInstrument, pNoteOnEvent->FragmentPos()) < 0) {          if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument) < 0) {
294              return; // failed to trigger the new voice              dmsg(1,("Triggering new voice failed!\n"));
295          }              pKey->pActiveVoices->free(pNewVoice);
296            }
297          // update key info          else if (!pKey->Active) { // mark as active key
298          if (!pKey->pSustainPtr) {              pKey->Active = true;
299              dmsg(4,("ProcessNoteOn(): pSustainPtr == null, setting release pointer to the last voice on the key...\n"));              pKey->pSelf  = pActiveKeys->alloc();
300              pKey->pSustainPtr = pKey->pActiveVoices->last();              *pKey->pSelf = pNoteOnEvent->Key;
301          }          }
302      }      }
303      else std::cerr << "No free voice!" << std::endl << std::flush;      else std::cerr << "No free voice!" << std::endl << std::flush;
# Line 287  void AudioThread::ProcessNoteOff(Modulat Line 315  void AudioThread::ProcessNoteOff(Modulat
315      midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOffEvent->Key];      midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOffEvent->Key];
316    
317      pKey->KeyPressed = false; // the MIDI key was now released      pKey->KeyPressed = false; // the MIDI key was now released
318      if (SustainPedal) { // if sustain pedal is pressed postpone the Note-Off  
319          if (pKey->pSustainPtr) {      // release voices on this key if needed
320              // stick the note-off information to the respective voice      if (pKey->Active && !SustainPedal) {
321              Voice* pVoiceToRelease = pKey->pSustainPtr;          pNoteOffEvent->Type = ModulationSystem::event_type_release; // transform event type
322              pVoiceToRelease->ReleaseVelocity = pNoteOffEvent->Velocity;          pEvents->move(pNoteOffEvent, pKey->pEvents); // move event to the key's own event list
   
             // now increment the sustain pointer  
             pKey->pActiveVoices->set_current(pVoiceToRelease);  
             pKey->pSustainPtr = pKey->pActiveVoices->next();  
   
             // if the key was not marked as sustained yet, add it's MIDI key number to the sustained key pool  
             if (!pKey->Sustained) {  
                 uint* puiSustainedKey  = pSustainedKeyPool->alloc();  
                 *puiSustainedKey       = pNoteOffEvent->Key;  
                 pKey->pSustainPoolNode = puiSustainedKey;  
                 pKey->Sustained        = true;  
             }  
         }  
         else dmsg(3,("Ignoring NOTE OFF, seems like more Note-Offs than Note-Ons or no free voices available?\n"));  
     }  
     else {  
         // release all active voices on the midi key  
         Voice* pVoiceNext = pKey->pActiveVoices->first();  
         while (pVoiceNext) {  
             Voice* pVoiceToRelease = pVoiceNext;  
             pKey->pActiveVoices->set_current(pVoiceToRelease);  
             pVoiceNext = pKey->pActiveVoices->next();  
             pVoiceToRelease->Release(pNoteOffEvent->FragmentPos());  
         }  
323      }      }
324  }  }
325    
326  /**  /**
327   *  Moves pitchbend event from the general (input) event list to the pitch   *  Moves pitchbend event from the general (input) event list to the pitch
328   *  event list and converts absolute pitch value to delta pitch value.   *  event list.
329   *   *
330   *  @param pPitchbendEvent - absolute pitch value and time stamp of the event   *  @param pPitchbendEvent - absolute pitch value and time stamp of the event
331   */   */
332  void AudioThread::ProcessPitchbend(ModulationSystem::Event* pPitchbendEvent) {  void AudioThread::ProcessPitchbend(ModulationSystem::Event* pPitchbendEvent) {
333      int currentPitch        = pPitchbendEvent->Pitch;      this->Pitch = pPitchbendEvent->Pitch; // store current pitch value
334      pPitchbendEvent->Pitch -= this->Pitch;  // convert to delta      pEvents->move(pPitchbendEvent, pSynthesisEvents[ModulationSystem::destination_vco]);
     this->Pitch             = currentPitch; // store current absolute pitch value  
     pEvents->move(pPitchbendEvent, pCCEvents[ModulationSystem::destination_vco]);  
335  }  }
336    
337  /**  /**
338   *  Immediately kills the voice given with pVoice (no matter if sustain is   *  Immediately kills the voice given with pVoice (no matter if sustain is
339   *  pressed or not) and removes it from the MIDI key's list of active voice.   *  pressed or not) and removes it from the MIDI key's list of active voice.
340   *  This method will e.g. be called if a voice went inactive by itself. If   *  This method will e.g. be called if a voice went inactive by itself.
  *  sustain pedal is pressed the method takes care to free those sustain  
  *  informations of the voice.  
341   *   *
342   *  @param pVoice - points to the voice to be killed   *  @param pVoice - points to the voice to be killed
343   */   */
# Line 347  void AudioThread::KillVoice(Voice* pVoic Line 347  void AudioThread::KillVoice(Voice* pVoic
347    
348          midi_key_info_t* pKey = &pMIDIKeyInfo[pVoice->MIDIKey];          midi_key_info_t* pKey = &pMIDIKeyInfo[pVoice->MIDIKey];
349    
         if (pKey->Sustained) {  
             // check if the sustain pointer has to be moved, now that we kill the voice  
             if (pKey->pSustainPtr) {  
                 if (pKey->pSustainPtr == pVoice) {  
                     // move sustain pointer to the next sustained voice  
                     dmsg(3,("Correcting sustain pointer\n"));  
                     pKey->pActiveVoices->set_current(pVoice);  
                     pKey->pSustainPtr = pKey->pActiveVoices->next();  
                 }  
                 else dmsg(4,("KillVoice(Voice*): pSustainPtr != pVoice\n"));  
             }  
             else dmsg(3,("KillVoice(Voice*): pSustainPtr == null\n"));  
         }  
   
350          // free the voice object          // free the voice object
351          pVoicePool->free(pVoice);          pVoicePool->free(pVoice);
352    
353          // check if there are no voices left on the MIDI key and update the key info if so          // check if there are no voices left on the MIDI key and update the key info if so
354          if (pKey->pActiveVoices->is_empty()) {          if (pKey->pActiveVoices->is_empty()) {
355              pKey->pSustainPtr = NULL;              pKey->Active = false;
356              if (pKey->Sustained) {              pActiveKeys->free(pKey->pSelf); // remove key from list of active keys
357                  pSustainedKeyPool->free(pKey->pSustainPoolNode);              pKey->pSelf = NULL;
                 pKey->pSustainPoolNode = NULL;  
                 pKey->Sustained        = false;  
             }  
358              dmsg(3,("Key has no more voices now\n"));              dmsg(3,("Key has no more voices now\n"));
359          }          }
360      }      }
# Line 389  void AudioThread::ProcessControlChange(M Line 372  void AudioThread::ProcessControlChange(M
372    
373      switch (pControlChangeEvent->Controller) {      switch (pControlChangeEvent->Controller) {
374          case 64: {          case 64: {
375              if (pControlChangeEvent->Value >= 64 && PrevHoldCCValue < 64) {              if (pControlChangeEvent->Value >= 64 && !SustainPedal) {
376                  dmsg(4,("PEDAL DOWN\n"));                  dmsg(4,("PEDAL DOWN\n"));
377                  SustainPedal = true;                  SustainPedal = true;
378    
379                    // cancel release process of voices if necessary
380                    uint* piKey = pActiveKeys->first();
381                    if (piKey) {
382                        pControlChangeEvent->Type = ModulationSystem::event_type_cancel_release; // transform event type
383                        while (piKey) {
384                            midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
385                            pActiveKeys->set_current(piKey);
386                            piKey = pActiveKeys->next();
387                            if (!pKey->KeyPressed) {
388                                ModulationSystem::Event* pNewEvent = pKey->pEvents->alloc();
389                                if (pNewEvent) *pNewEvent = *pControlChangeEvent; // copy event to the key's own event list
390                                else dmsg(1,("Event pool emtpy!\n"));
391                            }
392                        }
393                    }
394              }              }
395              if (pControlChangeEvent->Value < 64 && PrevHoldCCValue >= 64) {              if (pControlChangeEvent->Value < 64 && SustainPedal) {
396                  dmsg(4,("PEDAL UP\n"));                  dmsg(4,("PEDAL UP\n"));
397                  SustainPedal = false;                  SustainPedal = false;
398                  // iterate through all keys that are currently sustained  
399                  for (uint* key = pSustainedKeyPool->first(); key; key = pSustainedKeyPool->next()) {                  // release voices if their respective key is not pressed
400                      if (!pMIDIKeyInfo[*key].KeyPressed) { // release the voices on the key, if the key is not pressed anymore                  uint* piKey = pActiveKeys->first();
401                          // release all active voices on the midi key                  if (piKey) {
402                          Voice* pNextVoice = pMIDIKeyInfo[*key].pActiveVoices->first();                      pControlChangeEvent->Type = ModulationSystem::event_type_release; // transform event type
403                          while (pNextVoice) {                      while (piKey) {
404                              Voice* pVoiceToRelease = pNextVoice;                          midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
405                              pMIDIKeyInfo[*key].pActiveVoices->set_current(pVoiceToRelease);                          pActiveKeys->set_current(piKey);
406                              pNextVoice = pMIDIKeyInfo[*key].pActiveVoices->next();                          piKey = pActiveKeys->next();
407                              dmsg(3,("Sustain CC: releasing voice on midi key %d\n", *key));                          if (!pKey->KeyPressed) {
408                              pVoiceToRelease->Release(pControlChangeEvent->FragmentPos());                              ModulationSystem::Event* pNewEvent = pKey->pEvents->alloc();
409                                if (pNewEvent) *pNewEvent = *pControlChangeEvent; // copy event to the key's own event list
410                                else dmsg(1,("Event pool emtpy!\n"));
411                          }                          }
                         pSustainedKeyPool->free(pMIDIKeyInfo[*key].pSustainPoolNode);  
                         pMIDIKeyInfo[*key].pSustainPoolNode = NULL;  
                         pMIDIKeyInfo[*key].Sustained        = false;  
                         pMIDIKeyInfo[*key].pSustainPtr      = NULL;  
412                      }                      }
413                  }                  }
                 //SustainedKeyPool->empty();  
414              }              }
             PrevHoldCCValue = pControlChangeEvent->Value;  
415              break;              break;
416          }          }
417      }      }
418        
419        // update controller value in the engine's controller table
420        ControllerTable[pControlChangeEvent->Controller] = pControlChangeEvent->Value;
421        
422        // move event from the unsorted event list to the control change event list
423        pEvents->move(pControlChangeEvent, pCCEvents);
424  }  }
425    
426  /**  /**
# Line 447  void AudioThread::CacheInitialSamples(gi Line 448  void AudioThread::CacheInitialSamples(gi
448    
449      if (!pSample->GetCache().Size) std::cerr << "Unable to cache sample - maybe memory full!" << std::endl << std::flush;      if (!pSample->GetCache().Size) std::cerr << "Unable to cache sample - maybe memory full!" << std::endl << std::flush;
450  }  }
451    
452    /**
453     *  Load an instrument from a .gig file.
454     *
455     *  @param FileName   - file name of the Gigasampler instrument file
456     *  @param Instrument - index of the instrument in the .gig file
457     *  @returns          detailed description of the result of the method call
458     */
459    result_t AudioThread::LoadInstrument(const char* FileName, uint Instrument) {
460        result_t result;
461    
462        if (pInstrument) { // if already running
463            // signal audio thread not to enter render part anymore
464            SuspensionRequested = true;
465            // sleep until wakened by audio thread
466            pthread_mutex_lock(&__render_state_mutex);
467            pthread_cond_wait(&__render_exit_condition, &__render_state_mutex);
468            pthread_mutex_unlock(&__render_state_mutex);
469    
470            dmsg(1,("Freeing old instrument from memory..."));
471            delete pGig;
472            delete pRIFF;
473            pInstrument = NULL;
474            dmsg(1,("OK\n"));
475        }
476    
477        // loading gig file
478        try {
479            dmsg(1,("Loading gig file..."));
480            pRIFF       = new RIFF::File(FileName);
481            pGig        = new gig::File(pRIFF);
482            pInstrument = pGig->GetInstrument(Instrument);
483            if (!pInstrument) {
484                std::stringstream msg;
485                msg << "There's no instrument with index " << Instrument << ".";
486                std::cerr << msg << std::endl;
487                result.type    = result_type_error;
488                result.code    = LSCP_ERR_UNKNOWN;
489                result.message = msg.str();
490                return result;
491            }
492            pGig->GetFirstSample(); // just to complete instrument loading before we enter the realtime part
493            dmsg(1,("OK\n"));
494        }
495        catch (RIFF::Exception e) {
496            e.PrintMessage();
497            result.type    = result_type_error;
498            result.code    = LSCP_ERR_UNKNOWN;
499            result.message = e.Message;
500            return result;
501        }
502        catch (...) {
503            dmsg(1,("Unknown exception while trying to parse gig file.\n"));
504            result.type    = result_type_error;
505            result.code    = LSCP_ERR_UNKNOWN;
506            result.message = "Unknown exception while trying to parse gig file.";
507            return result;
508        }
509    
510        // cache initial samples points (for actually needed samples)
511        dmsg(1,("Caching initial samples..."));
512        gig::Region* pRgn = this->pInstrument->GetFirstRegion();
513        while (pRgn) {
514            if (!pRgn->GetSample()->GetCache().Size) {
515                dmsg(2,("C"));
516                CacheInitialSamples(pRgn->GetSample());
517            }
518            for (uint i = 0; i < pRgn->DimensionRegions; i++) {
519                CacheInitialSamples(pRgn->pDimensionRegions[i]->pSample);
520            }
521    
522            pRgn = this->pInstrument->GetNextRegion();
523        }
524        dmsg(1,("OK\n"));
525    
526        ResetInternal(); // reset engine
527    
528        // signal audio thread to continue with rendering
529        SuspensionRequested = false;
530    
531        // success
532        result.type = result_type_success;
533        return result;
534    }
535    
536    /**
537     *  Reset all voices and disk thread and clear input event queue and all
538     *  control and status variables.
539     */
540    void AudioThread::Reset() {
541        if (pInstrument) { // if already running
542            // signal audio thread not to enter render part anymore
543            SuspensionRequested = true;
544            // sleep until wakened by audio thread
545            pthread_mutex_lock(&__render_state_mutex);
546            pthread_cond_wait(&__render_exit_condition, &__render_state_mutex);
547            pthread_mutex_unlock(&__render_state_mutex);
548        }
549    
550        ResetInternal();
551    
552        // signal audio thread to continue with rendering
553        SuspensionRequested = false;
554    }
555    
556    /**
557     *  Reset all voices and disk thread and clear input event queue and all
558     *  control and status variables. This method is not thread safe!
559     */
560    void AudioThread::ResetInternal() {
561        this->Pitch         = 0;
562        SustainPedal        = 0;
563        ActiveVoiceCount    = 0;
564        ActiveVoiceCountMax = 0;
565    
566        // reset key info
567        for (uint i = 0; i < 128; i++) {
568            pMIDIKeyInfo[i].pActiveVoices->clear();
569            pMIDIKeyInfo[i].pEvents->clear();
570            pMIDIKeyInfo[i].KeyPressed = false;
571            pMIDIKeyInfo[i].Active     = false;
572            pMIDIKeyInfo[i].pSelf      = NULL;
573        }
574    
575        // reset all voices
576        for (Voice* pVoice = pVoicePool->first(); pVoice; pVoice = pVoicePool->next()) {
577            pVoice->Reset();
578        }
579    
580        // free all active keys
581        pActiveKeys->clear();
582    
583        // reset disk thread
584        pDiskThread->Reset();
585    
586        // delete all input events
587        pEventQueue->init();
588    }

Legend:
Removed from v.32  
changed lines
  Added in v.40

  ViewVC Help
Powered by ViewVC