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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 35 - (hide annotations) (download)
Fri Mar 5 13:46:15 2004 UTC (20 years, 2 months ago) by schoenebeck
File size: 23204 byte(s)
* implemented parser for the LinuxSampler control protocol (LSCP) by using
  flex / bison (where src/network/lscp.l is the input file for lex / flex
  and src/network/lscp.y is the input file for yacc / bison), parser and
  scanner can be regenerated by 'make parser'
* implemented LSCP network server (only single threaded so far), LSCP
  server will be launched if LinuxSampler was started with "--server" flag,
  implemented the following LSCP commands so far: "LOAD INSTRUMENT", "GET
  CHANNEL VOICE_COUNT", "GET CHANNEL STREAM_COUNT", "GET CHANNEL
  BUFFER_FILL", "SET CHANNEL VOLUME" and "RESET CHANNEL"
* disk thread now started within the engine

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 35 Voice::pDiskThread = this->pDiskThread;
31 schoenebeck 32 Voice::pEngine = this;
32     pEventQueue = new RingBuffer<ModulationSystem::Event>(MAX_EVENTS_PER_FRAGMENT);
33     pEventPool = new RTELMemoryPool<ModulationSystem::Event>(MAX_EVENTS_PER_FRAGMENT);
34     pVoicePool = new RTELMemoryPool<Voice>(MAX_AUDIO_VOICES);
35 schoenebeck 33 pActiveKeys = new RTELMemoryPool<uint>(128);
36 schoenebeck 32 pEvents = new RTEList<ModulationSystem::Event>(pEventPool);
37     for (uint i = 0; i < ModulationSystem::destination_count; i++) {
38     pCCEvents[i] = new RTEList<ModulationSystem::Event>(pEventPool);
39 schoenebeck 9 }
40     for (uint i = 0; i < 128; i++) {
41 schoenebeck 35 pMIDIKeyInfo[i].pActiveVoices = new RTEList<Voice>(pVoicePool);
42     pMIDIKeyInfo[i].KeyPressed = false;
43     pMIDIKeyInfo[i].Active = false;
44     pMIDIKeyInfo[i].pSelf = NULL;
45     pMIDIKeyInfo[i].pEvents = new RTEList<ModulationSystem::Event>(pEventPool);
46 schoenebeck 9 }
47    
48 schoenebeck 31 // FIXME: assuming stereo output
49     pAudioSumBuffer[0] = new float[pAudioIO->MaxSamplesPerCycle() * pAudioIO->Channels()];
50     pAudioSumBuffer[1] = &pAudioSumBuffer[0][pAudioIO->MaxSamplesPerCycle()];
51 schoenebeck 9
52     // set all voice outputs to the AudioSumBuffer
53 schoenebeck 32 for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) { //FIXME: assuming stereo
54     pVoice->SetOutputLeft(pAudioSumBuffer[0], pAudioIO->MaxSamplesPerCycle());
55     pVoice->SetOutputRight(pAudioSumBuffer[1], pAudioIO->MaxSamplesPerCycle());
56 schoenebeck 9 }
57 schoenebeck 32 pVoicePool->clear();
58 schoenebeck 9
59 schoenebeck 35 pRIFF = NULL;
60     pGig = NULL;
61     pInstrument = NULL;
62 schoenebeck 9
63 schoenebeck 30 // initialize modulation system
64 schoenebeck 31 ModulationSystem::Initialize(pAudioIO->SampleRate(), pAudioIO->MaxSamplesPerCycle());
65 schoenebeck 30
66 senoner 10 // sustain pedal value
67 schoenebeck 12 PrevHoldCCValue = 0;
68     SustainPedal = 0;
69 senoner 10
70 schoenebeck 35 SuspensionRequested = false;
71     pthread_mutex_init(&__render_state_mutex, NULL);
72     pthread_cond_init(&__render_exit_condition, NULL);
73    
74     dmsg(1,("Starting disk thread..."));
75     pDiskThread->StartThread();
76 schoenebeck 12 dmsg(1,("OK\n"));
77 schoenebeck 9 }
78    
79     AudioThread::~AudioThread() {
80 schoenebeck 35 if (pDiskThread) {
81     pDiskThread->StopThread();
82     delete pDiskThread;
83     }
84     if (pGig) delete pGig;
85     if (pRIFF) delete pRIFF;
86 schoenebeck 30 ModulationSystem::Close();
87 schoenebeck 32 for (uint i = 0; i < 128; i++) {
88     if (pMIDIKeyInfo[i].pActiveVoices) delete pMIDIKeyInfo[i].pActiveVoices;
89 schoenebeck 33 if (pMIDIKeyInfo[i].pEvents) delete pMIDIKeyInfo[i].pEvents;
90 schoenebeck 9 }
91 schoenebeck 32 for (uint i = 0; i < ModulationSystem::destination_count; i++) {
92     if (pCCEvents[i]) delete pCCEvents[i];
93     }
94     delete[] pCCEvents;
95 schoenebeck 33 if (pEvents) delete pEvents;
96     if (pEventQueue) delete pEventQueue;
97     if (pEventPool) delete pEventPool;
98     if (pVoicePool) delete pVoicePool;
99     if (pActiveKeys) delete pActiveKeys;
100 schoenebeck 31 delete[] pAudioSumBuffer[0]; // this also frees the right channel buffer
101 schoenebeck 35 pthread_cond_destroy(&__render_exit_condition);
102     pthread_mutex_destroy(&__render_state_mutex);
103 schoenebeck 9 }
104    
105 schoenebeck 32 /**
106     * Let this engine proceed to render the given amount of sample points. The
107     * calculated audio data of all voices of this engine will be placed into
108     * the engine's audio sum buffer which has to be copied and eventually be
109     * converted to the appropriate value range by the audio output class (e.g.
110     * AlsaIO or JackIO) right after.
111     *
112     * @param Samples - number of sample points to be rendered
113     * @returns 0 on success
114     */
115 schoenebeck 31 int AudioThread::RenderAudio(uint Samples) {
116 schoenebeck 9
117 schoenebeck 35 // zero out the output sum buffer (left and right channel)
118     memset(pAudioSumBuffer[0], 0, Samples * pAudioIO->Channels() * sizeof(float));
119    
120    
121     // check if rendering process was requested to be interrupted (e.g. to load another instrument)
122     if (SuspensionRequested) {
123     pthread_cond_broadcast(&__render_exit_condition); // wake up anybody waiting for us
124     return 0;
125     }
126    
127    
128 schoenebeck 32 // empty the event lists for the new fragment
129     pEvents->clear();
130     for (uint i = 0; i < ModulationSystem::destination_count; i++) {
131     pCCEvents[i]->clear();
132     }
133    
134     // read and copy events from input queue
135     ModulationSystem::Event Event;
136 schoenebeck 9 while (true) {
137 schoenebeck 32 if (!pEventQueue->pop(&Event)) break;
138     pEvents->alloc_assign(Event);
139     }
140 schoenebeck 9
141 schoenebeck 32
142     // update time of start and end of this audio fragment (as events' time stamps relate to this)
143     ModulationSystem::UpdateFragmentTime();
144    
145    
146     // process events
147     ModulationSystem::Event* pNextEvent = pEvents->first();
148     while (pNextEvent) {
149     ModulationSystem::Event* pEvent = pNextEvent;
150     pEvents->set_current(pEvent);
151     pNextEvent = pEvents->next();
152     switch (pEvent->Type) {
153     case ModulationSystem::event_type_note_on:
154 schoenebeck 31 dmsg(5,("Audio Thread: Note on received\n"));
155 schoenebeck 32 ProcessNoteOn(pEvent);
156 schoenebeck 31 break;
157 schoenebeck 32 case ModulationSystem::event_type_note_off:
158 schoenebeck 31 dmsg(5,("Audio Thread: Note off received\n"));
159 schoenebeck 32 ProcessNoteOff(pEvent);
160 schoenebeck 31 break;
161 schoenebeck 32 case ModulationSystem::event_type_control_change:
162 schoenebeck 31 dmsg(5,("Audio Thread: MIDI CC received\n"));
163 schoenebeck 32 ProcessControlChange(pEvent);
164 schoenebeck 31 break;
165 schoenebeck 32 case ModulationSystem::event_type_pitchbend:
166     dmsg(5,("Audio Thread: Pitchbend received\n"));
167     ProcessPitchbend(pEvent);
168     break;
169 schoenebeck 9 }
170 schoenebeck 31 }
171 schoenebeck 9
172    
173 schoenebeck 31 // render audio from all active voices
174     int active_voices = 0;
175 schoenebeck 33 uint* piKey = pActiveKeys->first();
176     while (piKey) { // iterate through all active keys
177     midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
178     pActiveKeys->set_current(piKey);
179     piKey = pActiveKeys->next();
180    
181 schoenebeck 32 Voice* pVoiceNext = pKey->pActiveVoices->first();
182 schoenebeck 33 while (pVoiceNext) { // iterate through all voices on this key
183 schoenebeck 32 // already get next voice on key
184     Voice* pVoice = pVoiceNext;
185     pKey->pActiveVoices->set_current(pVoice);
186     pVoiceNext = pKey->pActiveVoices->next();
187    
188     // now render current voice
189     pVoice->Render(Samples);
190     if (pVoice->IsActive()) active_voices++; // still active
191 schoenebeck 31 else { // voice reached end, is now inactive
192 schoenebeck 32 KillVoice(pVoice); // remove voice from the list of active voices
193 schoenebeck 9 }
194     }
195 schoenebeck 33 pKey->pEvents->clear(); // free all events on the key
196 schoenebeck 31 }
197 schoenebeck 32
198 schoenebeck 33
199 schoenebeck 31 // write that to the disk thread class so that it can print it
200     // on the console for debugging purposes
201     ActiveVoiceCount = active_voices;
202     if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;
203 schoenebeck 9
204    
205 schoenebeck 31 return 0;
206 schoenebeck 9 }
207    
208 schoenebeck 32 /**
209     * Will be called by the MIDIIn Thread to let the audio thread trigger a new
210     * voice for the given key.
211     *
212     * @param Key - MIDI key number of the triggered key
213     * @param Velocity - MIDI velocity value of the triggered key
214     */
215     void AudioThread::SendNoteOn(uint8_t Key, uint8_t Velocity) {
216     ModulationSystem::Event Event;
217     Event.Type = ModulationSystem::event_type_note_on;
218     Event.Key = Key;
219     Event.Velocity = Velocity;
220     if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
221     else dmsg(1,("AudioThread: Input event queue full!"));
222 schoenebeck 9 }
223    
224 schoenebeck 32 /**
225     * Will be called by the MIDIIn Thread to signal the audio thread to release
226     * voice(s) on the given key.
227     *
228     * @param Key - MIDI key number of the released key
229     * @param Velocity - MIDI release velocity value of the released key
230     */
231     void AudioThread::SendNoteOff(uint8_t Key, uint8_t Velocity) {
232     ModulationSystem::Event Event;
233     Event.Type = ModulationSystem::event_type_note_off;
234     Event.Key = Key;
235     Event.Velocity = Velocity;
236     if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
237     else dmsg(1,("AudioThread: Input event queue full!"));
238 schoenebeck 9 }
239    
240 schoenebeck 32 /**
241     * Will be called by the MIDIIn Thread to signal the audio thread to change
242     * the pitch value for all voices.
243     *
244     * @param Pitch - MIDI pitch value (-8192 ... +8191)
245     */
246     void AudioThread::SendPitchbend(int Pitch) {
247     ModulationSystem::Event Event;
248     Event.Type = ModulationSystem::event_type_pitchbend;
249     Event.Pitch = Pitch;
250     if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
251     else dmsg(1,("AudioThread: Input event queue full!"));
252 senoner 10 }
253    
254 schoenebeck 18 /**
255 schoenebeck 32 * Will be called by the MIDIIn Thread to signal the audio thread that a
256     * continuous controller value has changed.
257     *
258     * @param Controller - MIDI controller number of the occured control change
259     * @param Value - value of the control change
260     */
261     void AudioThread::SendControlChange(uint8_t Controller, uint8_t Value) {
262     ModulationSystem::Event Event;
263     Event.Type = ModulationSystem::event_type_control_change;
264     Event.Controller = Controller;
265     Event.Value = Value;
266     if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
267     else dmsg(1,("AudioThread: Input event queue full!"));
268     }
269    
270     /**
271 schoenebeck 18 * Assigns and triggers a new voice for the respective MIDI key.
272 schoenebeck 32 *
273     * @param pNoteOnEvent - key, velocity and time stamp of the event
274 schoenebeck 18 */
275 schoenebeck 32 void AudioThread::ProcessNoteOn(ModulationSystem::Event* pNoteOnEvent) {
276     midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Key];
277 schoenebeck 15
278 schoenebeck 32 pKey->KeyPressed = true; // the MIDI key was now pressed down
279 schoenebeck 33
280     // cancel release process of voices on this key if needed
281     if (pKey->Active && !SustainPedal) {
282     pNoteOnEvent->Type = ModulationSystem::event_type_cancel_release; // transform event type
283     pEvents->move(pNoteOnEvent, pKey->pEvents); // move event to the key's own event list
284     }
285    
286     // allocate a new voice for the key
287     Voice* pNewVoice = pKey->pActiveVoices->alloc();
288 schoenebeck 32 if (pNewVoice) {
289 schoenebeck 18 // launch the new voice
290 schoenebeck 33 if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument) < 0) {
291     dmsg(1,("Triggering new voice failed!\n"));
292     pKey->pActiveVoices->free(pNewVoice);
293 schoenebeck 18 }
294 schoenebeck 33 else if (!pKey->Active) { // mark as active key
295     pKey->Active = true;
296     pKey->pSelf = pActiveKeys->alloc();
297     *pKey->pSelf = pNoteOnEvent->Key;
298 schoenebeck 15 }
299 schoenebeck 9 }
300 schoenebeck 32 else std::cerr << "No free voice!" << std::endl << std::flush;
301 schoenebeck 9 }
302    
303 schoenebeck 15 /**
304     * Releases the voices on the given key if sustain pedal is not pressed.
305     * If sustain is pressed, the release of the note will be postponed until
306     * sustain pedal will be released or voice turned inactive by itself (e.g.
307     * due to completion of sample playback).
308 schoenebeck 32 *
309     * @param pNoteOffEvent - key, velocity and time stamp of the event
310 schoenebeck 15 */
311 schoenebeck 32 void AudioThread::ProcessNoteOff(ModulationSystem::Event* pNoteOffEvent) {
312     midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOffEvent->Key];
313    
314     pKey->KeyPressed = false; // the MIDI key was now released
315    
316 schoenebeck 33 // release voices on this key if needed
317     if (pKey->Active && !SustainPedal) {
318     pNoteOffEvent->Type = ModulationSystem::event_type_release; // transform event type
319     pEvents->move(pNoteOffEvent, pKey->pEvents); // move event to the key's own event list
320 schoenebeck 12 }
321     }
322 senoner 10
323 schoenebeck 15 /**
324 schoenebeck 32 * Moves pitchbend event from the general (input) event list to the pitch
325     * event list and converts absolute pitch value to delta pitch value.
326     *
327     * @param pPitchbendEvent - absolute pitch value and time stamp of the event
328     */
329     void AudioThread::ProcessPitchbend(ModulationSystem::Event* pPitchbendEvent) {
330     int currentPitch = pPitchbendEvent->Pitch;
331     pPitchbendEvent->Pitch -= this->Pitch; // convert to delta
332     this->Pitch = currentPitch; // store current absolute pitch value
333     pEvents->move(pPitchbendEvent, pCCEvents[ModulationSystem::destination_vco]);
334     }
335    
336     /**
337 schoenebeck 30 * Immediately kills the voice given with pVoice (no matter if sustain is
338     * pressed or not) and removes it from the MIDI key's list of active voice.
339 schoenebeck 33 * This method will e.g. be called if a voice went inactive by itself.
340 schoenebeck 32 *
341     * @param pVoice - points to the voice to be killed
342 schoenebeck 15 */
343 schoenebeck 30 void AudioThread::KillVoice(Voice* pVoice) {
344 schoenebeck 9 if (pVoice) {
345 schoenebeck 30 if (pVoice->IsActive()) pVoice->Kill();
346 senoner 10
347 schoenebeck 32 midi_key_info_t* pKey = &pMIDIKeyInfo[pVoice->MIDIKey];
348    
349     // free the voice object
350     pVoicePool->free(pVoice);
351 schoenebeck 15
352 schoenebeck 18 // check if there are no voices left on the MIDI key and update the key info if so
353 schoenebeck 32 if (pKey->pActiveVoices->is_empty()) {
354 schoenebeck 33 pKey->Active = false;
355     pActiveKeys->free(pKey->pSelf); // remove key from list of active keys
356     pKey->pSelf = NULL;
357 schoenebeck 18 dmsg(3,("Key has no more voices now\n"));
358 schoenebeck 15 }
359 schoenebeck 9 }
360 schoenebeck 15 else std::cerr << "Couldn't release voice! (pVoice == NULL)\n" << std::flush;
361 schoenebeck 9 }
362    
363 schoenebeck 32 /**
364     * Reacts on supported control change commands (e.g. pitch bend wheel,
365     * modulation wheel, aftertouch).
366     *
367     * @param pControlChangeEvent - controller, value and time stamp of the event
368     */
369     void AudioThread::ProcessControlChange(ModulationSystem::Event* pControlChangeEvent) {
370     dmsg(4,("AudioThread::ContinuousController cc=%d v=%d\n", pControlChangeEvent->Controller, pControlChangeEvent->Value));
371    
372     switch (pControlChangeEvent->Controller) {
373     case 64: {
374     if (pControlChangeEvent->Value >= 64 && PrevHoldCCValue < 64) {
375     dmsg(4,("PEDAL DOWN\n"));
376     SustainPedal = true;
377 schoenebeck 33
378     // cancel release process of voices if necessary
379     uint* piKey = pActiveKeys->first();
380     if (piKey) {
381     pControlChangeEvent->Type = ModulationSystem::event_type_cancel_release; // transform event type
382     while (piKey) {
383     midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
384     pActiveKeys->set_current(piKey);
385     piKey = pActiveKeys->next();
386     if (!pKey->KeyPressed) {
387     ModulationSystem::Event* pNewEvent = pKey->pEvents->alloc();
388     if (pNewEvent) *pNewEvent = *pControlChangeEvent; // copy event to the key's own event list
389     else dmsg(1,("Event pool emtpy!\n"));
390     }
391     }
392     pEvents->free(pControlChangeEvent); // free the original event
393     }
394 schoenebeck 32 }
395     if (pControlChangeEvent->Value < 64 && PrevHoldCCValue >= 64) {
396     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 33 pEvents->free(pControlChangeEvent); // free the original event
414 schoenebeck 15 }
415 schoenebeck 33
416 schoenebeck 12 }
417 schoenebeck 32 PrevHoldCCValue = pControlChangeEvent->Value;
418     break;
419 schoenebeck 12 }
420 senoner 10 }
421     }
422    
423 schoenebeck 32 /**
424     * Caches a certain size at the beginning of the given sample in RAM. If the
425     * sample is very short, the whole sample will be loaded into RAM and thus
426     * no disk streaming is needed for this sample. Caching an initial part of
427     * samples is needed to compensate disk reading latency.
428     *
429     * @param pSample - points to the sample to be cached
430     */
431 schoenebeck 9 void AudioThread::CacheInitialSamples(gig::Sample* pSample) {
432     if (!pSample || pSample->GetCache().Size) return;
433     if (pSample->SamplesTotal <= NUM_RAM_PRELOAD_SAMPLES) {
434     // Sample is too short for disk streaming, so we load the whole
435     // sample into RAM and place 'pAudioIO->FragmentSize << MAX_PITCH'
436     // number of '0' samples (silence samples) behind the official buffer
437     // border, to allow the interpolator do it's work even at the end of
438     // the sample.
439 schoenebeck 31 gig::buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension((pAudioIO->MaxSamplesPerCycle() << MAX_PITCH) + 3);
440 schoenebeck 12 dmsg(4,("Cached %d Bytes, %d silence bytes.\n", buf.Size, buf.NullExtensionSize));
441 schoenebeck 9 }
442     else { // we only cache NUM_RAM_PRELOAD_SAMPLES and stream the other sample points from disk
443     pSample->LoadSampleData(NUM_RAM_PRELOAD_SAMPLES);
444     }
445    
446     if (!pSample->GetCache().Size) std::cerr << "Unable to cache sample - maybe memory full!" << std::endl << std::flush;
447     }
448 schoenebeck 35
449     /**
450     * Load an instrument from a .gig file.
451     *
452     * @param FileName - file name of the Gigasampler instrument file
453     * @param Instrument - index of the instrument in the .gig file
454     * @returns detailed description of the result of the method call
455     */
456     result_t AudioThread::LoadInstrument(const char* FileName, uint Instrument) {
457     result_t result;
458    
459     if (pInstrument) { // if already running
460     // signal audio thread not to enter render part anymore
461     SuspensionRequested = true;
462     // sleep until wakened by audio thread
463     pthread_mutex_lock(&__render_state_mutex);
464     pthread_cond_wait(&__render_exit_condition, &__render_state_mutex);
465     pthread_mutex_unlock(&__render_state_mutex);
466    
467     dmsg(1,("Freeing old instrument from memory..."));
468     delete pGig;
469     delete pRIFF;
470     pInstrument = NULL;
471     dmsg(1,("OK\n"));
472     }
473    
474     // loading gig file
475     try {
476     dmsg(1,("Loading gig file..."));
477     pRIFF = new RIFF::File(FileName);
478     pGig = new gig::File(pRIFF);
479     pInstrument = pGig->GetInstrument(Instrument);
480     if (!pInstrument) {
481     std::stringstream msg;
482     msg << "There's no instrument with index " << Instrument << ".";
483     std::cerr << msg << std::endl;
484     result.type = result_type_error;
485     result.code = LSCP_ERR_UNKNOWN;
486     result.message = msg.str();
487     return result;
488     }
489     pGig->GetFirstSample(); // just to complete instrument loading before we enter the realtime part
490     dmsg(1,("OK\n"));
491     }
492     catch (RIFF::Exception e) {
493     e.PrintMessage();
494     result.type = result_type_error;
495     result.code = LSCP_ERR_UNKNOWN;
496     result.message = e.Message;
497     return result;
498     }
499     catch (...) {
500     dmsg(1,("Unknown exception while trying to parse gig file.\n"));
501     result.type = result_type_error;
502     result.code = LSCP_ERR_UNKNOWN;
503     result.message = "Unknown exception while trying to parse gig file.";
504     return result;
505     }
506    
507     // cache initial samples points (for actually needed samples)
508     dmsg(1,("Caching initial samples..."));
509     gig::Region* pRgn = this->pInstrument->GetFirstRegion();
510     while (pRgn) {
511     if (!pRgn->GetSample()->GetCache().Size) {
512     dmsg(2,("C"));
513     CacheInitialSamples(pRgn->GetSample());
514     }
515     for (uint i = 0; i < pRgn->DimensionRegions; i++) {
516     CacheInitialSamples(pRgn->pDimensionRegions[i]->pSample);
517     }
518    
519     pRgn = this->pInstrument->GetNextRegion();
520     }
521     dmsg(1,("OK\n"));
522    
523     ResetInternal(); // reset engine
524    
525     // signal audio thread to continue with rendering
526     SuspensionRequested = false;
527    
528     // success
529     result.type = result_type_success;
530     return result;
531     }
532    
533     /**
534     * Reset all voices and disk thread and clear input event queue and all
535     * control and status variables.
536     */
537     void AudioThread::Reset() {
538     if (pInstrument) { // if already running
539     // signal audio thread not to enter render part anymore
540     SuspensionRequested = true;
541     // sleep until wakened by audio thread
542     pthread_mutex_lock(&__render_state_mutex);
543     pthread_cond_wait(&__render_exit_condition, &__render_state_mutex);
544     pthread_mutex_unlock(&__render_state_mutex);
545     }
546    
547     ResetInternal();
548    
549     // signal audio thread to continue with rendering
550     SuspensionRequested = false;
551     }
552    
553     /**
554     * Reset all voices and disk thread and clear input event queue and all
555     * control and status variables. This method is not thread safe!
556     */
557     void AudioThread::ResetInternal() {
558     this->Pitch = 0;
559     PrevHoldCCValue = 0; // sustain pedal value
560     SustainPedal = 0;
561     ActiveVoiceCount = 0;
562     ActiveVoiceCountMax = 0;
563    
564     // reset key info
565     for (uint i = 0; i < 128; i++) {
566     pMIDIKeyInfo[i].pActiveVoices->clear();
567     pMIDIKeyInfo[i].pEvents->clear();
568     pMIDIKeyInfo[i].KeyPressed = false;
569     pMIDIKeyInfo[i].Active = false;
570     pMIDIKeyInfo[i].pSelf = NULL;
571     }
572    
573     // reset all voices
574     for (Voice* pVoice = pVoicePool->first(); pVoice; pVoice = pVoicePool->next()) {
575     pVoice->Reset();
576     }
577    
578     // free all active keys
579     pActiveKeys->clear();
580    
581     // reset disk thread
582     pDiskThread->Reset();
583    
584     // delete all input events
585     pEventQueue->init();
586     }

  ViewVC Help
Powered by ViewVC