65 |
InstrumentIdx = -1; |
InstrumentIdx = -1; |
66 |
InstrumentStat = -1; |
InstrumentStat = -1; |
67 |
|
|
68 |
|
AudioDeviceChannelLeft = -1; |
69 |
|
AudioDeviceChannelRight = -1; |
70 |
|
|
71 |
ResetInternal(); |
ResetInternal(); |
72 |
} |
} |
73 |
|
|
152 |
SustainPedal = false; |
SustainPedal = false; |
153 |
ActiveVoiceCount = 0; |
ActiveVoiceCount = 0; |
154 |
ActiveVoiceCountMax = 0; |
ActiveVoiceCountMax = 0; |
155 |
|
GlobalVolume = 1.0; |
156 |
|
|
157 |
// set all MIDI controller values to zero |
// set all MIDI controller values to zero |
158 |
memset(ControllerTable, 0x00, 128); |
memset(ControllerTable, 0x00, 128); |
282 |
throw LinuxSamplerException(msg); |
throw LinuxSamplerException(msg); |
283 |
} |
} |
284 |
|
|
285 |
|
this->AudioDeviceChannelLeft = 0; |
286 |
|
this->AudioDeviceChannelRight = 1; |
287 |
|
this->pOutputLeft = pAudioOutputDevice->Channel(0)->Buffer(); |
288 |
|
this->pOutputRight = pAudioOutputDevice->Channel(1)->Buffer(); |
289 |
|
this->MaxSamplesPerCycle = pAudioOutputDevice->MaxSamplesPerCycle(); |
290 |
|
this->SampleRate = pAudioOutputDevice->SampleRate(); |
291 |
|
|
292 |
// (re)create disk thread |
// (re)create disk thread |
293 |
if (this->pDiskThread) { |
if (this->pDiskThread) { |
294 |
this->pDiskThread->StopThread(); |
this->pDiskThread->StopThread(); |
302 |
|
|
303 |
for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) { |
for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) { |
304 |
pVoice->pDiskThread = this->pDiskThread; |
pVoice->pDiskThread = this->pDiskThread; |
|
pVoice->SetOutput(pAudioOut); |
|
305 |
dmsg(3,("d")); |
dmsg(3,("d")); |
306 |
} |
} |
307 |
pVoicePool->clear(); |
pVoicePool->clear(); |
339 |
AudioOutputDevice* olddevice = pAudioOutputDevice; |
AudioOutputDevice* olddevice = pAudioOutputDevice; |
340 |
pAudioOutputDevice = NULL; |
pAudioOutputDevice = NULL; |
341 |
olddevice->Disconnect(this); |
olddevice->Disconnect(this); |
342 |
|
AudioDeviceChannelLeft = -1; |
343 |
|
AudioDeviceChannelRight = -1; |
344 |
} |
} |
345 |
} |
} |
346 |
|
|
527 |
pEvents->move(pNoteOnEvent, pKey->pEvents); // move event to the key's own event list |
pEvents->move(pNoteOnEvent, pKey->pEvents); // move event to the key's own event list |
528 |
} |
} |
529 |
|
|
530 |
// allocate a new voice for the key |
// allocate and trigger a new voice for the key |
531 |
Voice* pNewVoice = pKey->pActiveVoices->alloc(); |
LaunchVoice(pNoteOnEvent); |
|
if (pNewVoice) { |
|
|
// launch the new voice |
|
|
if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument) < 0) { |
|
|
dmsg(1,("Triggering new voice failed!\n")); |
|
|
pKey->pActiveVoices->free(pNewVoice); |
|
|
} |
|
|
else if (!pKey->Active) { // mark as active key |
|
|
pKey->Active = true; |
|
|
pKey->pSelf = pActiveKeys->alloc(); |
|
|
*pKey->pSelf = pNoteOnEvent->Key; |
|
|
} |
|
|
} |
|
|
else std::cerr << "No free voice!" << std::endl << std::flush; |
|
532 |
} |
} |
533 |
|
|
534 |
/** |
/** |
563 |
} |
} |
564 |
|
|
565 |
/** |
/** |
566 |
|
* Allocates and triggers a new voice. This method will usually be |
567 |
|
* called by the ProcessNoteOn() method and by the voices itself |
568 |
|
* (e.g. to spawn further voices on the same key for layered sounds). |
569 |
|
* |
570 |
|
* @param pNoteOnEvent - key, velocity and time stamp of the event |
571 |
|
* @param iLayer - layer index for the new voice (optional - only |
572 |
|
* in case of layered sounds of course) |
573 |
|
*/ |
574 |
|
void Engine::LaunchVoice(Event* pNoteOnEvent, int iLayer) { |
575 |
|
midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Key]; |
576 |
|
|
577 |
|
// allocate a new voice for the key |
578 |
|
Voice* pNewVoice = pKey->pActiveVoices->alloc(); |
579 |
|
if (pNewVoice) { |
580 |
|
// launch the new voice |
581 |
|
if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument, iLayer) < 0) { |
582 |
|
dmsg(1,("Triggering new voice failed!\n")); |
583 |
|
pKey->pActiveVoices->free(pNewVoice); |
584 |
|
} |
585 |
|
else if (!pKey->Active) { // mark as active key |
586 |
|
pKey->Active = true; |
587 |
|
pKey->pSelf = pActiveKeys->alloc(); |
588 |
|
*pKey->pSelf = pNoteOnEvent->Key; |
589 |
|
} |
590 |
|
} |
591 |
|
else std::cerr << "No free voice!" << std::endl << std::flush; |
592 |
|
} |
593 |
|
|
594 |
|
/** |
595 |
* Immediately kills the voice given with pVoice (no matter if sustain is |
* Immediately kills the voice given with pVoice (no matter if sustain is |
596 |
* pressed or not) and removes it from the MIDI key's list of active voice. |
* pressed or not) and removes it from the MIDI key's list of active voice. |
597 |
* This method will e.g. be called if a voice went inactive by itself. |
* This method will e.g. be called if a voice went inactive by itself. |
703 |
GlobalVolume = f; |
GlobalVolume = f; |
704 |
} |
} |
705 |
|
|
706 |
|
uint Engine::Channels() { |
707 |
|
return 2; |
708 |
|
} |
709 |
|
|
710 |
|
void Engine::SetOutputChannel(uint EngineAudioChannel, uint AudioDeviceChannel) { |
711 |
|
AudioChannel* pChannel = pAudioOutputDevice->Channel(AudioDeviceChannel); |
712 |
|
if (!pChannel) throw AudioOutputException("Invalid audio output device channel " + ToString(AudioDeviceChannel)); |
713 |
|
switch (EngineAudioChannel) { |
714 |
|
case 0: // left output channel |
715 |
|
pOutputLeft = pChannel->Buffer(); |
716 |
|
AudioDeviceChannelLeft = AudioDeviceChannel; |
717 |
|
break; |
718 |
|
case 1: // right output channel |
719 |
|
pOutputRight = pChannel->Buffer(); |
720 |
|
AudioDeviceChannelRight = AudioDeviceChannel; |
721 |
|
break; |
722 |
|
default: |
723 |
|
throw AudioOutputException("Invalid engine audio channel " + ToString(EngineAudioChannel)); |
724 |
|
} |
725 |
|
} |
726 |
|
|
727 |
|
int Engine::OutputChannel(uint EngineAudioChannel) { |
728 |
|
switch (EngineAudioChannel) { |
729 |
|
case 0: // left channel |
730 |
|
return AudioDeviceChannelLeft; |
731 |
|
case 1: // right channel |
732 |
|
return AudioDeviceChannelRight; |
733 |
|
default: |
734 |
|
throw AudioOutputException("Invalid engine audio channel " + ToString(EngineAudioChannel)); |
735 |
|
} |
736 |
|
} |
737 |
|
|
738 |
uint Engine::VoiceCount() { |
uint Engine::VoiceCount() { |
739 |
return ActiveVoiceCount; |
return ActiveVoiceCount; |
740 |
} |
} |
784 |
} |
} |
785 |
|
|
786 |
String Engine::Version() { |
String Engine::Version() { |
787 |
String s = "$Revision: 1.7 $"; |
String s = "$Revision: 1.9 $"; |
788 |
return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword |
return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword |
789 |
} |
} |
790 |
|
|