 165b814f5d
			
		
	
	
		165b814f5d
		
	
	
	
	
		
			
			this is necessary in order to get Furnace to build using CMake 4.0. you should do: git submodule deinit extern/portaudio
		
			
				
	
	
		
			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
 |