308 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			308 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|   | #include "portaudiocpp/System.hxx"
 | ||
|  | 
 | ||
|  | #include <cstddef>
 | ||
|  | #include <cassert>
 | ||
|  | 
 | ||
|  | #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
 |