/[svn]/linuxsampler/tags/singlechannel/src/audiothread.cpp
ViewVC logotype

Annotation of /linuxsampler/tags/singlechannel/src/audiothread.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 37 - (hide annotations) (download)
Wed Mar 10 22:01:36 2004 UTC (20 years, 2 months ago) by schoenebeck
Original Path: linuxsampler/trunk/src/audiothread.cpp
File size: 23420 byte(s)
* src/eg_vca.cpp: added following transitions to the envelope generator:
  'Attack_Hold' -> 'Release', 'Decay_1' -> 'Release' in case of a release
  event
* EG1 parameters 'Attack Time', 'Release Time' and 'Sustain Time' are now
  controllable by a MIDI controller defined in the .gig file
* src/voice.cpp: fixed bug in pitch calculation which caused new triggered
  voices to be played back without honoring the current pitch bend value

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     * event list and converts absolute pitch value to delta pitch value.
329     *
330     * @param pPitchbendEvent - absolute pitch value and time stamp of the event
331     */
332     void AudioThread::ProcessPitchbend(ModulationSystem::Event* pPitchbendEvent) {
333     int currentPitch = pPitchbendEvent->Pitch;
334     pPitchbendEvent->Pitch -= this->Pitch; // convert to delta
335     this->Pitch = currentPitch; // store current absolute pitch value
336 schoenebeck 37 pEvents->move(pPitchbendEvent, pSynthesisEvents[ModulationSystem::destination_vco]);
337 schoenebeck 32 }
338    
339     /**
340 schoenebeck 30 * Immediately kills the voice given with pVoice (no matter if sustain is
341     * pressed or not) and removes it from the MIDI key's list of active voice.
342 schoenebeck 33 * This method will e.g. be called if a voice went inactive by itself.
343 schoenebeck 32 *
344     * @param pVoice - points to the voice to be killed
345 schoenebeck 15 */
346 schoenebeck 30 void AudioThread::KillVoice(Voice* pVoice) {
347 schoenebeck 9 if (pVoice) {
348 schoenebeck 30 if (pVoice->IsActive()) pVoice->Kill();
349 senoner 10
350 schoenebeck 32 midi_key_info_t* pKey = &pMIDIKeyInfo[pVoice->MIDIKey];
351    
352     // free the voice object
353     pVoicePool->free(pVoice);
354 schoenebeck 15
355 schoenebeck 18 // check if there are no voices left on the MIDI key and update the key info if so
356 schoenebeck 32 if (pKey->pActiveVoices->is_empty()) {
357 schoenebeck 33 pKey->Active = false;
358     pActiveKeys->free(pKey->pSelf); // remove key from list of active keys
359     pKey->pSelf = NULL;
360 schoenebeck 18 dmsg(3,("Key has no more voices now\n"));
361 schoenebeck 15 }
362 schoenebeck 9 }
363 schoenebeck 15 else std::cerr << "Couldn't release voice! (pVoice == NULL)\n" << std::flush;
364 schoenebeck 9 }
365    
366 schoenebeck 32 /**
367     * Reacts on supported control change commands (e.g. pitch bend wheel,
368     * modulation wheel, aftertouch).
369     *
370     * @param pControlChangeEvent - controller, value and time stamp of the event
371     */
372     void AudioThread::ProcessControlChange(ModulationSystem::Event* pControlChangeEvent) {
373     dmsg(4,("AudioThread::ContinuousController cc=%d v=%d\n", pControlChangeEvent->Controller, pControlChangeEvent->Value));
374    
375     switch (pControlChangeEvent->Controller) {
376     case 64: {
377 schoenebeck 37 if (pControlChangeEvent->Value >= 64 && !SustainPedal) {
378 schoenebeck 32 dmsg(4,("PEDAL DOWN\n"));
379     SustainPedal = true;
380 schoenebeck 33
381     // cancel release process of voices if necessary
382     uint* piKey = pActiveKeys->first();
383     if (piKey) {
384     pControlChangeEvent->Type = ModulationSystem::event_type_cancel_release; // transform event type
385     while (piKey) {
386     midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
387     pActiveKeys->set_current(piKey);
388     piKey = pActiveKeys->next();
389     if (!pKey->KeyPressed) {
390     ModulationSystem::Event* pNewEvent = pKey->pEvents->alloc();
391     if (pNewEvent) *pNewEvent = *pControlChangeEvent; // copy event to the key's own event list
392     else dmsg(1,("Event pool emtpy!\n"));
393     }
394     }
395     }
396 schoenebeck 32 }
397 schoenebeck 37 if (pControlChangeEvent->Value < 64 && SustainPedal) {
398 schoenebeck 32 dmsg(4,("PEDAL UP\n"));
399     SustainPedal = false;
400 schoenebeck 33
401     // release voices if their respective key is not pressed
402     uint* piKey = pActiveKeys->first();
403     if (piKey) {
404     pControlChangeEvent->Type = ModulationSystem::event_type_release; // transform event type
405     while (piKey) {
406     midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
407     pActiveKeys->set_current(piKey);
408     piKey = pActiveKeys->next();
409     if (!pKey->KeyPressed) {
410     ModulationSystem::Event* pNewEvent = pKey->pEvents->alloc();
411     if (pNewEvent) *pNewEvent = *pControlChangeEvent; // copy event to the key's own event list
412     else dmsg(1,("Event pool emtpy!\n"));
413 schoenebeck 32 }
414 schoenebeck 18 }
415 schoenebeck 15 }
416 schoenebeck 12 }
417 schoenebeck 32 break;
418 schoenebeck 12 }
419 senoner 10 }
420 schoenebeck 37
421     // update controller value in the engine's controller table
422     ControllerTable[pControlChangeEvent->Controller] = pControlChangeEvent->Value;
423    
424     // move event from the unsorted event list to the control change event list
425     pEvents->move(pControlChangeEvent, pCCEvents);
426 senoner 10 }
427    
428 schoenebeck 32 /**
429     * Caches a certain size at the beginning of the given sample in RAM. If the
430     * sample is very short, the whole sample will be loaded into RAM and thus
431     * no disk streaming is needed for this sample. Caching an initial part of
432     * samples is needed to compensate disk reading latency.
433     *
434     * @param pSample - points to the sample to be cached
435     */
436 schoenebeck 9 void AudioThread::CacheInitialSamples(gig::Sample* pSample) {
437     if (!pSample || pSample->GetCache().Size) return;
438     if (pSample->SamplesTotal <= NUM_RAM_PRELOAD_SAMPLES) {
439     // Sample is too short for disk streaming, so we load the whole
440     // sample into RAM and place 'pAudioIO->FragmentSize << MAX_PITCH'
441     // number of '0' samples (silence samples) behind the official buffer
442     // border, to allow the interpolator do it's work even at the end of
443     // the sample.
444 schoenebeck 31 gig::buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension((pAudioIO->MaxSamplesPerCycle() << MAX_PITCH) + 3);
445 schoenebeck 12 dmsg(4,("Cached %d Bytes, %d silence bytes.\n", buf.Size, buf.NullExtensionSize));
446 schoenebeck 9 }
447     else { // we only cache NUM_RAM_PRELOAD_SAMPLES and stream the other sample points from disk
448     pSample->LoadSampleData(NUM_RAM_PRELOAD_SAMPLES);
449     }
450    
451     if (!pSample->GetCache().Size) std::cerr << "Unable to cache sample - maybe memory full!" << std::endl << std::flush;
452     }
453 schoenebeck 35
454     /**
455     * Load an instrument from a .gig file.
456     *
457     * @param FileName - file name of the Gigasampler instrument file
458     * @param Instrument - index of the instrument in the .gig file
459     * @returns detailed description of the result of the method call
460     */
461     result_t AudioThread::LoadInstrument(const char* FileName, uint Instrument) {
462     result_t result;
463    
464     if (pInstrument) { // if already running
465     // signal audio thread not to enter render part anymore
466     SuspensionRequested = true;
467     // sleep until wakened by audio thread
468     pthread_mutex_lock(&__render_state_mutex);
469     pthread_cond_wait(&__render_exit_condition, &__render_state_mutex);
470     pthread_mutex_unlock(&__render_state_mutex);
471    
472     dmsg(1,("Freeing old instrument from memory..."));
473     delete pGig;
474     delete pRIFF;
475     pInstrument = NULL;
476     dmsg(1,("OK\n"));
477     }
478    
479     // loading gig file
480     try {
481     dmsg(1,("Loading gig file..."));
482     pRIFF = new RIFF::File(FileName);
483     pGig = new gig::File(pRIFF);
484     pInstrument = pGig->GetInstrument(Instrument);
485     if (!pInstrument) {
486     std::stringstream msg;
487     msg << "There's no instrument with index " << Instrument << ".";
488     std::cerr << msg << std::endl;
489     result.type = result_type_error;
490     result.code = LSCP_ERR_UNKNOWN;
491     result.message = msg.str();
492     return result;
493     }
494     pGig->GetFirstSample(); // just to complete instrument loading before we enter the realtime part
495     dmsg(1,("OK\n"));
496     }
497     catch (RIFF::Exception e) {
498     e.PrintMessage();
499     result.type = result_type_error;
500     result.code = LSCP_ERR_UNKNOWN;
501     result.message = e.Message;
502     return result;
503     }
504     catch (...) {
505     dmsg(1,("Unknown exception while trying to parse gig file.\n"));
506     result.type = result_type_error;
507     result.code = LSCP_ERR_UNKNOWN;
508     result.message = "Unknown exception while trying to parse gig file.";
509     return result;
510     }
511    
512     // cache initial samples points (for actually needed samples)
513     dmsg(1,("Caching initial samples..."));
514     gig::Region* pRgn = this->pInstrument->GetFirstRegion();
515     while (pRgn) {
516     if (!pRgn->GetSample()->GetCache().Size) {
517     dmsg(2,("C"));
518     CacheInitialSamples(pRgn->GetSample());
519     }
520     for (uint i = 0; i < pRgn->DimensionRegions; i++) {
521     CacheInitialSamples(pRgn->pDimensionRegions[i]->pSample);
522     }
523    
524     pRgn = this->pInstrument->GetNextRegion();
525     }
526     dmsg(1,("OK\n"));
527    
528     ResetInternal(); // reset engine
529    
530     // signal audio thread to continue with rendering
531     SuspensionRequested = false;
532    
533     // success
534     result.type = result_type_success;
535     return result;
536     }
537    
538     /**
539     * Reset all voices and disk thread and clear input event queue and all
540     * control and status variables.
541     */
542     void AudioThread::Reset() {
543     if (pInstrument) { // if already running
544     // signal audio thread not to enter render part anymore
545     SuspensionRequested = true;
546     // sleep until wakened by audio thread
547     pthread_mutex_lock(&__render_state_mutex);
548     pthread_cond_wait(&__render_exit_condition, &__render_state_mutex);
549     pthread_mutex_unlock(&__render_state_mutex);
550     }
551    
552     ResetInternal();
553    
554     // signal audio thread to continue with rendering
555     SuspensionRequested = false;
556     }
557    
558     /**
559     * Reset all voices and disk thread and clear input event queue and all
560     * control and status variables. This method is not thread safe!
561     */
562     void AudioThread::ResetInternal() {
563     this->Pitch = 0;
564     SustainPedal = 0;
565     ActiveVoiceCount = 0;
566     ActiveVoiceCountMax = 0;
567    
568     // reset key info
569     for (uint i = 0; i < 128; i++) {
570     pMIDIKeyInfo[i].pActiveVoices->clear();
571     pMIDIKeyInfo[i].pEvents->clear();
572     pMIDIKeyInfo[i].KeyPressed = false;
573     pMIDIKeyInfo[i].Active = false;
574     pMIDIKeyInfo[i].pSelf = NULL;
575     }
576    
577     // reset all voices
578     for (Voice* pVoice = pVoicePool->first(); pVoice; pVoice = pVoicePool->next()) {
579     pVoice->Reset();
580     }
581    
582     // free all active keys
583     pActiveKeys->clear();
584    
585     // reset disk thread
586     pDiskThread->Reset();
587    
588     // delete all input events
589     pEventQueue->init();
590     }

  ViewVC Help
Powered by ViewVC