/[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 33 - (hide annotations) (download)
Mon Feb 16 19:30:42 2004 UTC (20 years, 3 months ago) by schoenebeck
Original Path: linuxsampler/trunk/src/audiothread.cpp
File size: 18489 byte(s)
* implemented bidirectional voice state transition, means voice state can
  switch arbitrary times between 'Sustained'<-->'Released' within it's life
  time, thus the release process of a voice can be cancelled
* src/eg_vca.cpp: extended envelope generator by additional states
  ('Attack_Hold', 'Decay_1' and 'Decay_2')
* applied patch from Vladimir Senkov which adds new command line parameters
  ('--jackout', '--alsaout' and '--samplerate')
* configure.in: fixed compiler warning

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 31 AudioThread::AudioThread(AudioIO* pAudioIO, DiskThread* pDiskThread, gig::Instrument* pInstrument) {
26 schoenebeck 32 this->pAudioIO = pAudioIO;
27     this->pDiskThread = pDiskThread;
28     this->pInstrument = pInstrument;
29     this->Pitch = 0;
30     Voice::pDiskThread = pDiskThread;
31     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 32 pMIDIKeyInfo[i].pActiveVoices = new RTEList<Voice>(pVoicePool);
42 schoenebeck 18 pMIDIKeyInfo[i].KeyPressed = false;
43 schoenebeck 33 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     // cache initial samples points (for actually needed samples)
60 schoenebeck 12 dmsg(1,("Caching initial samples..."));
61 schoenebeck 9 gig::Region* pRgn = this->pInstrument->GetFirstRegion();
62     while (pRgn) {
63     if (!pRgn->GetSample()->GetCache().Size) {
64 schoenebeck 12 dmsg(2,("C"));
65 schoenebeck 9 CacheInitialSamples(pRgn->GetSample());
66     }
67     for (uint i = 0; i < pRgn->DimensionRegions; i++) {
68     CacheInitialSamples(pRgn->pDimensionRegions[i]->pSample);
69     }
70    
71     pRgn = this->pInstrument->GetNextRegion();
72     }
73 senoner 10
74 schoenebeck 30 // initialize modulation system
75 schoenebeck 31 ModulationSystem::Initialize(pAudioIO->SampleRate(), pAudioIO->MaxSamplesPerCycle());
76 schoenebeck 30
77 senoner 10 // sustain pedal value
78 schoenebeck 12 PrevHoldCCValue = 0;
79     SustainPedal = 0;
80 senoner 10
81 schoenebeck 12 dmsg(1,("OK\n"));
82 schoenebeck 9 }
83    
84     AudioThread::~AudioThread() {
85 schoenebeck 30 ModulationSystem::Close();
86 schoenebeck 32 for (uint i = 0; i < 128; i++) {
87     if (pMIDIKeyInfo[i].pActiveVoices) delete pMIDIKeyInfo[i].pActiveVoices;
88 schoenebeck 33 if (pMIDIKeyInfo[i].pEvents) delete pMIDIKeyInfo[i].pEvents;
89 schoenebeck 9 }
90 schoenebeck 32 for (uint i = 0; i < ModulationSystem::destination_count; i++) {
91     if (pCCEvents[i]) delete pCCEvents[i];
92     }
93     delete[] pCCEvents;
94 schoenebeck 33 if (pEvents) delete pEvents;
95     if (pEventQueue) delete pEventQueue;
96     if (pEventPool) delete pEventPool;
97     if (pVoicePool) delete pVoicePool;
98     if (pActiveKeys) delete pActiveKeys;
99 schoenebeck 31 delete[] pAudioSumBuffer[0]; // this also frees the right channel buffer
100 schoenebeck 9 }
101    
102 schoenebeck 32 /**
103     * Let this engine proceed to render the given amount of sample points. The
104     * calculated audio data of all voices of this engine will be placed into
105     * the engine's audio sum buffer which has to be copied and eventually be
106     * converted to the appropriate value range by the audio output class (e.g.
107     * AlsaIO or JackIO) right after.
108     *
109     * @param Samples - number of sample points to be rendered
110     * @returns 0 on success
111     */
112 schoenebeck 31 int AudioThread::RenderAudio(uint Samples) {
113 schoenebeck 9
114 schoenebeck 32 // empty the event lists for the new fragment
115     pEvents->clear();
116     for (uint i = 0; i < ModulationSystem::destination_count; i++) {
117     pCCEvents[i]->clear();
118     }
119    
120     // read and copy events from input queue
121     ModulationSystem::Event Event;
122 schoenebeck 9 while (true) {
123 schoenebeck 32 if (!pEventQueue->pop(&Event)) break;
124     pEvents->alloc_assign(Event);
125     }
126 schoenebeck 9
127 schoenebeck 32
128     // update time of start and end of this audio fragment (as events' time stamps relate to this)
129     ModulationSystem::UpdateFragmentTime();
130    
131    
132     // process events
133     ModulationSystem::Event* pNextEvent = pEvents->first();
134     while (pNextEvent) {
135     ModulationSystem::Event* pEvent = pNextEvent;
136     pEvents->set_current(pEvent);
137     pNextEvent = pEvents->next();
138     switch (pEvent->Type) {
139     case ModulationSystem::event_type_note_on:
140 schoenebeck 31 dmsg(5,("Audio Thread: Note on received\n"));
141 schoenebeck 32 ProcessNoteOn(pEvent);
142 schoenebeck 31 break;
143 schoenebeck 32 case ModulationSystem::event_type_note_off:
144 schoenebeck 31 dmsg(5,("Audio Thread: Note off received\n"));
145 schoenebeck 32 ProcessNoteOff(pEvent);
146 schoenebeck 31 break;
147 schoenebeck 32 case ModulationSystem::event_type_control_change:
148 schoenebeck 31 dmsg(5,("Audio Thread: MIDI CC received\n"));
149 schoenebeck 32 ProcessControlChange(pEvent);
150 schoenebeck 31 break;
151 schoenebeck 32 case ModulationSystem::event_type_pitchbend:
152     dmsg(5,("Audio Thread: Pitchbend received\n"));
153     ProcessPitchbend(pEvent);
154     break;
155 schoenebeck 9 }
156 schoenebeck 31 }
157 schoenebeck 9
158    
159 schoenebeck 31 // zero out the output sum buffer (left and right channel)
160     memset(pAudioSumBuffer[0], 0, Samples * pAudioIO->Channels() * sizeof(float));
161 schoenebeck 9
162    
163 schoenebeck 31 // render audio from all active voices
164     int active_voices = 0;
165 schoenebeck 33 uint* piKey = pActiveKeys->first();
166     while (piKey) { // iterate through all active keys
167     midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
168     pActiveKeys->set_current(piKey);
169     piKey = pActiveKeys->next();
170    
171 schoenebeck 32 Voice* pVoiceNext = pKey->pActiveVoices->first();
172 schoenebeck 33 while (pVoiceNext) { // iterate through all voices on this key
173 schoenebeck 32 // already get next voice on key
174     Voice* pVoice = pVoiceNext;
175     pKey->pActiveVoices->set_current(pVoice);
176     pVoiceNext = pKey->pActiveVoices->next();
177    
178     // now render current voice
179     pVoice->Render(Samples);
180     if (pVoice->IsActive()) active_voices++; // still active
181 schoenebeck 31 else { // voice reached end, is now inactive
182 schoenebeck 32 KillVoice(pVoice); // remove voice from the list of active voices
183 schoenebeck 9 }
184     }
185 schoenebeck 33 pKey->pEvents->clear(); // free all events on the key
186 schoenebeck 31 }
187 schoenebeck 32
188 schoenebeck 33
189 schoenebeck 31 // write that to the disk thread class so that it can print it
190     // on the console for debugging purposes
191     ActiveVoiceCount = active_voices;
192     if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount;
193 schoenebeck 9
194    
195 schoenebeck 31 return 0;
196 schoenebeck 9 }
197    
198 schoenebeck 32 /**
199     * Will be called by the MIDIIn Thread to let the audio thread trigger a new
200     * voice for the given key.
201     *
202     * @param Key - MIDI key number of the triggered key
203     * @param Velocity - MIDI velocity value of the triggered key
204     */
205     void AudioThread::SendNoteOn(uint8_t Key, uint8_t Velocity) {
206     ModulationSystem::Event Event;
207     Event.Type = ModulationSystem::event_type_note_on;
208     Event.Key = Key;
209     Event.Velocity = Velocity;
210     if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
211     else dmsg(1,("AudioThread: Input event queue full!"));
212 schoenebeck 9 }
213    
214 schoenebeck 32 /**
215     * Will be called by the MIDIIn Thread to signal the audio thread to release
216     * voice(s) on the given key.
217     *
218     * @param Key - MIDI key number of the released key
219     * @param Velocity - MIDI release velocity value of the released key
220     */
221     void AudioThread::SendNoteOff(uint8_t Key, uint8_t Velocity) {
222     ModulationSystem::Event Event;
223     Event.Type = ModulationSystem::event_type_note_off;
224     Event.Key = Key;
225     Event.Velocity = Velocity;
226     if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
227     else dmsg(1,("AudioThread: Input event queue full!"));
228 schoenebeck 9 }
229    
230 schoenebeck 32 /**
231     * Will be called by the MIDIIn Thread to signal the audio thread to change
232     * the pitch value for all voices.
233     *
234     * @param Pitch - MIDI pitch value (-8192 ... +8191)
235     */
236     void AudioThread::SendPitchbend(int Pitch) {
237     ModulationSystem::Event Event;
238     Event.Type = ModulationSystem::event_type_pitchbend;
239     Event.Pitch = Pitch;
240     if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
241     else dmsg(1,("AudioThread: Input event queue full!"));
242 senoner 10 }
243    
244 schoenebeck 18 /**
245 schoenebeck 32 * Will be called by the MIDIIn Thread to signal the audio thread that a
246     * continuous controller value has changed.
247     *
248     * @param Controller - MIDI controller number of the occured control change
249     * @param Value - value of the control change
250     */
251     void AudioThread::SendControlChange(uint8_t Controller, uint8_t Value) {
252     ModulationSystem::Event Event;
253     Event.Type = ModulationSystem::event_type_control_change;
254     Event.Controller = Controller;
255     Event.Value = Value;
256     if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&Event);
257     else dmsg(1,("AudioThread: Input event queue full!"));
258     }
259    
260     /**
261 schoenebeck 18 * Assigns and triggers a new voice for the respective MIDI key.
262 schoenebeck 32 *
263     * @param pNoteOnEvent - key, velocity and time stamp of the event
264 schoenebeck 18 */
265 schoenebeck 32 void AudioThread::ProcessNoteOn(ModulationSystem::Event* pNoteOnEvent) {
266     midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Key];
267 schoenebeck 15
268 schoenebeck 32 pKey->KeyPressed = true; // the MIDI key was now pressed down
269 schoenebeck 33
270     // cancel release process of voices on this key if needed
271     if (pKey->Active && !SustainPedal) {
272     pNoteOnEvent->Type = ModulationSystem::event_type_cancel_release; // transform event type
273     pEvents->move(pNoteOnEvent, pKey->pEvents); // move event to the key's own event list
274     }
275    
276     // allocate a new voice for the key
277     Voice* pNewVoice = pKey->pActiveVoices->alloc();
278 schoenebeck 32 if (pNewVoice) {
279 schoenebeck 18 // launch the new voice
280 schoenebeck 33 if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument) < 0) {
281     dmsg(1,("Triggering new voice failed!\n"));
282     pKey->pActiveVoices->free(pNewVoice);
283 schoenebeck 18 }
284 schoenebeck 33 else if (!pKey->Active) { // mark as active key
285     pKey->Active = true;
286     pKey->pSelf = pActiveKeys->alloc();
287     *pKey->pSelf = pNoteOnEvent->Key;
288 schoenebeck 15 }
289 schoenebeck 9 }
290 schoenebeck 32 else std::cerr << "No free voice!" << std::endl << std::flush;
291 schoenebeck 9 }
292    
293 schoenebeck 15 /**
294     * Releases the voices on the given key if sustain pedal is not pressed.
295     * If sustain is pressed, the release of the note will be postponed until
296     * sustain pedal will be released or voice turned inactive by itself (e.g.
297     * due to completion of sample playback).
298 schoenebeck 32 *
299     * @param pNoteOffEvent - key, velocity and time stamp of the event
300 schoenebeck 15 */
301 schoenebeck 32 void AudioThread::ProcessNoteOff(ModulationSystem::Event* pNoteOffEvent) {
302     midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOffEvent->Key];
303    
304     pKey->KeyPressed = false; // the MIDI key was now released
305    
306 schoenebeck 33 // release voices on this key if needed
307     if (pKey->Active && !SustainPedal) {
308     pNoteOffEvent->Type = ModulationSystem::event_type_release; // transform event type
309     pEvents->move(pNoteOffEvent, pKey->pEvents); // move event to the key's own event list
310 schoenebeck 12 }
311     }
312 senoner 10
313 schoenebeck 15 /**
314 schoenebeck 32 * Moves pitchbend event from the general (input) event list to the pitch
315     * event list and converts absolute pitch value to delta pitch value.
316     *
317     * @param pPitchbendEvent - absolute pitch value and time stamp of the event
318     */
319     void AudioThread::ProcessPitchbend(ModulationSystem::Event* pPitchbendEvent) {
320     int currentPitch = pPitchbendEvent->Pitch;
321     pPitchbendEvent->Pitch -= this->Pitch; // convert to delta
322     this->Pitch = currentPitch; // store current absolute pitch value
323     pEvents->move(pPitchbendEvent, pCCEvents[ModulationSystem::destination_vco]);
324     }
325    
326     /**
327 schoenebeck 30 * Immediately kills the voice given with pVoice (no matter if sustain is
328     * pressed or not) and removes it from the MIDI key's list of active voice.
329 schoenebeck 33 * This method will e.g. be called if a voice went inactive by itself.
330 schoenebeck 32 *
331     * @param pVoice - points to the voice to be killed
332 schoenebeck 15 */
333 schoenebeck 30 void AudioThread::KillVoice(Voice* pVoice) {
334 schoenebeck 9 if (pVoice) {
335 schoenebeck 30 if (pVoice->IsActive()) pVoice->Kill();
336 senoner 10
337 schoenebeck 32 midi_key_info_t* pKey = &pMIDIKeyInfo[pVoice->MIDIKey];
338    
339     // free the voice object
340     pVoicePool->free(pVoice);
341 schoenebeck 15
342 schoenebeck 18 // check if there are no voices left on the MIDI key and update the key info if so
343 schoenebeck 32 if (pKey->pActiveVoices->is_empty()) {
344 schoenebeck 33 pKey->Active = false;
345     pActiveKeys->free(pKey->pSelf); // remove key from list of active keys
346     pKey->pSelf = NULL;
347 schoenebeck 18 dmsg(3,("Key has no more voices now\n"));
348 schoenebeck 15 }
349 schoenebeck 9 }
350 schoenebeck 15 else std::cerr << "Couldn't release voice! (pVoice == NULL)\n" << std::flush;
351 schoenebeck 9 }
352    
353 schoenebeck 32 /**
354     * Reacts on supported control change commands (e.g. pitch bend wheel,
355     * modulation wheel, aftertouch).
356     *
357     * @param pControlChangeEvent - controller, value and time stamp of the event
358     */
359     void AudioThread::ProcessControlChange(ModulationSystem::Event* pControlChangeEvent) {
360     dmsg(4,("AudioThread::ContinuousController cc=%d v=%d\n", pControlChangeEvent->Controller, pControlChangeEvent->Value));
361    
362     switch (pControlChangeEvent->Controller) {
363     case 64: {
364     if (pControlChangeEvent->Value >= 64 && PrevHoldCCValue < 64) {
365     dmsg(4,("PEDAL DOWN\n"));
366     SustainPedal = true;
367 schoenebeck 33
368     // cancel release process of voices if necessary
369     uint* piKey = pActiveKeys->first();
370     if (piKey) {
371     pControlChangeEvent->Type = ModulationSystem::event_type_cancel_release; // transform event type
372     while (piKey) {
373     midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
374     pActiveKeys->set_current(piKey);
375     piKey = pActiveKeys->next();
376     if (!pKey->KeyPressed) {
377     ModulationSystem::Event* pNewEvent = pKey->pEvents->alloc();
378     if (pNewEvent) *pNewEvent = *pControlChangeEvent; // copy event to the key's own event list
379     else dmsg(1,("Event pool emtpy!\n"));
380     }
381     }
382     pEvents->free(pControlChangeEvent); // free the original event
383     }
384 schoenebeck 32 }
385     if (pControlChangeEvent->Value < 64 && PrevHoldCCValue >= 64) {
386     dmsg(4,("PEDAL UP\n"));
387     SustainPedal = false;
388 schoenebeck 33
389     // release voices if their respective key is not pressed
390     uint* piKey = pActiveKeys->first();
391     if (piKey) {
392     pControlChangeEvent->Type = ModulationSystem::event_type_release; // transform event type
393     while (piKey) {
394     midi_key_info_t* pKey = &pMIDIKeyInfo[*piKey];
395     pActiveKeys->set_current(piKey);
396     piKey = pActiveKeys->next();
397     if (!pKey->KeyPressed) {
398     ModulationSystem::Event* pNewEvent = pKey->pEvents->alloc();
399     if (pNewEvent) *pNewEvent = *pControlChangeEvent; // copy event to the key's own event list
400     else dmsg(1,("Event pool emtpy!\n"));
401 schoenebeck 32 }
402 schoenebeck 18 }
403 schoenebeck 33 pEvents->free(pControlChangeEvent); // free the original event
404 schoenebeck 15 }
405 schoenebeck 33
406 schoenebeck 12 }
407 schoenebeck 32 PrevHoldCCValue = pControlChangeEvent->Value;
408     break;
409 schoenebeck 12 }
410 senoner 10 }
411     }
412    
413 schoenebeck 32 /**
414     * Caches a certain size at the beginning of the given sample in RAM. If the
415     * sample is very short, the whole sample will be loaded into RAM and thus
416     * no disk streaming is needed for this sample. Caching an initial part of
417     * samples is needed to compensate disk reading latency.
418     *
419     * @param pSample - points to the sample to be cached
420     */
421 schoenebeck 9 void AudioThread::CacheInitialSamples(gig::Sample* pSample) {
422     if (!pSample || pSample->GetCache().Size) return;
423     if (pSample->SamplesTotal <= NUM_RAM_PRELOAD_SAMPLES) {
424     // Sample is too short for disk streaming, so we load the whole
425     // sample into RAM and place 'pAudioIO->FragmentSize << MAX_PITCH'
426     // number of '0' samples (silence samples) behind the official buffer
427     // border, to allow the interpolator do it's work even at the end of
428     // the sample.
429 schoenebeck 31 gig::buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension((pAudioIO->MaxSamplesPerCycle() << MAX_PITCH) + 3);
430 schoenebeck 12 dmsg(4,("Cached %d Bytes, %d silence bytes.\n", buf.Size, buf.NullExtensionSize));
431 schoenebeck 9 }
432     else { // we only cache NUM_RAM_PRELOAD_SAMPLES and stream the other sample points from disk
433     pSample->LoadSampleData(NUM_RAM_PRELOAD_SAMPLES);
434     }
435    
436     if (!pSample->GetCache().Size) std::cerr << "Unable to cache sample - maybe memory full!" << std::endl << std::flush;
437     }

  ViewVC Help
Powered by ViewVC