mirror of
				https://github.com/cookiengineer/audacity
				synced 2025-11-03 23:53:55 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			309 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			309 lines
		
	
	
		
			6.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
 | 
						|
 |