#include "portaudiocpp/System.hxx" #include #include #include "portaudiocpp/HostApi.hxx" #include "portaudiocpp/Device.hxx" #include "portaudiocpp/Stream.hxx" #include "portaudiocpp/Exception.hxx" #include "portaudiocpp/SystemHostApiIterator.hxx" #include "portaudiocpp/SystemDeviceIterator.hxx" namespace portaudio { // ----------------------------------------------------------------------------------- // Static members: System *System::instance_ = NULL; int System::initCount_ = 0; HostApi **System::hostApis_ = NULL; Device **System::devices_ = NULL; Device *System::nullDevice_ = NULL; // ----------------------------------------------------------------------------------- int System::version() { return Pa_GetVersion(); } const char *System::versionText() { return Pa_GetVersionText(); } void System::initialize() { ++initCount_; if (initCount_ == 1) { // Create singleton: assert(instance_ == NULL); instance_ = new System(); // Initialize the PortAudio system: { PaError err = Pa_Initialize(); if (err != paNoError) throw PaException(err); } // Create and populate device array: { int numDevices = instance().deviceCount(); devices_ = new Device*[numDevices]; for (int i = 0; i < numDevices; ++i) devices_[i] = new Device(i); } // Create and populate host api array: { int numHostApis = instance().hostApiCount(); hostApis_ = new HostApi*[numHostApis]; for (int i = 0; i < numHostApis; ++i) hostApis_[i] = new HostApi(i); } // Create null device: nullDevice_ = new Device(paNoDevice); } } void System::terminate() { PaError err = paNoError; if (initCount_ == 1) { // Destroy null device: delete nullDevice_; // Destroy host api array: { if (hostApis_ != NULL) { int numHostApis = instance().hostApiCount(); for (int i = 0; i < numHostApis; ++i) delete hostApis_[i]; delete[] hostApis_; hostApis_ = NULL; } } // Destroy device array: { if (devices_ != NULL) { int numDevices = instance().deviceCount(); for (int i = 0; i < numDevices; ++i) delete devices_[i]; delete[] devices_; devices_ = NULL; } } // Terminate the PortAudio system: assert(instance_ != NULL); err = Pa_Terminate(); // Destroy singleton: delete instance_; instance_ = NULL; } if (initCount_ > 0) --initCount_; if (err != paNoError) throw PaException(err); } System &System::instance() { assert(exists()); return *instance_; } bool System::exists() { return (instance_ != NULL); } // ----------------------------------------------------------------------------------- System::HostApiIterator System::hostApisBegin() { System::HostApiIterator tmp; tmp.ptr_ = &hostApis_[0]; // begin (first element) return tmp; } System::HostApiIterator System::hostApisEnd() { int count = hostApiCount(); System::HostApiIterator tmp; tmp.ptr_ = &hostApis_[count]; // end (one past last element) return tmp; } HostApi &System::defaultHostApi() { PaHostApiIndex defaultHostApi = Pa_GetDefaultHostApi(); if (defaultHostApi < 0) throw PaException(defaultHostApi); return *hostApis_[defaultHostApi]; } HostApi &System::hostApiByTypeId(PaHostApiTypeId type) { PaHostApiIndex index = Pa_HostApiTypeIdToHostApiIndex(type); if (index < 0) throw PaException(index); return *hostApis_[index]; } HostApi &System::hostApiByIndex(PaHostApiIndex index) { if (index < 0 || index >= hostApiCount()) throw PaException(paInternalError); return *hostApis_[index]; } int System::hostApiCount() { PaHostApiIndex count = Pa_GetHostApiCount(); if (count < 0) throw PaException(count); return count; } // ----------------------------------------------------------------------------------- System::DeviceIterator System::devicesBegin() { DeviceIterator tmp; tmp.ptr_ = &devices_[0]; return tmp; } System::DeviceIterator System::devicesEnd() { int count = deviceCount(); DeviceIterator tmp; tmp.ptr_ = &devices_[count]; return tmp; } ////// /// Returns the System's default input Device, or the null Device if none /// was available. ////// Device &System::defaultInputDevice() { PaDeviceIndex index = Pa_GetDefaultInputDevice(); return deviceByIndex(index); } ////// /// Returns the System's default output Device, or the null Device if none /// was available. ////// Device &System::defaultOutputDevice() { PaDeviceIndex index = Pa_GetDefaultOutputDevice(); return deviceByIndex(index); } ////// /// Returns the Device for the given index. /// Will throw a paInternalError equivalent PaException if the given index /// is out of range. ////// Device &System::deviceByIndex(PaDeviceIndex index) { if (index < -1 || index >= deviceCount()) { throw PaException(paInternalError); } if (index == -1) return System::instance().nullDevice(); return *devices_[index]; } int System::deviceCount() { PaDeviceIndex count = Pa_GetDeviceCount(); if (count < 0) throw PaException(count); return count; } Device &System::nullDevice() { return *nullDevice_; } // ----------------------------------------------------------------------------------- void System::sleep(long msec) { Pa_Sleep(msec); } int System::sizeOfSample(PaSampleFormat format) { PaError err = Pa_GetSampleSize(format); if (err < 0) { throw PaException(err); return 0; } return err; } // ----------------------------------------------------------------------------------- System::System() { // (left blank intentionally) } System::~System() { // (left blank intentionally) } // ----------------------------------------------------------------------------------- } // namespace portaudio