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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 40 - (hide annotations) (download)
Tue Mar 30 13:14:58 2004 UTC (20 years, 1 month ago) by schoenebeck
File size: 23236 byte(s)
* added Envelope Generator 2 and 3 (filter cutoff EG and pitch EG) for
  accurate .gig playback
* fixed accuracy of pitch calculation
* changed filter cutoff range to 100Hz..10kHz with exponential curve, this
  value range can also be adjusted on compile time by setting
  FILTER_CUTOFF_MIN and FILTER_CUTOFF_MAX in src/voice.h to desired
  frequencies
* src/lfo.h: lfo is now generalized to a C++ template, which will be useful
  especially when we implement further engines

1 schoenebeck 9 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck *
6     * *
7     * This program is free software; you can redistribute it and/or modify *
8     * it under the terms of the GNU General Public License as published by *
9     * the Free Software Foundation; either version 2 of the License, or *
10     * (at your option) any later version. *
11     * *
12     * This program is distributed in the hope that it will be useful, *
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15     * GNU General Public License for more details. *
16     * *
17     * You should have received a copy of the GNU General Public License *
18     * along with this program; if not, write to the Free Software *
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20     * MA 02111-1307 USA *
21     ***************************************************************************/
22    
23     #include "audiothread.h"
24    
25 schoenebeck 35 AudioThread::AudioThread(AudioIO* pAudioIO) {
26 schoenebeck 32 this->pAudioIO = pAudioIO;
27 schoenebeck 35 this->pDiskThread = new DiskThread(((pAudioIO->MaxSamplesPerCycle() << MAX_PITCH) << 1) + 6); //FIXME: assuming stereo
28     this->pInstrument = NULL;
29 schoenebeck 32 this->Pitch = 0;
30 schoenebeck 37 this->SustainPedal = 0;
31 schoenebeck 35 Voice::pDiskThread = this->pDiskThread;
32 schoenebeck 32 Voice::pEngine = this;
33     pEventQueue = new RingBuffer<ModulationSystem::Event>(MAX_EVENTS_PER_FRAGMENT);
34     pEventPool = new RTELMemoryPool<ModulationSystem::Event>(MAX_EVENTS_PER_FRAGMENT);
35     pVoicePool = new RTELMemoryPool<Voice>(MAX_AUDIO_VOICES);
36 schoenebeck 33 pActiveKeys = new RTELMemoryPool<uint>(128);
37 schoenebeck 32 pEvents = new RTEList<ModulationSystem::Event>(pEventPool);
38 schoenebeck 37 pCCEvents = new RTEList<ModulationSystem::Event>(pEventPool);
39 schoenebeck 32 for (uint i = 0; i < ModulationSystem::destination_count; i++) {
40 schoenebeck 37 pSynthesisEvents[i] = new RTEList<ModulationSystem::Event>(pEventPool);
41 schoenebeck 9 }
42     for (uint i = 0; i < 128; i++) {
43 schoenebeck 35 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 schoenebeck 9 }
49    
50 schoenebeck 31 // FIXME: assuming stereo output
51     pAudioSumBuffer[0] = new float[pAudioIO->MaxSamplesPerCycle() * pAudioIO->Channels()];
52     pAudioSumBuffer[1] = &pAudioSumBuffer[0][pAudioIO->MaxSamplesPerCycle()];
53 schoenebeck 9
54     // set all voice outputs to the AudioSumBuffer
55 schoenebeck 32 for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) { //FIXME: assuming stereo
56     pVoice->SetOutputLeft(pAudioSumBuffer[0], pAudioIO->MaxSamplesPerCycle());
57     pVoice->SetOutputRight(pAudioSumBuffer[1], pAudioIO->MaxSamplesPerCycle());
58 schoenebeck 9 }
59 schoenebeck 32 pVoicePool->clear();
60 schoenebeck 9
61 schoenebeck 35 pRIFF = NULL;
62     pGig = NULL;
63     pInstrument = NULL;
64 schoenebeck 9
65 schoenebeck 30 // initialize modulation system
66 schoenebeck 31 ModulationSystem::Initialize(pAudioIO->SampleRate(), pAudioIO->MaxSamplesPerCycle());
67 schoenebeck 37
68     // set all MIDI controller values to zero
69     memset(ControllerTable, 0x00, 128);
70 schoenebeck 30
71 schoenebeck 35 SuspensionRequested = false;
72     pthread_mutex_init(&__render_state_mutex, NULL);
73     pthread_cond_init(&__render_exit_condition, NULL);
74    
75     dmsg(1,("Starting disk thread..."));
76     pDiskThread->StartThread();
77 schoenebeck 12 dmsg(1,("OK\n"));
78 schoenebeck 9 }
79    
80     AudioThread::~AudioThread() {
81 schoenebeck 35 if (pDiskThread) {
82     pDiskThread->StopThread();
83     delete pDiskThread;
84     }
85     if (pGig) delete pGig;
86     if (pRIFF) delete pRIFF;
87 schoenebeck 30 ModulationSystem::Close();
88 schoenebeck 32 for (uint i = 0; i < 128; i++) {
89     if (pMIDIKeyInfo[i].pActiveVoices) delete pMIDIKeyInfo[i].pActiveVoices;
90 schoenebeck 33 if (pMIDIKeyInfo[i].pEvents) delete pMIDIKeyInfo[i].pEvents;
91 schoenebeck 9 }
92 schoenebeck 32 for (uint i = 0; i < ModulationSystem::destination_count; i++) {
93 schoenebeck 37 if (pSynthesisEvents[i]) delete pSynthesisEvents[i];
94 schoenebeck 32 }
95 schoenebeck 37 delete[] pSynthesisEvents;
96 schoenebeck 33 if (pEvents) delete pEvents;
97 schoenebeck 37 if (pCCEvents) delete pCCEvents;
98 schoenebeck 33 if (pEventQueue) delete pEventQueue;
99     if (pEventPool) delete pEventPool;
100     if (pVoicePool) delete pVoicePool;
101     if (pActiveKeys) delete pActiveKeys;
102 schoenebeck 31 delete[] pAudioSumBuffer[0]; // this also frees the right channel buffer
103 schoenebeck 35 pthread_cond_destroy(&__render_exit_condition);
104     pthread_mutex_destroy(&__render_state_mutex);
105 schoenebeck 9 }
106    
107 schoenebeck 32 /**
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 schoenebeck 31 int AudioThread::RenderAudio(uint Samples) {
118 schoenebeck 9
119 schoenebeck 35 // 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 schoenebeck 32 // empty the event lists for the new fragment
131     pEvents->clear();
132 schoenebeck 37 pCCEvents->clear();
133 schoenebeck 32 for (uint i = 0; i < ModulationSystem::destination_count; i++) {
134 schoenebeck 37 pSynthesisEvents[i]->clear();
135 schoenebeck 32 }
136    
137     // read and copy events from input queue
138     ModulationSystem::Event Event;
139 schoenebeck 9 while (true) {
140 schoenebeck 32 if (!pEventQueue->pop(&Event)) break;
141     pEvents->alloc_assign(Event);
142     }
143 schoenebeck 9
144 schoenebeck 32
145     // update time of start and end of this audio fragment (as events' time stamps relate to this)
146     ModulationSystem::UpdateFragmentTime();
147    
148    
149     // process events
150     ModulationSystem::Event* pNextEvent = pEvents->first();
151     while (pNextEvent) {
152     ModulationSystem::Event* pEvent = pNextEvent;
153     pEvents->set_current(pEvent);
154     pNextEvent = pEvents->next();
155     switch (pEvent->Type) {
156     case ModulationSystem::event_type_note_on:
157 schoenebeck 31 dmsg(5,("Audio Thread: Note on received\n"));
158 schoenebeck 32 ProcessNoteOn(pEvent);
159 schoenebeck 31 break;
160 schoenebeck 32 case ModulationSystem::event_type_note_off:
161 schoenebeck 31 dmsg(5,("Audio Thread: Note off received\n"));
162 schoenebeck 32 ProcessNoteOff(pEvent);
163 schoenebeck 31 break;
164 schoenebeck 32 case ModulationSystem::event_type_control_change:
165 schoenebeck 31 dmsg(5,("Audio Thread: MIDI CC received\n"));
166 schoenebeck 32 ProcessControlChange(pEvent);
167 schoenebeck 31 break;
168 schoenebeck 32 case ModulationSystem::event_type_pitchbend:
169     dmsg(5,("Audio Thread: Pitchbend received\n"));
170     ProcessPitchbend(pEvent);
171     break;
172 schoenebeck 9 }
173 schoenebeck 31 }
174 schoenebeck 9
175    
176 schoenebeck 31 // render audio from all active voices
177     int active_voices = 0;
178 schoenebeck 33 uint* piKey = pActiveKeys->first();
179     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 schoenebeck 32 Voice* pVoiceNext = pKey->pActiveVoices->first();
185 schoenebeck 33 while (pVoiceNext) { // iterate through all voices on this key
186 schoenebeck 32 // 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 schoenebeck 31 else { // voice reached end, is now inactive
195 schoenebeck 32 KillVoice(pVoice); // remove voice from the list of active voices
196 schoenebeck 9 }
197     }
198 schoenebeck 33 pKey->pEvents->clear(); // free all events on the key
199 schoenebeck 31 }
200 schoenebeck 32
201 schoenebeck 33
202 schoenebeck 31 // write that to the disk thread class so that it can print it
203     // on the console for debugging purposes
204     ActiveVoiceCount = active_voices;
205     if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;
206 schoenebeck 9
207    
208 schoenebeck 31 return 0;
209 schoenebeck 9 }
210    
211 schoenebeck 32 /**
212     * Will be called by the MIDIIn Thread to let the audio thread trigger a new
213     * voice for the given key.
214     *
215     * @param Key - MIDI key number of the triggered key
216     * @param Velocity - MIDI velocity value of the triggered key
217     */
218     void AudioThread::SendNoteOn(uint8_t Key, uint8_t Velocity) {
219     ModulationSystem::Event Event;
220     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 schoenebeck 9 }
226    
227 schoenebeck 32 /**
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 schoenebeck 9 }
242    
243 schoenebeck 32 /**
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 senoner 10 }
256    
257 schoenebeck 18 /**
258 schoenebeck 32 * 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 schoenebeck 18 * Assigns and triggers a new voice for the respective MIDI key.
275 schoenebeck 32 *
276     * @param pNoteOnEvent - key, velocity and time stamp of the event
277 schoenebeck 18 */
278 schoenebeck 32 void AudioThread::ProcessNoteOn(ModulationSystem::Event* pNoteOnEvent) {
279     midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Key];
280 schoenebeck 15
281 schoenebeck 32 pKey->KeyPressed = true; // the MIDI key was now pressed down
282 schoenebeck 33
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 schoenebeck 32 if (pNewVoice) {
292 schoenebeck 18 // launch the new voice
293 schoenebeck 33 if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument) < 0) {
294     dmsg(1,("Triggering new voice failed!\n"));
295     pKey->pActiveVoices->free(pNewVoice);
296 schoenebeck 18 }
297 schoenebeck 33 else if (!pKey->Active) { // mark as active key
298     pKey->Active = true;
299     pKey->pSelf = pActiveKeys->alloc();
300     *pKey->pSelf = pNoteOnEvent->Key;
301 schoenebeck 15 }
302 schoenebeck 9 }
303 schoenebeck 32 else std::cerr << "No free voice!" << std::endl << std::flush;
304 schoenebeck 9 }
305    
306 schoenebeck 15 /**
307     * Releases the voices on the given key if sustain pedal is not pressed.
308     * If sustain is pressed, the release of the note will be postponed until
309     * sustain pedal will be released or voice turned inactive by itself (e.g.
310     * due to completion of sample playback).
311 schoenebeck 32 *
312     * @param pNoteOffEvent - key, velocity and time stamp of the event
313 schoenebeck 15 */
314 schoenebeck 32 void AudioThread::ProcessNoteOff(ModulationSystem::Event* pNoteOffEvent) {
315     midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOffEvent->Key];
316    
317     pKey->KeyPressed = false; // the MIDI key was now released
318    
319 schoenebeck 33 // 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 schoenebeck 12 }
324     }
325 senoner 10
326 schoenebeck 15 /**
327 schoenebeck 32 * Moves pitchbend event from the general (input) event list to the pitch
328 schoenebeck 40 * event list.
329 schoenebeck 32 *
330     * @param pPitchbendEvent - absolute pitch value and time stamp of the event
331     */
332     void AudioThread::ProcessPitchbend(ModulationSystem::Event* pPitchbendEvent) {
333 schoenebeck 40 this->Pitch = pPitchbendEvent->Pitch; // store current pitch value
334 schoenebeck 37 pEvents->move(pPitchbendEvent, pSynthesisEvents[ModulationSystem::destination_vco]);
335 schoenebeck 32 }
336    
337     /**
338 schoenebeck 30 * 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 schoenebeck 33 * This method will e.g. be called if a voice went inactive by itself.
341 schoenebeck 32 *
342     * @param pVoice - points to the voice to be killed
343 schoenebeck 15 */
344 schoenebeck 30 void AudioThread::KillVoice(Voice* pVoice) {
345 schoenebeck 9 if (pVoice) {
346 schoenebeck 30 if (pVoice->IsActive()) pVoice->Kill();
347 senoner 10
348 schoenebeck 32 midi_key_info_t* pKey = &pMIDIKeyInfo[pVoice->MIDIKey];
349    
350     // free the voice object
351     pVoicePool->free(pVoice);
352 schoenebeck 15
353 schoenebeck 18 // check if there are no voices left on the MIDI key and update the key info if so
354 schoenebeck 32 if (pKey->pActiveVoices->is_empty()) {
355 schoenebeck 33 pKey->Active = false;
356     pActiveKeys->free(pKey->pSelf); // remove key from list of active keys
357     pKey->pSelf = NULL;
358 schoenebeck 18 dmsg(3,("Key has no more voices now\n"));
359 schoenebeck 15 }
360 schoenebeck 9 }
361 schoenebeck 15 else std::cerr << "Couldn't release voice! (pVoice == NULL)\n" << std::flush;
362 schoenebeck 9 }
363    
364 schoenebeck 32 /**
365     * Reacts on supported control change commands (e.g. pitch bend wheel,
366     * modulation wheel, aftertouch).
367     *
368     * @param pControlChangeEvent - controller, value and time stamp of the event
369     */
370     void AudioThread::ProcessControlChange(ModulationSystem::Event* pControlChangeEvent) {
371     dmsg(4,("AudioThread::ContinuousController cc=%d v=%d\n", pControlChangeEvent->Controller, pControlChangeEvent->Value));
372    
373     switch (pControlChangeEvent->Controller) {
374     case 64: {
375 schoenebeck 37 if (pControlChangeEvent->Value >= 64 && !SustainPedal) {
376 schoenebeck 32 dmsg(4,("PEDAL DOWN\n"));
377     SustainPedal = true;
378 schoenebeck 33
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 schoenebeck 32 }
395 schoenebeck 37 if (pControlChangeEvent->Value < 64 && SustainPedal) {
396 schoenebeck 32 dmsg(4,("PEDAL UP\n"));
397     SustainPedal = false;
398 schoenebeck 33
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 schoenebeck 32 }
412 schoenebeck 18 }
413 schoenebeck 15 }
414 schoenebeck 12 }
415 schoenebeck 32 break;
416 schoenebeck 12 }
417 senoner 10 }
418 schoenebeck 37
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 senoner 10 }
425    
426 schoenebeck 32 /**
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 schoenebeck 9 void AudioThread::CacheInitialSamples(gig::Sample* pSample) {
435     if (!pSample || pSample->GetCache().Size) return;
436     if (pSample->SamplesTotal <= NUM_RAM_PRELOAD_SAMPLES) {
437     // Sample is too short for disk streaming, so we load the whole
438     // sample into RAM and place 'pAudioIO->FragmentSize << MAX_PITCH'
439     // 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
441     // the sample.
442 schoenebeck 31 gig::buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension((pAudioIO->MaxSamplesPerCycle() << MAX_PITCH) + 3);
443 schoenebeck 12 dmsg(4,("Cached %d Bytes, %d silence bytes.\n", buf.Size, buf.NullExtensionSize));
444 schoenebeck 9 }
445     else { // we only cache NUM_RAM_PRELOAD_SAMPLES and stream the other sample points from disk
446     pSample->LoadSampleData(NUM_RAM_PRELOAD_SAMPLES);
447     }
448    
449     if (!pSample->GetCache().Size) std::cerr << "Unable to cache sample - maybe memory full!" << std::endl << std::flush;
450     }
451 schoenebeck 35
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     }

  ViewVC Help
Powered by ViewVC