/*************************************************************************** * * * LinuxSampler - modular, streaming capable sampler * * * * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * * Copyright (C) 2005 Christian Schoenebeck * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * * MA 02111-1307 USA * ***************************************************************************/ #include "AudioOutputDeviceFactory.h" #include "AudioOutputDevice.h" namespace LinuxSampler { // *************** ParameterActive *************** // * AudioOutputDevice::ParameterActive::ParameterActive() : DeviceCreationParameterBool() { InitWithDefault(); } AudioOutputDevice::ParameterActive::ParameterActive(String s) : DeviceCreationParameterBool(s) { } String AudioOutputDevice::ParameterActive::Description() { return "Enable / disable device"; } bool AudioOutputDevice::ParameterActive::Fix() { return false; } bool AudioOutputDevice::ParameterActive::Mandatory() { return false; } std::map AudioOutputDevice::ParameterActive::DependsAsParameters() { return std::map(); } optional AudioOutputDevice::ParameterActive::DefaultAsBool(std::map Parameters) { return true; } void AudioOutputDevice::ParameterActive::OnSetValue(bool b) throw (LinuxSamplerException) { if (b) ((AudioOutputDevice*)pDevice)->Play(); else ((AudioOutputDevice*)pDevice)->Stop(); } String AudioOutputDevice::ParameterActive::Name() { return "ACTIVE"; } // *************** ParameterSampleRate *************** // * AudioOutputDevice::ParameterSampleRate::ParameterSampleRate() : DeviceCreationParameterInt() { InitWithDefault(); } AudioOutputDevice::ParameterSampleRate::ParameterSampleRate(String s) : DeviceCreationParameterInt(s) { } String AudioOutputDevice::ParameterSampleRate::Description() { return "Output sample rate"; } bool AudioOutputDevice::ParameterSampleRate::Fix() { return true; } bool AudioOutputDevice::ParameterSampleRate::Mandatory() { return false; } std::map AudioOutputDevice::ParameterSampleRate::DependsAsParameters() { return std::map(); } optional AudioOutputDevice::ParameterSampleRate::DefaultAsInt(std::map Parameters) { return 44100; } optional AudioOutputDevice::ParameterSampleRate::RangeMinAsInt(std::map Parameters) { return optional::nothing; } optional AudioOutputDevice::ParameterSampleRate::RangeMaxAsInt(std::map Parameters) { return optional::nothing; } std::vector AudioOutputDevice::ParameterSampleRate::PossibilitiesAsInt(std::map Parameters) { return std::vector(); } void AudioOutputDevice::ParameterSampleRate::OnSetValue(int i) throw (LinuxSamplerException) { /* cannot happen, as parameter is fix */ } String AudioOutputDevice::ParameterSampleRate::Name() { return "SAMPLERATE"; } // *************** ParameterChannels *************** // * AudioOutputDevice::ParameterChannels::ParameterChannels() : DeviceCreationParameterInt() { InitWithDefault(); } AudioOutputDevice::ParameterChannels::ParameterChannels(String s) : DeviceCreationParameterInt(s) { } String AudioOutputDevice::ParameterChannels::Description() { return "Number of output channels"; } bool AudioOutputDevice::ParameterChannels::Fix() { return false; } bool AudioOutputDevice::ParameterChannels::Mandatory() { return false; } std::map AudioOutputDevice::ParameterChannels::DependsAsParameters() { return std::map(); } optional AudioOutputDevice::ParameterChannels::DefaultAsInt(std::map Parameters) { return 2; } optional AudioOutputDevice::ParameterChannels::RangeMinAsInt(std::map Parameters) { return optional::nothing; } optional AudioOutputDevice::ParameterChannels::RangeMaxAsInt(std::map Parameters) { return optional::nothing; } std::vector AudioOutputDevice::ParameterChannels::PossibilitiesAsInt(std::map Parameters) { return std::vector(); } void AudioOutputDevice::ParameterChannels::OnSetValue(int i) throw (LinuxSamplerException) { ((AudioOutputDevice*)pDevice)->AcquireChannels(i); } String AudioOutputDevice::ParameterChannels::Name() { return "CHANNELS"; } // *************** AudioOutputDevice *************** // * AudioOutputDevice::AudioOutputDevice(std::map DriverParameters) { this->Parameters = DriverParameters; } AudioOutputDevice::~AudioOutputDevice() { // delete all audio channels { std::vector::iterator iter = Channels.begin(); while (iter != Channels.end()) { Channels.erase(iter); delete *iter; iter++; } } // delete all device parameters { std::map::iterator iter = Parameters.begin(); while (iter != Parameters.end()) { Parameters.erase(iter); delete iter->second; iter++; } } } void AudioOutputDevice::Connect(Engine* pEngine) { if (Engines.find(pEngine) == Engines.end()) { Engines.insert(pEngine); // make sure the engine knows about the connection //pEngine->Connect(this); } } void AudioOutputDevice::Disconnect(Engine* pEngine) { if (Engines.find(pEngine) != Engines.end()) { // if clause to prevent disconnect loop Engines.erase(pEngine); // make sure the engine knows about the disconnection //pEngine->DisconnectAudioOutputDevice(); } } AudioChannel* AudioOutputDevice::Channel(uint ChannelIndex) { return (ChannelIndex < Channels.size()) ? Channels[ChannelIndex] : NULL; } void AudioOutputDevice::AcquireChannels(uint Channels) { if (Channels > this->Channels.size()) { for (int c = this->Channels.size(); c < Channels; c++) { this->Channels.push_back(CreateChannel(c)); } } } std::map AudioOutputDevice::DeviceParameters() { return Parameters; } int AudioOutputDevice::RenderAudio(uint Samples) { if (Channels.empty()) return 0; // reset all channels with silence { std::vector::iterator iterChannels = Channels.begin(); std::vector::iterator end = Channels.end(); for (; iterChannels != end; iterChannels++) (*iterChannels)->Clear(); // zero out audio buffer } int result = 0; // let all connected engines render audio for the current audio fragment cycle #if CONFIG_RT_EXCEPTIONS try #endif // CONFIG_RT_EXCEPTIONS { std::set::iterator iterEngine = Engines.begin(); std::set::iterator end = Engines.end(); for (; iterEngine != end; iterEngine++) { int res = (*iterEngine)->RenderAudio(Samples); if (res != 0) result = res; } } #if CONFIG_RT_EXCEPTIONS catch (std::runtime_error se) { std::cerr << "std::runtime_error: " << se.what() << std::endl << std::flush; exit(EXIT_FAILURE); } #endif // CONFIG_RT_EXCEPTIONS return result; } int AudioOutputDevice::RenderSilence(uint Samples) { if (Channels.empty()) return 0; // reset all channels with silence { std::vector::iterator iterChannels = Channels.begin(); std::vector::iterator end = Channels.end(); for (; iterChannels != end; iterChannels++) (*iterChannels)->Clear(); // zero out audio buffer } return 0; } } // namespace LinuxSampler