/[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 14 by schoenebeck, Fri Nov 21 15:40:40 2003 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) : Thread(true, 1, 0) {  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      pCommandQueue     = new RingBuffer<command_t>(1024);      this->Pitch        = 0;
30      pVoices           = new Voice*[MAX_AUDIO_VOICES];      this->SustainPedal = 0;
31      // allocate the ActiveVoicePool (for each midi key there is a variable size linked list      Voice::pDiskThread = this->pDiskThread;
32      // of pointers to Voice objects)      Voice::pEngine     = this;
33      ActiveVoicePool = new RTELMemoryPool<Voice*>(MAX_AUDIO_VOICES);      pEventQueue        = new RingBuffer<ModulationSystem::Event>(MAX_EVENTS_PER_FRAGMENT);
34      for (uint i = 0; i < MAX_AUDIO_VOICES; i++) {      pEventPool         = new RTELMemoryPool<ModulationSystem::Event>(MAX_EVENTS_PER_FRAGMENT);
35          pVoices[i] = new Voice(pDiskThread);      pVoicePool         = new RTELMemoryPool<Voice>(MAX_AUDIO_VOICES);
36        pActiveKeys        = new RTELMemoryPool<uint>(128);
37        pEvents            = new RTEList<ModulationSystem::Event>(pEventPool);
38        pCCEvents          = new RTEList<ModulationSystem::Event>(pEventPool);
39        for (uint i = 0; i < ModulationSystem::destination_count; i++) {
40            pSynthesisEvents[i] = new RTEList<ModulationSystem::Event>(pEventPool);
41      }      }
42      for (uint i = 0; i < 128; i++) {      for (uint i = 0; i < 128; i++) {
43          pActiveVoices[i] = new RTEList<Voice*>;          pMIDIKeyInfo[i].pActiveVoices = new RTEList<Voice>(pVoicePool);
44            pMIDIKeyInfo[i].KeyPressed    = false;
45            pMIDIKeyInfo[i].Active        = false;
46            pMIDIKeyInfo[i].pSelf         = NULL;
47            pMIDIKeyInfo[i].pEvents       = new RTEList<ModulationSystem::Event>(pEventPool);
48      }      }
     SustainedKeyPool = new RTELMemoryPool<sustained_key_t>(MAX_AUDIO_VOICES);  
49    
50      pAudioSumBuffer = new float[pAudioIO->FragmentSize * pAudioIO->Channels];      // FIXME: assuming stereo output
51        pAudioSumBuffer[0] = new float[pAudioIO->MaxSamplesPerCycle() * pAudioIO->Channels()];
52        pAudioSumBuffer[1] = &pAudioSumBuffer[0][pAudioIO->MaxSamplesPerCycle()];
53    
54      // set all voice outputs to the AudioSumBuffer      // set all voice outputs to the AudioSumBuffer
55      for (int i = 0; i < MAX_AUDIO_VOICES; i++) {      for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) { //FIXME: assuming stereo
56          pVoices[i]->SetOutput(pAudioSumBuffer, pAudioIO->FragmentSize * 2);  //FIXME: assuming stereo          pVoice->SetOutputLeft(pAudioSumBuffer[0],  pAudioIO->MaxSamplesPerCycle());
57      }          pVoice->SetOutputRight(pAudioSumBuffer[1], pAudioIO->MaxSamplesPerCycle());
58        }
59      // cache initial samples points (for actually needed samples)      pVoicePool->clear();
60      dmsg(1,("Caching initial samples..."));  
61      gig::Region* pRgn = this->pInstrument->GetFirstRegion();      pRIFF       = NULL;
62      while (pRgn) {      pGig        = NULL;
63          if (!pRgn->GetSample()->GetCache().Size) {      pInstrument = NULL;
64              dmsg(2,("C"));  
65              CacheInitialSamples(pRgn->GetSample());      // initialize modulation system
66          }      ModulationSystem::Initialize(pAudioIO->SampleRate(), pAudioIO->MaxSamplesPerCycle());
67          for (uint i = 0; i < pRgn->DimensionRegions; i++) {      
68              CacheInitialSamples(pRgn->pDimensionRegions[i]->pSample);      // set all MIDI controller values to zero
69          }      memset(ControllerTable, 0x00, 128);
70    
71          pRgn = this->pInstrument->GetNextRegion();      SuspensionRequested = false;
72      }      pthread_mutex_init(&__render_state_mutex, NULL);
73        pthread_cond_init(&__render_exit_condition, NULL);
     // sustain pedal value  
     PrevHoldCCValue = 0;  
     SustainPedal    = 0;  
74    
75        dmsg(1,("Starting disk thread..."));
76        pDiskThread->StartThread();
77      dmsg(1,("OK\n"));      dmsg(1,("OK\n"));
78  }  }
79    
80  AudioThread::~AudioThread() {  AudioThread::~AudioThread() {
81      if (pCommandQueue) delete pCommandQueue;      if (pDiskThread) {
82      if (pVoices) {          pDiskThread->StopThread();
83          for (uint i = 0; i < MAX_AUDIO_VOICES; i++) {          delete pDiskThread;
84              if (pVoices[i]) delete pVoices[i];      }
85          }      if (pGig)  delete pGig;
86        if (pRIFF) delete pRIFF;
87        ModulationSystem::Close();
88        for (uint i = 0; i < 128; i++) {
89            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++) {
93            if (pSynthesisEvents[i]) delete pSynthesisEvents[i];
94        }
95        delete[] pSynthesisEvents;
96        if (pEvents)     delete pEvents;
97        if (pCCEvents)   delete pCCEvents;
98        if (pEventQueue) delete pEventQueue;
99        if (pEventPool)  delete pEventPool;
100        if (pVoicePool)  delete pVoicePool;
101        if (pActiveKeys) delete pActiveKeys;
102        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    /**
108     *  Let this engine proceed to render the given amount of sample points. The
109     *  calculated audio data of all voices of this engine will be placed into
110     *  the engine's audio sum buffer which has to be copied and eventually be
111     *  converted to the appropriate value range by the audio output class (e.g.
112     *  AlsaIO or JackIO) right after.
113     *
114     *  @param Samples - number of sample points to be rendered
115     *  @returns       0 on success
116     */
117    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      }      }
     delete[] pVoices;  
 }  
128    
 int AudioThread::Main() {  
     dmsg(2,("Audio thread running\n"));  
129    
130      while (true) {      // empty the event lists for the new fragment
131        pEvents->clear();
132        pCCEvents->clear();
133        for (uint i = 0; i < ModulationSystem::destination_count; i++) {
134            pSynthesisEvents[i]->clear();
135        }
136    
137          // read and process commands from the queue      // read and copy events from input queue
138          while (true) {      ModulationSystem::Event Event;
139              command_t command;      while (true) {
140              if (pCommandQueue->read(&command, 1) == 0) break;          if (!pEventQueue->pop(&Event)) break;
141            pEvents->alloc_assign(Event);
142              switch (command.type) {      }
                 case command_type_note_on:  
                     dmsg(5,("Audio Thread: Note on received\n"));  
                     ActivateVoice(command.pitch, command.velocity);  
                     break;  
                 case command_type_note_off:  
                     dmsg(5,("Audio Thread: Note off received\n"));  
                     ReleaseVoice(command.pitch, command.velocity);  
                     break;  
                 case command_type_continuous_controller:  
                     dmsg(5,("Audio Thread: MIDI CC received\n"));  
                     ContinuousController(command.channel, command.number, command.value);  
                     break;  
             }  
         }  
143    
144    
145          // zero out the sum buffer      // update time of start and end of this audio fragment (as events' time stamps relate to this)
146          for (uint u = 0; u < pAudioIO->FragmentSize * pAudioIO->Channels; u++) {      ModulationSystem::UpdateFragmentTime();
             pAudioSumBuffer[u] = 0.0;  
         }  
147    
148    
149          // render audio from all active voices      // process events
150          int active_voices = 0;      ModulationSystem::Event* pNextEvent = pEvents->first();
151          for (uint i = 0; i < MAX_AUDIO_VOICES; i++) {      while (pNextEvent) {
152              if (pVoices[i]->IsActive()) {          ModulationSystem::Event* pEvent = pNextEvent;
153                  pVoices[i]->RenderAudio();          pEvents->set_current(pEvent);
154                  if (pVoices[i]->IsActive()) active_voices++; // still active          pNextEvent = pEvents->next();
155                  else { // voice reached end, is now inactive          switch (pEvent->Type) {
156                      ReleaseVoice(pVoices[i]); // remove voice from the list of active voices              case ModulationSystem::event_type_note_on:
157                  }                  dmsg(5,("Audio Thread: Note on received\n"));
158              }                  ProcessNoteOn(pEvent);
159                    break;
160                case ModulationSystem::event_type_note_off:
161                    dmsg(5,("Audio Thread: Note off received\n"));
162                    ProcessNoteOff(pEvent);
163                    break;
164                case ModulationSystem::event_type_control_change:
165                    dmsg(5,("Audio Thread: MIDI CC received\n"));
166                    ProcessControlChange(pEvent);
167                    break;
168                case ModulationSystem::event_type_pitchbend:
169                    dmsg(5,("Audio Thread: Pitchbend received\n"));
170                    ProcessPitchbend(pEvent);
171                    break;
172          }          }
173          // write that to the disk thread class so that it can print it      }
         // on the console for debugging purposes  
         ActiveVoiceCount = active_voices;  
         if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;  
174    
175    
176          // check clipping in the audio sum, convert to sample_type      // render audio from all active voices
177          // (from 32bit to 16bit sample) and copy to output buffer      int active_voices = 0;
178          float sample_point;      uint* piKey = pActiveKeys->first();
179          for (uint u = 0; u < pAudioIO->FragmentSize * pAudioIO->Channels; u++) {      while (piKey) { // iterate through all active keys
180              sample_point = this->pAudioSumBuffer[u] / 4; // FIXME division by 4 just for testing purposes (to give a bit of head room when mixing multiple voices together)          midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
181              if (sample_point < -32768.0) sample_point = -32768.0;          pActiveKeys->set_current(piKey);
182              if (sample_point > 32767.0)  sample_point = 32767.0;          piKey = pActiveKeys->next();
183              this->pAudioIO->pOutputBuffer[u] = (sample_t) sample_point;  
184            Voice* pVoiceNext = pKey->pActiveVoices->first();
185            while (pVoiceNext) { // iterate through all voices on this key
186                // already get next voice on key
187                Voice* pVoice = pVoiceNext;
188                pKey->pActiveVoices->set_current(pVoice);
189                pVoiceNext = pKey->pActiveVoices->next();
190    
191                // now render current voice
192                pVoice->Render(Samples);
193                if (pVoice->IsActive()) active_voices++; // still active
194                else { // voice reached end, is now inactive
195                    KillVoice(pVoice); // remove voice from the list of active voices
196                }
197          }          }
198            pKey->pEvents->clear(); // free all events on the key
   
         // call audio driver to output sound  
         int res = this->pAudioIO->Output();  
         if (res < 0) exit(EXIT_FAILURE);  
199      }      }
 }  
   
 /// Will be called by the MIDIIn Thread to let the audio thread trigger a new voice.  
 void AudioThread::ProcessNoteOn(uint8_t Pitch, uint8_t Velocity) {  
     command_t cmd;  
     cmd.type     = command_type_note_on;  
     cmd.pitch    = Pitch;  
     cmd.velocity = Velocity;  
     this->pCommandQueue->write(&cmd, 1);  
 }  
200    
 /// Will be called by the MIDIIn Thread to signal the audio thread to release a voice.  
 void AudioThread::ProcessNoteOff(uint8_t Pitch, uint8_t Velocity) {  
     command_t cmd;  
     cmd.type     = command_type_note_off;  
     cmd.pitch    = Pitch;  
     cmd.velocity = Velocity;  
     this->pCommandQueue->write(&cmd, 1);  
 }  
201    
202  // Will be called by the MIDIIn Thead to send MIDI continuos controller events      // write that to the disk thread class so that it can print it
203  void AudioThread::ProcessContinuousController(uint8_t Channel, uint8_t Number, uint8_t Value) {      // on the console for debugging purposes
204      command_t cmd;      ActiveVoiceCount = active_voices;
205      cmd.type     = command_type_continuous_controller;      if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;
206      cmd.channel  = Channel;  
207      cmd.number   = Number;  
208      cmd.value    = Value;      return 0;
209      this->pCommandQueue->write(&cmd, 1);  }
210  }  
211    /**
212  void AudioThread::ActivateVoice(uint8_t MIDIKey, uint8_t Velocity) {   *  Will be called by the MIDIIn Thread to let the audio thread trigger a new
213      for (int i = 0; i < MAX_AUDIO_VOICES; i++) {   *  voice for the given key.
214          if (pVoices[i]->IsActive()) continue;   *
215          pVoices[i]->Trigger(MIDIKey, Velocity, this->pInstrument);   *  @param Key      - MIDI key number of the triggered key
216          // add (append) a new voice to the corresponding MIDIKey active voices list   *  @param Velocity - MIDI velocity value of the triggered key
217          Voice** new_voice_ptr = ActiveVoicePool->alloc_append(pActiveVoices[MIDIKey]);   */
218          *new_voice_ptr = pVoices[i];  void AudioThread::SendNoteOn(uint8_t Key, uint8_t Velocity) {
219          pVoices[i]->pSelfPtr = new_voice_ptr; // FIXME: hack to allow fast deallocation      ModulationSystem::Event Event;
220          return;      Event.Type       = ModulationSystem::event_type_note_on;
221        Event.Key        = Key;
222        Event.Velocity   = Velocity;
223        if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
224        else dmsg(1,("AudioThread: Input event queue full!"));
225    }
226    
227    /**
228     *  Will be called by the MIDIIn Thread to signal the audio thread to release
229     *  voice(s) on the given key.
230     *
231     *  @param Key      - MIDI key number of the released key
232     *  @param Velocity - MIDI release velocity value of the released key
233     */
234    void AudioThread::SendNoteOff(uint8_t Key, uint8_t Velocity) {
235        ModulationSystem::Event Event;
236        Event.Type       = ModulationSystem::event_type_note_off;
237        Event.Key        = Key;
238        Event.Velocity   = Velocity;
239        if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
240        else dmsg(1,("AudioThread: Input event queue full!"));
241    }
242    
243    /**
244     *  Will be called by the MIDIIn Thread to signal the audio thread to change
245     *  the pitch value for all voices.
246     *
247     *  @param Pitch - MIDI pitch value (-8192 ... +8191)
248     */
249    void AudioThread::SendPitchbend(int Pitch) {
250        ModulationSystem::Event Event;
251        Event.Type  = ModulationSystem::event_type_pitchbend;
252        Event.Pitch = Pitch;
253        if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
254        else dmsg(1,("AudioThread: Input event queue full!"));
255    }
256    
257    /**
258     *  Will be called by the MIDIIn Thread to signal the audio thread that a
259     *  continuous controller value has changed.
260     *
261     *  @param Controller - MIDI controller number of the occured control change
262     *  @param Value      - value of the control change
263     */
264    void AudioThread::SendControlChange(uint8_t Controller, uint8_t Value) {
265        ModulationSystem::Event Event;
266        Event.Type       = ModulationSystem::event_type_control_change;
267        Event.Controller = Controller;
268        Event.Value      = Value;
269        if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
270        else dmsg(1,("AudioThread: Input event queue full!"));
271    }
272    
273    /**
274     *  Assigns and triggers a new voice for the respective MIDI key.
275     *
276     *  @param pNoteOnEvent - key, velocity and time stamp of the event
277     */
278    void AudioThread::ProcessNoteOn(ModulationSystem::Event* pNoteOnEvent) {
279        midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Key];
280    
281        pKey->KeyPressed = true; // the MIDI key was now pressed down
282    
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) {
292            // launch the new voice
293            if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument) < 0) {
294                dmsg(1,("Triggering new voice failed!\n"));
295                pKey->pActiveVoices->free(pNewVoice);
296            }
297            else if (!pKey->Active) { // mark as active key
298                pKey->Active = true;
299                pKey->pSelf  = pActiveKeys->alloc();
300                *pKey->pSelf = pNoteOnEvent->Key;
301            }
302      }      }
303      std::cerr << "No free voice!" << std::endl << std::flush;      else std::cerr << "No free voice!" << std::endl << std::flush;
304  }  }
305    
306  void AudioThread::ReleaseVoice(uint8_t MIDIKey, uint8_t Velocity) {  /**
307      // if sustain pedal is pressed postpone the Note-Off   *  Releases the voices on the given key if sustain pedal is not pressed.
308      if (SustainPedal) {   *  If sustain is pressed, the release of the note will be postponed until
309          // alloc an element in the SustainedKeyPool and add the current midikey to it   *  sustain pedal will be released or voice turned inactive by itself (e.g.
310          sustained_key_t* key = SustainedKeyPool->alloc();   *  due to completion of sample playback).
311          if (key == NULL) printf("ERROR: SustainedKeyPool FULL ! exiting\n"); // FIXME   *
312          key->midikey  = MIDIKey;   *  @param pNoteOffEvent - key, velocity and time stamp of the event
313          key->velocity = Velocity;   */
314      }  void AudioThread::ProcessNoteOff(ModulationSystem::Event* pNoteOffEvent) {
315      else {      midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOffEvent->Key];
316          // get the first voice in the list of active voices on the MIDI Key  
317          Voice** pVoicePtr = pActiveVoices[MIDIKey]->first();      pKey->KeyPressed = false; // the MIDI key was now released
318          if (pVoicePtr) ReleaseVoice(*pVoicePtr);  
319          else std::cerr << "Couldn't find active voice for note off command!" << std::endl << std::flush;      // release voices on this key if needed
320        if (pKey->Active && !SustainPedal) {
321            pNoteOffEvent->Type = ModulationSystem::event_type_release; // transform event type
322            pEvents->move(pNoteOffEvent, pKey->pEvents); // move event to the key's own event list
323      }      }
324  }  }
325    
326  void AudioThread::ReleaseVoice(Voice* pVoice) {  /**
327     *  Moves pitchbend event from the general (input) event list to the pitch
328     *  event list.
329     *
330     *  @param pPitchbendEvent - absolute pitch value and time stamp of the event
331     */
332    void AudioThread::ProcessPitchbend(ModulationSystem::Event* pPitchbendEvent) {
333        this->Pitch = pPitchbendEvent->Pitch; // store current pitch value
334        pEvents->move(pPitchbendEvent, pSynthesisEvents[ModulationSystem::destination_vco]);
335    }
336    
337    /**
338     *  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.
340     *  This method will e.g. be called if a voice went inactive by itself.
341     *
342     *  @param pVoice - points to the voice to be killed
343     */
344    void AudioThread::KillVoice(Voice* pVoice) {
345      if (pVoice) {      if (pVoice) {
346          if (pVoice->IsActive()) pVoice->Kill(); //TODO: for now we're rude and just kill the poor, poor voice immediately :), later we add a Release() method to the Voice class and call it here to let the voice go through it's release phase          if (pVoice->IsActive()) pVoice->Kill();
347    
348            midi_key_info_t* pKey = &pMIDIKeyInfo[pVoice->MIDIKey];
349    
350          // remove the voice from the list associated to this MIDI key          // free the voice object
351          ActiveVoicePool->free(pVoice->pSelfPtr);          pVoicePool->free(pVoice);
352    
353            // check if there are no voices left on the MIDI key and update the key info if so
354            if (pKey->pActiveVoices->is_empty()) {
355                pKey->Active = false;
356                pActiveKeys->free(pKey->pSelf); // remove key from list of active keys
357                pKey->pSelf = NULL;
358                dmsg(3,("Key has no more voices now\n"));
359            }
360      }      }
361      else std::cerr << "Couldn't find active voice to release!" << std::endl << std::flush;      else std::cerr << "Couldn't release voice! (pVoice == NULL)\n" << std::flush;
362  }  }
363    
364  void AudioThread::ContinuousController(uint8_t Channel, uint8_t Number, uint8_t Value) {  /**
365      dmsg(4,("AudioThread::ContinuousController c=%d n=%d v=%d\n", Channel, Number, Value));   *  Reacts on supported control change commands (e.g. pitch bend wheel,
366      if (Number == 64) {   *  modulation wheel, aftertouch).
367          if (Value >= 64 && PrevHoldCCValue < 64) {   *
368              dmsg(4,("PEDAL DOWN\n"));   *  @param pControlChangeEvent - controller, value and time stamp of the event
369              SustainPedal = true;   */
370          }  void AudioThread::ProcessControlChange(ModulationSystem::Event* pControlChangeEvent) {
371          if (Value < 64 && PrevHoldCCValue >= 64) {      dmsg(4,("AudioThread::ContinuousController cc=%d v=%d\n", pControlChangeEvent->Controller, pControlChangeEvent->Value));
372              dmsg(4,("PEDAL UP\n"));  
373              SustainPedal = false;      switch (pControlChangeEvent->Controller) {
374              for (sustained_key_t* key = SustainedKeyPool->first(); key; key = SustainedKeyPool->next()) {          case 64: {
375                  ReleaseVoice(key->midikey, key->velocity);              if (pControlChangeEvent->Value >= 64 && !SustainPedal) {
376                    dmsg(4,("PEDAL DOWN\n"));
377                    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              // empty the SustainedKeyPool (free all the elements)              if (pControlChangeEvent->Value < 64 && SustainPedal) {
396              SustainedKeyPool->empty();                  dmsg(4,("PEDAL UP\n"));
397                    SustainPedal = false;
398    
399                    // release voices if their respective key is not pressed
400                    uint* piKey = pActiveKeys->first();
401                    if (piKey) {
402                        pControlChangeEvent->Type = ModulationSystem::event_type_release; // transform event type
403                        while (piKey) {
404                            midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
405                            pActiveKeys->set_current(piKey);
406                            piKey = pActiveKeys->next();
407                            if (!pKey->KeyPressed) {
408                                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                            }
412                        }
413                    }
414                }
415                break;
416          }          }
         PrevHoldCCValue = Value;  
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    /**
427     *  Caches a certain size at the beginning of the given sample in RAM. If the
428     *  sample is very short, the whole sample will be loaded into RAM and thus
429     *  no disk streaming is needed for this sample. Caching an initial part of
430     *  samples is needed to compensate disk reading latency.
431     *
432     *  @param pSample - points to the sample to be cached
433     */
434  void AudioThread::CacheInitialSamples(gig::Sample* pSample) {  void AudioThread::CacheInitialSamples(gig::Sample* pSample) {
435      if (!pSample || pSample->GetCache().Size) return;      if (!pSample || pSample->GetCache().Size) return;
436      if (pSample->SamplesTotal <= NUM_RAM_PRELOAD_SAMPLES) {      if (pSample->SamplesTotal <= NUM_RAM_PRELOAD_SAMPLES) {
# Line 241  void AudioThread::CacheInitialSamples(gi Line 439  void AudioThread::CacheInitialSamples(gi
439          // number of '0' samples (silence samples) behind the official buffer          // number of '0' samples (silence samples) behind the official buffer
440          // border, to allow the interpolator do it's work even at the end of          // border, to allow the interpolator do it's work even at the end of
441          // the sample.          // the sample.
442          gig::buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension(pAudioIO->FragmentSize << MAX_PITCH);          gig::buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension((pAudioIO->MaxSamplesPerCycle() << MAX_PITCH) + 3);
443          dmsg(4,("Cached %d Bytes, %d silence bytes.\n", buf.Size, buf.NullExtensionSize));          dmsg(4,("Cached %d Bytes, %d silence bytes.\n", buf.Size, buf.NullExtensionSize));
444      }      }
445      else { // we only cache NUM_RAM_PRELOAD_SAMPLES and stream the other sample points from disk      else { // we only cache NUM_RAM_PRELOAD_SAMPLES and stream the other sample points from disk
# Line 250  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.14  
changed lines
  Added in v.40

  ViewVC Help
Powered by ViewVC