From f61f0a2fa9906f4d1f8f13f773c2bb27796e8fab Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Thu, 4 Oct 2007 14:19:20 +0000 Subject: Added explicit initialization of buffers in DsHandle (gps). --- RtAudio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'RtAudio.cpp') diff --git a/RtAudio.cpp b/RtAudio.cpp index dd76b59..64ffaa5 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -3223,7 +3223,7 @@ struct DsHandle { HANDLE condition; DsHandle() - :drainCounter(0), internalDrain(false) { id[0] = 0, id[1] = 0; xrun[0] = false; xrun[1] = false; bufferPointer[0] = 0; bufferPointer[1] = 0; } + :drainCounter(0), internalDrain(false) { id[0] = 0; id[1] = 0; buffer[0] = 0; buffer[1] = 0; xrun[0] = false; xrun[1] = false; bufferPointer[0] = 0; bufferPointer[1] = 0; } }; /* -- cgit v1.2.3 From 9ee3d84d670af9bc98899b7eef05f039003a6dba Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Thu, 22 Nov 2007 01:07:39 +0000 Subject: Updates to windoze asio and ds based on user feedback (gps). --- RtAudio.cpp | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'RtAudio.cpp') diff --git a/RtAudio.cpp b/RtAudio.cpp index 64ffaa5..fc4418e 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -2528,15 +2528,27 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne return FAILURE; } - // Set the sample rate. - result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate ); + // Get the current sample rate + ASIOSampleRate currentRate; + result = ASIOGetSampleRate( ¤tRate ); if ( result != ASE_OK ) { drivers.removeCurrentDriver(); - errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ")."; + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate."; errorText_ = errorStream_.str(); return FAILURE; } + // Set the sample rate only if necessary + if ( currentRate != sampleRate ) { + result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate ); + if ( result != ASE_OK ) { + drivers.removeCurrentDriver(); + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } + } + // Determine the driver data type. ASIOChannelInfo channelInfo; channelInfo.channel = 0; @@ -2696,7 +2708,8 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne stream_.doConvertBuffer[mode] = true; // Allocate necessary internal buffers - unsigned long bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat ); + unsigned long bufferBytes; + bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat ); stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 ); if ( stream_.userBuffer[mode] == NULL ) { errorText_ = "RtApiAsio::probeDeviceOpen: error allocating user buffer memory."; @@ -2958,8 +2971,8 @@ bool RtApiAsio :: callbackEvent( long bufferIndex ) handle->internalDrain = true; } - unsigned int bufferBytes, i, j; - unsigned int nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1]; + unsigned int nChannels, bufferBytes, i, j; + nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1]; if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { bufferBytes = stream_.bufferSize * formatBytes( stream_.deviceFormat[0] ); @@ -3187,6 +3200,14 @@ static const char* getAsioErrorString( ASIOError result ) #include #include +#if defined(__MINGW32__) +// missing from latest mingw winapi +#define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */ +#define WAVE_FORMAT_96S08 0x00020000 /* 96 kHz, Stereo, 8-bit */ +#define WAVE_FORMAT_96M16 0x00040000 /* 96 kHz, Mono, 16-bit */ +#define WAVE_FORMAT_96S16 0x00080000 /* 96 kHz, Stereo, 16-bit */ +#endif + #define MINIMUM_DEVICE_BUFFER_SIZE 32768 #ifdef _MSC_VER // if Microsoft Visual C++ @@ -3247,7 +3268,7 @@ RtApiDs::RtDsStatistics RtApiDs::getDsStatistics() // Declarations for utility functions, callbacks, and structures // specific to the DirectSound implementation. -static bool CALLBACK deviceCountCallback( LPGUID lpguid, +static BOOL CALLBACK deviceCountCallback( LPGUID lpguid, LPCTSTR description, LPCTSTR module, LPVOID lpContext ); @@ -4665,7 +4686,7 @@ std::string convertTChar( LPCTSTR name ) return s; } -static bool CALLBACK deviceCountCallback( LPGUID lpguid, +static BOOL CALLBACK deviceCountCallback( LPGUID lpguid, LPCTSTR description, LPCTSTR module, LPVOID lpContext ) @@ -4678,7 +4699,7 @@ static bool CALLBACK deviceCountCallback( LPGUID lpguid, LPDIRECTSOUNDCAPTURE object; hr = DirectSoundCaptureCreate( lpguid, &object, NULL ); - if ( hr != DS_OK ) return true; + if ( hr != DS_OK ) return TRUE; caps.dwSize = sizeof(caps); hr = object->GetCaps( &caps ); @@ -4692,7 +4713,7 @@ static bool CALLBACK deviceCountCallback( LPGUID lpguid, DSCAPS caps; LPDIRECTSOUND object; hr = DirectSoundCreate( lpguid, &object, NULL ); - if ( hr != DS_OK ) return true; + if ( hr != DS_OK ) return TRUE; caps.dwSize = sizeof(caps); hr = object->GetCaps( &caps ); @@ -4703,20 +4724,20 @@ static bool CALLBACK deviceCountCallback( LPGUID lpguid, object->Release(); } - if ( info->getDefault && lpguid == NULL ) return false; + if ( info->getDefault && lpguid == NULL ) return FALSE; if ( info->findIndex && info->counter > info->index ) { info->id = lpguid; info->name = convertTChar( description ); - return false; + return FALSE; } - return true; + return TRUE; } static char* getErrorString( int code ) { - switch (code) { + switch ( code ) { case DSERR_ALLOCATED: return "Already allocated"; -- cgit v1.2.3 From 1e492d19f956d99e3315a3600170d6f1d9869cab Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Fri, 30 Nov 2007 17:20:32 +0000 Subject: Various documentation, configuration, and minor naming changes (gps). --- RtAudio.cpp | 22 +++++++++++----------- configure.ac | 2 ++ doc/doxygen/probe.txt | 2 +- doc/doxygen/tutorial.txt | 4 ++-- 4 files changed, 16 insertions(+), 14 deletions(-) (limited to 'RtAudio.cpp') diff --git a/RtAudio.cpp b/RtAudio.cpp index fc4418e..8b6402b 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -3268,7 +3268,7 @@ RtApiDs::RtDsStatistics RtApiDs::getDsStatistics() // Declarations for utility functions, callbacks, and structures // specific to the DirectSound implementation. -static BOOL CALLBACK deviceCountCallback( LPGUID lpguid, +static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid, LPCTSTR description, LPCTSTR module, LPVOID lpContext ); @@ -3309,7 +3309,7 @@ unsigned int RtApiDs :: getDefaultInputDevice( void ) { // Count output devices. EnumInfo info; - HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &info ); + HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &info ); if ( FAILED( result ) ) { errorStream_ << "RtApiDs::getDefaultOutputDevice: error (" << getErrorString( result ) << ") counting output devices!"; errorText_ = errorStream_.str(); @@ -3320,7 +3320,7 @@ unsigned int RtApiDs :: getDefaultInputDevice( void ) // Now enumerate input devices until we find the id = NULL. info.isInput = true; info.getDefault = true; - result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &info ); + result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &info ); if ( FAILED( result ) ) { errorStream_ << "RtApiDs::getDefaultInputDevice: error (" << getErrorString( result ) << ") enumerating input devices!"; errorText_ = errorStream_.str(); @@ -3337,7 +3337,7 @@ unsigned int RtApiDs :: getDefaultOutputDevice( void ) // Enumerate output devices until we find the id = NULL. EnumInfo info; info.getDefault = true; - HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &info ); + HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &info ); if ( FAILED( result ) ) { errorStream_ << "RtApiDs::getDefaultOutputDevice: error (" << getErrorString( result ) << ") enumerating output devices!"; errorText_ = errorStream_.str(); @@ -3353,7 +3353,7 @@ unsigned int RtApiDs :: getDeviceCount( void ) { // Count DirectSound devices. EnumInfo info; - HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &info ); + HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &info ); if ( FAILED( result ) ) { errorStream_ << "RtApiDs::getDeviceCount: error (" << getErrorString( result ) << ") enumerating output devices!"; errorText_ = errorStream_.str(); @@ -3362,7 +3362,7 @@ unsigned int RtApiDs :: getDeviceCount( void ) // Count DirectSoundCapture devices. info.isInput = true; - result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &info ); + result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &info ); if ( FAILED( result ) ) { errorStream_ << "RtApiDs::getDeviceCount: error (" << getErrorString( result ) << ") enumerating input devices!"; errorText_ = errorStream_.str(); @@ -3387,7 +3387,7 @@ RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device ) EnumInfo dsinfo; dsinfo.findIndex = true; dsinfo.index = device; - HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &dsinfo ); + HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &dsinfo ); if ( FAILED( result ) ) { errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") enumerating output devices!"; errorText_ = errorStream_.str(); @@ -3445,7 +3445,7 @@ RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device ) probeInput: dsinfo.isInput = true; - result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &dsinfo ); + result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &dsinfo ); if ( FAILED( result ) ) { errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") enumerating input devices!"; errorText_ = errorStream_.str(); @@ -3555,7 +3555,7 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned EnumInfo dsinfo; dsinfo.findIndex = true; dsinfo.index = device; - HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &dsinfo ); + HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &dsinfo ); if ( FAILED( result ) ) { errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") enumerating output devices!"; errorText_ = errorStream_.str(); @@ -3571,7 +3571,7 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned } else { // mode == INPUT dsinfo.isInput = true; - HRESULT result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &dsinfo ); + HRESULT result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &dsinfo ); if ( FAILED( result ) ) { errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") enumerating input devices!"; errorText_ = errorStream_.str(); @@ -4686,7 +4686,7 @@ std::string convertTChar( LPCTSTR name ) return s; } -static BOOL CALLBACK deviceCountCallback( LPGUID lpguid, +static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid, LPCTSTR description, LPCTSTR module, LPVOID lpContext ) diff --git a/configure.ac b/configure.ac index 78eb85a..e0fac8b 100644 --- a/configure.ac +++ b/configure.ac @@ -123,6 +123,7 @@ case $host in AC_ARG_WITH(ds, [ --with-ds = choose DirectSound API support (windoze only)], [AC_SUBST( sound_api, [-D__WINDOWS_DS__] ) AC_MSG_RESULT(using DirectSound)], ) if test $sound_api = -D__WINDOWS_DS__; then audio_apis="-D__WINDOWS_DS__ $audio_apis" + LIBS="-ldsound -lwinmm $LIBS" fi # If no audio api flags specified, use DirectSound @@ -130,6 +131,7 @@ case $host in AC_SUBST( sound_api, [-D__WINDOWS_DS__] ) AC_MSG_RESULT(using DirectSound) audio_apis="-D__WINDOWS_DS__" + LIBS="-ldsound -lwinmm $LIBS" fi ;; diff --git a/doc/doxygen/probe.txt b/doc/doxygen/probe.txt index 761ae34..9fce97b 100644 --- a/doc/doxygen/probe.txt +++ b/doc/doxygen/probe.txt @@ -4,7 +4,7 @@ A programmer may wish to query the available audio device capabilities before de \code -// probe.cpp +// audioprobe.cpp #include #include "RtAudio.h" diff --git a/doc/doxygen/tutorial.txt b/doc/doxygen/tutorial.txt index 76b28b0..2ab0f1f 100644 --- a/doc/doxygen/tutorial.txt +++ b/doc/doxygen/tutorial.txt @@ -17,7 +17,7 @@ RtAudio incorporates the concept of audio streams, which represent audio output \section whatsnew What's New (Version 4.0) -RtAudio V4 represents a significant rewrite of the code and includes a number of API and functionality changes form previous versions. A partial list of the changes includes: +RtAudio V4 represents a significant rewrite of the code and includes a number of API and functionality changes from previous versions. A partial list of the changes includes: - new support for non-interleaved user data - additional input/output parameter specifications, including channel offset - new support for dynamic connection of devices @@ -28,7 +28,7 @@ RtAudio V4 represents a significant rewrite of the code and includes a number of - discontinued support of blocking functionality - discontinued support of SGI -Devices are now re-enumerated every time the RtAudio::getDeviceCount(), RtAudio::getDeviceInfo(), and RtAudio::openStream() functions are called. This allows for the proper identification of hot-pluggable (USB, Firewire, ...) devices while a given RtAudio instance exists. +Devices are now re-enumerated every time the RtAudio::getDeviceCount(), RtAudio::getDeviceInfo(), and RtAudio::openStream() functions are called. This allows for the proper identification of hot-pluggable (USB, Firewire, ...) devices that are connected after an RtAudio instance is created. \section download Download -- cgit v1.2.3 From f6708f5edc4719fdc5a54cfcb11159d197dd6dcd Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Tue, 4 Dec 2007 20:09:57 +0000 Subject: Various configure changes for MinGW (gps). --- Makefile.in | 7 +- RtAudio.cpp | 41 +- RtAudio.h | 2 + asio/asio.cpp | 257 ---- asio/asio.h | 1054 ----------------- asio/asiodrivers.cpp | 186 --- asio/asiodrivers.h | 41 - asio/asiodrvr.h | 76 -- asio/asiolist.cpp | 268 ----- asio/asiolist.h | 46 - asio/asiosys.h | 82 -- asio/ginclude.h | 38 - asio/iasiodrv.h | 37 - asio/iasiothiscallresolver.cpp | 563 --------- asio/iasiothiscallresolver.h | 201 ---- configure.ac | 25 +- include/asio.cpp | 257 ++++ include/asio.h | 1054 +++++++++++++++++ include/asiodrivers.cpp | 186 +++ include/asiodrivers.h | 41 + include/asiodrvr.h | 76 ++ include/asiolist.cpp | 268 +++++ include/asiolist.h | 46 + include/asiosys.h | 82 ++ include/dsound.h | 2369 +++++++++++++++++++++++++++++++++++++ include/ginclude.h | 38 + include/iasiodrv.h | 37 + include/iasiothiscallresolver.cpp | 563 +++++++++ include/iasiothiscallresolver.h | 201 ++++ include/soundcard.h | 2061 ++++++++++++++++++++++++++++++++ oss/soundcard.h | 2061 -------------------------------- tests/Makefile.in | 25 +- tests/Windows/rtaudio.dsw | 12 +- tests/playsaw.cpp | 3 +- tests/testall.cpp | 3 +- 35 files changed, 7352 insertions(+), 4955 deletions(-) delete mode 100644 asio/asio.cpp delete mode 100644 asio/asio.h delete mode 100644 asio/asiodrivers.cpp delete mode 100644 asio/asiodrivers.h delete mode 100644 asio/asiodrvr.h delete mode 100644 asio/asiolist.cpp delete mode 100644 asio/asiolist.h delete mode 100644 asio/asiosys.h delete mode 100644 asio/ginclude.h delete mode 100644 asio/iasiodrv.h delete mode 100644 asio/iasiothiscallresolver.cpp delete mode 100644 asio/iasiothiscallresolver.h create mode 100644 include/asio.cpp create mode 100644 include/asio.h create mode 100644 include/asiodrivers.cpp create mode 100644 include/asiodrivers.h create mode 100644 include/asiodrvr.h create mode 100644 include/asiolist.cpp create mode 100644 include/asiolist.h create mode 100644 include/asiosys.h create mode 100644 include/dsound.h create mode 100644 include/ginclude.h create mode 100644 include/iasiodrv.h create mode 100644 include/iasiothiscallresolver.cpp create mode 100644 include/iasiothiscallresolver.h create mode 100644 include/soundcard.h delete mode 100644 oss/soundcard.h (limited to 'RtAudio.cpp') diff --git a/Makefile.in b/Makefile.in index dfebb0e..57df82b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3,7 +3,7 @@ RM = /bin/rm -OBJECTS = RtAudio.o +OBJECTS = RtAudio.o @objects@ LIBRARY = librtaudio.a @@ -13,7 +13,7 @@ RANLIB = @RANLIB@ DEFS = @debug@ DEFS += @audio_apis@ -CFLAGS = @cflags@ +CFLAGS = @cflags@ -Iinclude CFLAGS += @warn@ all : $(LIBRARY) @@ -28,6 +28,9 @@ $(LIBRARY): $(OBJECTS) %.o : %.cpp $(CC) $(CFLAGS) $(DEFS) -c $(<) -o $@ +%.o : include/%.cpp + $(CC) $(CFLAGS) $(DEFS) -c $(<) -o $@ + clean : -rm -f $(LIBRARY) -rm -f $(OBJECTS) diff --git a/RtAudio.cpp b/RtAudio.cpp index 8b6402b..f5b324f 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -2291,10 +2291,10 @@ bool RtApiJack :: callbackEvent( unsigned long nframes ) // on information found in // http://www.cs.wustl.edu/~schmidt/win32-cv-1.html. -#include "asio/asiosys.h" -#include "asio/asio.h" -#include "asio/iasiothiscallresolver.h" -#include "asio/asiodrivers.h" +#include "asiosys.h" +#include "asio.h" +#include "iasiothiscallresolver.h" +#include "asiodrivers.h" #include AsioDrivers drivers; @@ -2366,11 +2366,14 @@ RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device ) error( RtError::INVALID_USE ); } - // Don't probe if a stream is already open. + // If a stream is already open, we cannot probe other devices. Thus, use the saved results. if ( stream_.state != STREAM_CLOSED ) { - errorText_ = "RtApiAsio::getDeviceInfo: unable to probe driver while a stream is open."; - error( RtError::WARNING ); - return info; + if ( device >= devices_.size() ) { + errorText_ = "RtApiAsio::getDeviceInfo: device ID was not present before stream was opened."; + error( RtError::WARNING ); + return info; + } + return devices_[ device ]; } char driverName[32]; @@ -2463,6 +2466,16 @@ void bufferSwitch( long index, ASIOBool processNow ) object->callbackEvent( index ); } +void RtApiAsio :: saveDeviceInfo( void ) +{ + devices_.clear(); + + unsigned int nDevices = getDeviceCount(); + devices_.resize( nDevices ); + for ( unsigned int i=0; isaveDeviceInfo(); + // Only load the driver once for duplex stream. if ( mode != INPUT || stream_.mode != OUTPUT ) { if ( !drivers.loadDriver( driverName ) ) { @@ -3879,6 +3898,7 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned } // Set various stream parameters + DsHandle *handle = 0; stream_.nDeviceChannels[mode] = channels + firstChannel; stream_.nUserChannels[mode] = channels; stream_.bufferSize = *bufferSize; @@ -3928,7 +3948,6 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned } // Allocate our DsHandle structures for the stream. - DsHandle *handle; if ( stream_.apiHandle == 0 ) { try { handle = new DsHandle; @@ -4099,7 +4118,7 @@ void RtApiDs :: startStream() duplexPrerollBytes = (int) ( 0.5 * stream_.sampleRate * formatBytes( stream_.deviceFormat[1] ) * stream_.nDeviceChannels[1] ); } - HRESULT result; + HRESULT result = 0; if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { //statistics.outputFrameSize = formatBytes( stream_.deviceFormat[0] ) * stream_.nDeviceChannels[0]; @@ -4145,7 +4164,7 @@ void RtApiDs :: stopStream() MUTEX_LOCK( &stream_.mutex ); - HRESULT result; + HRESULT result = 0; LPVOID audioPtr; DWORD dataLen; DsHandle *handle = (DsHandle *) stream_.apiHandle; diff --git a/RtAudio.h b/RtAudio.h index 5b6dd30..1bb1336 100644 --- a/RtAudio.h +++ b/RtAudio.h @@ -794,6 +794,8 @@ public: private: + std::vector devices_; + void saveDeviceInfo( void ); bool coInitialized_; bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, diff --git a/asio/asio.cpp b/asio/asio.cpp deleted file mode 100644 index b241663..0000000 --- a/asio/asio.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* - Steinberg Audio Stream I/O API - (c) 1996, Steinberg Soft- und Hardware GmbH - - asio.cpp - - asio functions entries which translate the - asio interface to the asiodrvr class methods -*/ - -#include -#include "asiosys.h" // platform definition -#include "asio.h" - -#if MAC -#include "asiodrvr.h" - -#pragma export on - -AsioDriver *theAsioDriver = 0; - -extern "C" -{ - -long main() -{ - return 'ASIO'; -} - -#elif WINDOWS - -#include "windows.h" -#include "iasiodrv.h" -#include "asiodrivers.h" - -IASIO *theAsioDriver = 0; -extern AsioDrivers *asioDrivers; - -#elif SGI || SUN || BEOS || LINUX -#include "asiodrvr.h" -static AsioDriver *theAsioDriver = 0; -#endif - -//----------------------------------------------------------------------------------------------------- -ASIOError ASIOInit(ASIODriverInfo *info) -{ -#if MAC || SGI || SUN || BEOS || LINUX - if(theAsioDriver) - { - delete theAsioDriver; - theAsioDriver = 0; - } - info->driverVersion = 0; - strcpy(info->name, "No ASIO Driver"); - theAsioDriver = getDriver(); - if(!theAsioDriver) - { - strcpy(info->errorMessage, "Not enough memory for the ASIO driver!"); - return ASE_NotPresent; - } - if(!theAsioDriver->init(info->sysRef)) - { - theAsioDriver->getErrorMessage(info->errorMessage); - delete theAsioDriver; - theAsioDriver = 0; - return ASE_NotPresent; - } - strcpy(info->errorMessage, "No ASIO Driver Error"); - theAsioDriver->getDriverName(info->name); - info->driverVersion = theAsioDriver->getDriverVersion(); - return ASE_OK; - -#else - - info->driverVersion = 0; - strcpy(info->name, "No ASIO Driver"); - if(theAsioDriver) // must be loaded! - { - if(!theAsioDriver->init(info->sysRef)) - { - theAsioDriver->getErrorMessage(info->errorMessage); - theAsioDriver = 0; - return ASE_NotPresent; - } - - strcpy(info->errorMessage, "No ASIO Driver Error"); - theAsioDriver->getDriverName(info->name); - info->driverVersion = theAsioDriver->getDriverVersion(); - return ASE_OK; - } - return ASE_NotPresent; - -#endif // !MAC -} - -ASIOError ASIOExit(void) -{ - if(theAsioDriver) - { -#if WINDOWS - asioDrivers->removeCurrentDriver(); -#else - delete theAsioDriver; -#endif - } - theAsioDriver = 0; - return ASE_OK; -} - -ASIOError ASIOStart(void) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->start(); -} - -ASIOError ASIOStop(void) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->stop(); -} - -ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels) -{ - if(!theAsioDriver) - { - *numInputChannels = *numOutputChannels = 0; - return ASE_NotPresent; - } - return theAsioDriver->getChannels(numInputChannels, numOutputChannels); -} - -ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency) -{ - if(!theAsioDriver) - { - *inputLatency = *outputLatency = 0; - return ASE_NotPresent; - } - return theAsioDriver->getLatencies(inputLatency, outputLatency); -} - -ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity) -{ - if(!theAsioDriver) - { - *minSize = *maxSize = *preferredSize = *granularity = 0; - return ASE_NotPresent; - } - return theAsioDriver->getBufferSize(minSize, maxSize, preferredSize, granularity); -} - -ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->canSampleRate(sampleRate); -} - -ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->getSampleRate(currentRate); -} - -ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->setSampleRate(sampleRate); -} - -ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources) -{ - if(!theAsioDriver) - { - *numSources = 0; - return ASE_NotPresent; - } - return theAsioDriver->getClockSources(clocks, numSources); -} - -ASIOError ASIOSetClockSource(long reference) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->setClockSource(reference); -} - -ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->getSamplePosition(sPos, tStamp); -} - -ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info) -{ - if(!theAsioDriver) - { - info->channelGroup = -1; - info->type = ASIOSTInt16MSB; - strcpy(info->name, "None"); - return ASE_NotPresent; - } - return theAsioDriver->getChannelInfo(info); -} - -ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels, - long bufferSize, ASIOCallbacks *callbacks) -{ - if(!theAsioDriver) - { - ASIOBufferInfo *info = bufferInfos; - for(long i = 0; i < numChannels; i++, info++) - info->buffers[0] = info->buffers[1] = 0; - return ASE_NotPresent; - } - return theAsioDriver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks); -} - -ASIOError ASIODisposeBuffers(void) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->disposeBuffers(); -} - -ASIOError ASIOControlPanel(void) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->controlPanel(); -} - -ASIOError ASIOFuture(long selector, void *opt) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->future(selector, opt); -} - -ASIOError ASIOOutputReady(void) -{ - if(!theAsioDriver) - return ASE_NotPresent; - return theAsioDriver->outputReady(); -} - -#if MAC -} // extern "C" -#pragma export off -#endif - - diff --git a/asio/asio.h b/asio/asio.h deleted file mode 100644 index 8ec811f..0000000 --- a/asio/asio.h +++ /dev/null @@ -1,1054 +0,0 @@ -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -/* - Steinberg Audio Stream I/O API - (c) 1997 - 2005, Steinberg Media Technologies GmbH - - ASIO Interface Specification v 2.1 - - 2005 - Added support for DSD sample data (in cooperation with Sony) - - - basic concept is an i/o synchronous double-buffer scheme: - - on bufferSwitch(index == 0), host will read/write: - - after ASIOStart(), the - read first input buffer A (index 0) - | will be invalid (empty) - * ------------------------ - |------------------------|-----------------------| - | | | - | Input Buffer A (0) | Input Buffer B (1) | - | | | - |------------------------|-----------------------| - | | | - | Output Buffer A (0) | Output Buffer B (1) | - | | | - |------------------------|-----------------------| - * ------------------------- - | before calling ASIOStart(), - write host will have filled output - buffer B (index 1) already - - *please* take special care of proper statement of input - and output latencies (see ASIOGetLatencies()), these - control sequencer sync accuracy - -*/ - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -/* - -prototypes summary: - -ASIOError ASIOInit(ASIODriverInfo *info); -ASIOError ASIOExit(void); -ASIOError ASIOStart(void); -ASIOError ASIOStop(void); -ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels); -ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency); -ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); -ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate); -ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate); -ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate); -ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources); -ASIOError ASIOSetClockSource(long reference); -ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp); -ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info); -ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels, - long bufferSize, ASIOCallbacks *callbacks); -ASIOError ASIODisposeBuffers(void); -ASIOError ASIOControlPanel(void); -void *ASIOFuture(long selector, void *params); -ASIOError ASIOOutputReady(void); - -*/ - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -#ifndef __ASIO_H -#define __ASIO_H - -// force 4 byte alignment -#if defined(_MSC_VER) && !defined(__MWERKS__) -#pragma pack(push,4) -#elif PRAGMA_ALIGN_SUPPORTED -#pragma options align = native -#endif - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Type definitions -//- - - - - - - - - - - - - - - - - - - - - - - - - - -// number of samples data type is 64 bit integer -#if NATIVE_INT64 - typedef long long int ASIOSamples; -#else - typedef struct ASIOSamples { - unsigned long hi; - unsigned long lo; - } ASIOSamples; -#endif - -// Timestamp data type is 64 bit integer, -// Time format is Nanoseconds. -#if NATIVE_INT64 - typedef long long int ASIOTimeStamp ; -#else - typedef struct ASIOTimeStamp { - unsigned long hi; - unsigned long lo; - } ASIOTimeStamp; -#endif - -// Samplerates are expressed in IEEE 754 64 bit double float, -// native format as host computer -#if IEEE754_64FLOAT - typedef double ASIOSampleRate; -#else - typedef struct ASIOSampleRate { - char ieee[8]; - } ASIOSampleRate; -#endif - -// Boolean values are expressed as long -typedef long ASIOBool; -enum { - ASIOFalse = 0, - ASIOTrue = 1 -}; - -// Sample Types are expressed as long -typedef long ASIOSampleType; -enum { - ASIOSTInt16MSB = 0, - ASIOSTInt24MSB = 1, // used for 20 bits as well - ASIOSTInt32MSB = 2, - ASIOSTFloat32MSB = 3, // IEEE 754 32 bit float - ASIOSTFloat64MSB = 4, // IEEE 754 64 bit double float - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can be more easily used with these - ASIOSTInt32MSB16 = 8, // 32 bit data with 16 bit alignment - ASIOSTInt32MSB18 = 9, // 32 bit data with 18 bit alignment - ASIOSTInt32MSB20 = 10, // 32 bit data with 20 bit alignment - ASIOSTInt32MSB24 = 11, // 32 bit data with 24 bit alignment - - ASIOSTInt16LSB = 16, - ASIOSTInt24LSB = 17, // used for 20 bits as well - ASIOSTInt32LSB = 18, - ASIOSTFloat32LSB = 19, // IEEE 754 32 bit float, as found on Intel x86 architecture - ASIOSTFloat64LSB = 20, // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - ASIOSTInt32LSB16 = 24, // 32 bit data with 18 bit alignment - ASIOSTInt32LSB18 = 25, // 32 bit data with 18 bit alignment - ASIOSTInt32LSB20 = 26, // 32 bit data with 20 bit alignment - ASIOSTInt32LSB24 = 27, // 32 bit data with 24 bit alignment - - // ASIO DSD format. - ASIOSTDSDInt8LSB1 = 32, // DSD 1 bit data, 8 samples per byte. First sample in Least significant bit. - ASIOSTDSDInt8MSB1 = 33, // DSD 1 bit data, 8 samples per byte. First sample in Most significant bit. - ASIOSTDSDInt8NER8 = 40, // DSD 8 bit data, 1 sample per byte. No Endianness required. - - ASIOSTLastEntry -}; - -/*----------------------------------------------------------------------------- -// DSD operation and buffer layout -// Definition by Steinberg/Sony Oxford. -// -// We have tried to treat DSD as PCM and so keep a consistant structure across -// the ASIO interface. -// -// DSD's sample rate is normally referenced as a multiple of 44.1Khz, so -// the standard sample rate is refered to as 64Fs (or 2.8224Mhz). We looked -// at making a special case for DSD and adding a field to the ASIOFuture that -// would allow the user to select the Over Sampleing Rate (OSR) as a seperate -// entity but decided in the end just to treat it as a simple value of -// 2.8224Mhz and use the standard interface to set it. -// -// The second problem was the "word" size, in PCM the word size is always a -// greater than or equal to 8 bits (a byte). This makes life easy as we can -// then pack the samples into the "natural" size for the machine. -// In DSD the "word" size is 1 bit. This is not a major problem and can easily -// be dealt with if we ensure that we always deal with a multiple of 8 samples. -// -// DSD brings with it another twist to the Endianness religion. How are the -// samples packed into the byte. It would be nice to just say the most significant -// bit is always the first sample, however there would then be a performance hit -// on little endian machines. Looking at how some of the processing goes... -// Little endian machines like the first sample to be in the Least Significant Bit, -// this is because when you write it to memory the data is in the correct format -// to be shifted in and out of the words. -// Big endian machine prefer the first sample to be in the Most Significant Bit, -// again for the same reasion. -// -// And just when things were looking really muddy there is a proposed extension to -// DSD that uses 8 bit word sizes. It does not care what endianness you use. -// -// Switching the driver between DSD and PCM mode -// ASIOFuture allows for extending the ASIO API quite transparently. -// See kAsioSetIoFormat, kAsioGetIoFormat, kAsioCanDoIoFormat -// -//-----------------------------------------------------------------------------*/ - - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Error codes -//- - - - - - - - - - - - - - - - - - - - - - - - - - -typedef long ASIOError; -enum { - ASE_OK = 0, // This value will be returned whenever the call succeeded - ASE_SUCCESS = 0x3f4847a0, // unique success return value for ASIOFuture calls - ASE_NotPresent = -1000, // hardware input or output is not present or available - ASE_HWMalfunction, // hardware is malfunctioning (can be returned by any ASIO function) - ASE_InvalidParameter, // input parameter invalid - ASE_InvalidMode, // hardware is in a bad mode or used in a bad mode - ASE_SPNotAdvancing, // hardware is not running when sample position is inquired - ASE_NoClock, // sample clock or rate cannot be determined or is not present - ASE_NoMemory // not enough memory for completing the request -}; - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Time Info support -//- - - - - - - - - - - - - - - - - - - - - - - - - - -typedef struct ASIOTimeCode -{ - double speed; // speed relation (fraction of nominal speed) - // optional; set to 0. or 1. if not supported - ASIOSamples timeCodeSamples; // time in samples - unsigned long flags; // some information flags (see below) - char future[64]; -} ASIOTimeCode; - -typedef enum ASIOTimeCodeFlags -{ - kTcValid = 1, - kTcRunning = 1 << 1, - kTcReverse = 1 << 2, - kTcOnspeed = 1 << 3, - kTcStill = 1 << 4, - - kTcSpeedValid = 1 << 8 -} ASIOTimeCodeFlags; - -typedef struct AsioTimeInfo -{ - double speed; // absolute speed (1. = nominal) - ASIOTimeStamp systemTime; // system time related to samplePosition, in nanoseconds - // on mac, must be derived from Microseconds() (not UpTime()!) - // on windows, must be derived from timeGetTime() - ASIOSamples samplePosition; - ASIOSampleRate sampleRate; // current rate - unsigned long flags; // (see below) - char reserved[12]; -} AsioTimeInfo; - -typedef enum AsioTimeInfoFlags -{ - kSystemTimeValid = 1, // must always be valid - kSamplePositionValid = 1 << 1, // must always be valid - kSampleRateValid = 1 << 2, - kSpeedValid = 1 << 3, - - kSampleRateChanged = 1 << 4, - kClockSourceChanged = 1 << 5 -} AsioTimeInfoFlags; - -typedef struct ASIOTime // both input/output -{ - long reserved[4]; // must be 0 - struct AsioTimeInfo timeInfo; // required - struct ASIOTimeCode timeCode; // optional, evaluated if (timeCode.flags & kTcValid) -} ASIOTime; - -/* - -using time info: -it is recommended to use the new method with time info even if the asio -device does not support timecode; continuous calls to ASIOGetSamplePosition -and ASIOGetSampleRate are avoided, and there is a more defined relationship -between callback time and the time info. - -see the example below. -to initiate time info mode, after you have received the callbacks pointer in -ASIOCreateBuffers, you will call the asioMessage callback with kAsioSupportsTimeInfo -as the argument. if this returns 1, host has accepted time info mode. -now host expects the new callback bufferSwitchTimeInfo to be used instead -of the old bufferSwitch method. the ASIOTime structure is assumed to be valid -and accessible until the callback returns. - -using time code: -if the device supports reading time code, it will call host's asioMessage callback -with kAsioSupportsTimeCode as the selector. it may then fill the according -fields and set the kTcValid flag. -host will call the future method with the kAsioEnableTimeCodeRead selector when -it wants to enable or disable tc reading by the device. you should also support -the kAsioCanTimeInfo and kAsioCanTimeCode selectors in ASIOFuture (see example). - -note: -the AsioTimeInfo/ASIOTimeCode pair is supposed to work in both directions. -as a matter of convention, the relationship between the sample -position counter and the time code at buffer switch time is -(ignoring offset between tc and sample pos when tc is running): - -on input: sample 0 -> input buffer sample 0 -> time code 0 -on output: sample 0 -> output buffer sample 0 -> time code 0 - -this means that for 'real' calculations, one has to take into account -the according latencies. - -example: - -ASIOTime asioTime; - -in createBuffers() -{ - memset(&asioTime, 0, sizeof(ASIOTime)); - AsioTimeInfo* ti = &asioTime.timeInfo; - ti->sampleRate = theSampleRate; - ASIOTimeCode* tc = &asioTime.timeCode; - tc->speed = 1.; - timeInfoMode = false; - canTimeCode = false; - if(callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0) == 1) - { - timeInfoMode = true; -#if kCanTimeCode - if(callbacks->asioMessage(kAsioSupportsTimeCode, 0, 0, 0) == 1) - canTimeCode = true; -#endif - } -} - -void switchBuffers(long doubleBufferIndex, bool processNow) -{ - if(timeInfoMode) - { - AsioTimeInfo* ti = &asioTime.timeInfo; - ti->flags = kSystemTimeValid | kSamplePositionValid | kSampleRateValid; - ti->systemTime = theNanoSeconds; - ti->samplePosition = theSamplePosition; - if(ti->sampleRate != theSampleRate) - ti->flags |= kSampleRateChanged; - ti->sampleRate = theSampleRate; - -#if kCanTimeCode - if(canTimeCode && timeCodeEnabled) - { - ASIOTimeCode* tc = &asioTime.timeCode; - tc->timeCodeSamples = tcSamples; // tc in samples - tc->flags = kTcValid | kTcRunning | kTcOnspeed; // if so... - } - ASIOTime* bb = callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse); -#else - callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse); -#endif - } - else - callbacks->bufferSwitch(doubleBufferIndex, ASIOFalse); -} - -ASIOError ASIOFuture(long selector, void *params) -{ - switch(selector) - { - case kAsioEnableTimeCodeRead: - timeCodeEnabled = true; - return ASE_SUCCESS; - case kAsioDisableTimeCodeRead: - timeCodeEnabled = false; - return ASE_SUCCESS; - case kAsioCanTimeInfo: - return ASE_SUCCESS; - #if kCanTimeCode - case kAsioCanTimeCode: - return ASE_SUCCESS; - #endif - } - return ASE_NotPresent; -}; - -*/ - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// application's audio stream handler callbacks -//- - - - - - - - - - - - - - - - - - - - - - - - - - -typedef struct ASIOCallbacks -{ - void (*bufferSwitch) (long doubleBufferIndex, ASIOBool directProcess); - // bufferSwitch indicates that both input and output are to be processed. - // the current buffer half index (0 for A, 1 for B) determines - // - the output buffer that the host should start to fill. the other buffer - // will be passed to output hardware regardless of whether it got filled - // in time or not. - // - the input buffer that is now filled with incoming data. Note that - // because of the synchronicity of i/o, the input always has at - // least one buffer latency in relation to the output. - // directProcess suggests to the host whether it should immedeately - // start processing (directProcess == ASIOTrue), or whether its process - // should be deferred because the call comes from a very low level - // (for instance, a high level priority interrupt), and direct processing - // would cause timing instabilities for the rest of the system. If in doubt, - // directProcess should be set to ASIOFalse. - // Note: bufferSwitch may be called at interrupt time for highest efficiency. - - void (*sampleRateDidChange) (ASIOSampleRate sRate); - // gets called when the AudioStreamIO detects a sample rate change - // If sample rate is unknown, 0 is passed (for instance, clock loss - // when externally synchronized). - - long (*asioMessage) (long selector, long value, void* message, double* opt); - // generic callback for various purposes, see selectors below. - // note this is only present if the asio version is 2 or higher - - ASIOTime* (*bufferSwitchTimeInfo) (ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess); - // new callback with time info. makes ASIOGetSamplePosition() and various - // calls to ASIOGetSampleRate obsolete, - // and allows for timecode sync etc. to be preferred; will be used if - // the driver calls asioMessage with selector kAsioSupportsTimeInfo. -} ASIOCallbacks; - -// asioMessage selectors -enum -{ - kAsioSelectorSupported = 1, // selector in , returns 1L if supported, - // 0 otherwise - kAsioEngineVersion, // returns engine (host) asio implementation version, - // 2 or higher - kAsioResetRequest, // request driver reset. if accepted, this - // will close the driver (ASIO_Exit() ) and - // re-open it again (ASIO_Init() etc). some - // drivers need to reconfigure for instance - // when the sample rate changes, or some basic - // changes have been made in ASIO_ControlPanel(). - // returns 1L; note the request is merely passed - // to the application, there is no way to determine - // if it gets accepted at this time (but it usually - // will be). - kAsioBufferSizeChange, // not yet supported, will currently always return 0L. - // for now, use kAsioResetRequest instead. - // once implemented, the new buffer size is expected - // in , and on success returns 1L - kAsioResyncRequest, // the driver went out of sync, such that - // the timestamp is no longer valid. this - // is a request to re-start the engine and - // slave devices (sequencer). returns 1 for ok, - // 0 if not supported. - kAsioLatenciesChanged, // the drivers latencies have changed. The engine - // will refetch the latencies. - kAsioSupportsTimeInfo, // if host returns true here, it will expect the - // callback bufferSwitchTimeInfo to be called instead - // of bufferSwitch - kAsioSupportsTimeCode, // - kAsioMMCCommand, // unused - value: number of commands, message points to mmc commands - kAsioSupportsInputMonitor, // kAsioSupportsXXX return 1 if host supports this - kAsioSupportsInputGain, // unused and undefined - kAsioSupportsInputMeter, // unused and undefined - kAsioSupportsOutputGain, // unused and undefined - kAsioSupportsOutputMeter, // unused and undefined - kAsioOverload, // driver detected an overload - - kAsioNumMessageSelectors -}; - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// (De-)Construction -//- - - - - - - - - - - - - - - - - - - - - - - - - - -typedef struct ASIODriverInfo -{ - long asioVersion; // currently, 2 - long driverVersion; // driver specific - char name[32]; - char errorMessage[124]; - void *sysRef; // on input: system reference - // (Windows: application main window handle, Mac & SGI: 0) -} ASIODriverInfo; - -ASIOError ASIOInit(ASIODriverInfo *info); -/* Purpose: - Initialize the AudioStreamIO. - Parameter: - info: pointer to an ASIODriver structure: - - asioVersion: - - on input, the host version. *** Note *** this is 0 for earlier asio - implementations, and the asioMessage callback is implemeted - only if asioVersion is 2 or greater. sorry but due to a design fault - the driver doesn't have access to the host version in ASIOInit :-( - added selector for host (engine) version in the asioMessage callback - so we're ok from now on. - - on return, asio implementation version. - older versions are 1 - if you support this version (namely, ASIO_outputReady() ) - this should be 2 or higher. also see the note in - ASIO_getTimeStamp() ! - - version: on return, the driver version (format is driver specific) - - name: on return, a null-terminated string containing the driver's name - - error message: on return, should contain a user message describing - the type of error that occured during ASIOInit(), if any. - - sysRef: platform specific - Returns: - If neither input nor output is present ASE_NotPresent - will be returned. - ASE_NoMemory, ASE_HWMalfunction are other possible error conditions -*/ - -ASIOError ASIOExit(void); -/* Purpose: - Terminates the AudioStreamIO. - Parameter: - None. - Returns: - If neither input nor output is present ASE_NotPresent - will be returned. - Notes: this implies ASIOStop() and ASIODisposeBuffers(), - meaning that no host callbacks must be accessed after ASIOExit(). -*/ - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Start/Stop -//- - - - - - - - - - - - - - - - - - - - - - - - - - -ASIOError ASIOStart(void); -/* Purpose: - Start input and output processing synchronously. - This will - - reset the sample counter to zero - - start the hardware (both input and output) - The first call to the hosts' bufferSwitch(index == 0) then tells - the host to read from input buffer A (index 0), and start - processing to output buffer A while output buffer B (which - has been filled by the host prior to calling ASIOStart()) - is possibly sounding (see also ASIOGetLatencies()) - Parameter: - None. - Returns: - If neither input nor output is present, ASE_NotPresent - will be returned. - If the hardware fails to start, ASE_HWMalfunction will be returned. - Notes: - There is no restriction on the time that ASIOStart() takes - to perform (that is, it is not considered a realtime trigger). -*/ - -ASIOError ASIOStop(void); -/* Purpose: - Stops input and output processing altogether. - Parameter: - None. - Returns: - If neither input nor output is present ASE_NotPresent - will be returned. - Notes: - On return from ASIOStop(), the driver must in no - case call the hosts' bufferSwitch() routine. -*/ - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Inquiry methods and sample rate -//- - - - - - - - - - - - - - - - - - - - - - - - - - -ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels); -/* Purpose: - Returns number of individual input/output channels. - Parameter: - numInputChannels will hold the number of available input channels - numOutputChannels will hold the number of available output channels - Returns: - If no input/output is present ASE_NotPresent will be returned. - If only inputs, or only outputs are available, the according - other parameter will be zero, and ASE_OK is returned. -*/ - -ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency); -/* Purpose: - Returns the input and output latencies. This includes - device specific delays, like FIFOs etc. - Parameter: - inputLatency will hold the 'age' of the first sample frame - in the input buffer when the hosts reads it in bufferSwitch() - (this is theoretical, meaning it does not include the overhead - and delay between the actual physical switch, and the time - when bufferSitch() enters). - This will usually be the size of one block in sample frames, plus - device specific latencies. - - outputLatency will specify the time between the buffer switch, - and the time when the next play buffer will start to sound. - The next play buffer is defined as the one the host starts - processing after (or at) bufferSwitch(), indicated by the - index parameter (0 for buffer A, 1 for buffer B). - It will usually be either one block, if the host writes directly - to a dma buffer, or two or more blocks if the buffer is 'latched' by - the driver. As an example, on ASIOStart(), the host will have filled - the play buffer at index 1 already; when it gets the callback (with - the parameter index == 0), this tells it to read from the input - buffer 0, and start to fill the play buffer 0 (assuming that now - play buffer 1 is already sounding). In this case, the output - latency is one block. If the driver decides to copy buffer 1 - at that time, and pass it to the hardware at the next slot (which - is most commonly done, but should be avoided), the output latency - becomes two blocks instead, resulting in a total i/o latency of at least - 3 blocks. As memory access is the main bottleneck in native dsp processing, - and to acheive less latency, it is highly recommended to try to avoid - copying (this is also why the driver is the owner of the buffers). To - summarize, the minimum i/o latency can be acheived if the input buffer - is processed by the host into the output buffer which will physically - start to sound on the next time slice. Also note that the host expects - the bufferSwitch() callback to be accessed for each time slice in order - to retain sync, possibly recursively; if it fails to process a block in - time, it will suspend its operation for some time in order to recover. - Returns: - If no input/output is present ASE_NotPresent will be returned. -*/ - -ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); -/* Purpose: - Returns min, max, and preferred buffer sizes for input/output - Parameter: - minSize will hold the minimum buffer size - maxSize will hold the maxium possible buffer size - preferredSize will hold the preferred buffer size (a size which - best fits performance and hardware requirements) - granularity will hold the granularity at which buffer sizes - may differ. Usually, the buffer size will be a power of 2; - in this case, granularity will hold -1 on return, signalling - possible buffer sizes starting from minSize, increased in - powers of 2 up to maxSize. - Returns: - If no input/output is present ASE_NotPresent will be returned. - Notes: - When minimum and maximum buffer size are equal, - the preferred buffer size has to be the same value as well; granularity - should be 0 in this case. -*/ - -ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate); -/* Purpose: - Inquires the hardware for the available sample rates. - Parameter: - sampleRate is the rate in question. - Returns: - If the inquired sample rate is not supported, ASE_NoClock will be returned. - If no input/output is present ASE_NotPresent will be returned. -*/ -ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate); -/* Purpose: - Get the current sample Rate. - Parameter: - currentRate will hold the current sample rate on return. - Returns: - If sample rate is unknown, sampleRate will be 0 and ASE_NoClock will be returned. - If no input/output is present ASE_NotPresent will be returned. - Notes: -*/ - -ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate); -/* Purpose: - Set the hardware to the requested sample Rate. If sampleRate == 0, - enable external sync. - Parameter: - sampleRate: on input, the requested rate - Returns: - If sampleRate is unknown ASE_NoClock will be returned. - If the current clock is external, and sampleRate is != 0, - ASE_InvalidMode will be returned - If no input/output is present ASE_NotPresent will be returned. - Notes: -*/ - -typedef struct ASIOClockSource -{ - long index; // as used for ASIOSetClockSource() - long associatedChannel; // for instance, S/PDIF or AES/EBU - long associatedGroup; // see channel groups (ASIOGetChannelInfo()) - ASIOBool isCurrentSource; // ASIOTrue if this is the current clock source - char name[32]; // for user selection -} ASIOClockSource; - -ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources); -/* Purpose: - Get the available external audio clock sources - Parameter: - clocks points to an array of ASIOClockSource structures: - - index: this is used to identify the clock source - when ASIOSetClockSource() is accessed, should be - an index counting from zero - - associatedInputChannel: the first channel of an associated - input group, if any. - - associatedGroup: the group index of that channel. - groups of channels are defined to seperate for - instance analog, S/PDIF, AES/EBU, ADAT connectors etc, - when present simultaniously. Note that associated channel - is enumerated according to numInputs/numOutputs, means it - is independant from a group (see also ASIOGetChannelInfo()) - inputs are associated to a clock if the physical connection - transfers both data and clock (like S/PDIF, AES/EBU, or - ADAT inputs). if there is no input channel associated with - the clock source (like Word Clock, or internal oscillator), both - associatedChannel and associatedGroup should be set to -1. - - isCurrentSource: on exit, ASIOTrue if this is the current clock - source, ASIOFalse else - - name: a null-terminated string for user selection of the available sources. - numSources: - on input: the number of allocated array members - on output: the number of available clock sources, at least - 1 (internal clock generator). - Returns: - If no input/output is present ASE_NotPresent will be returned. - Notes: -*/ - -ASIOError ASIOSetClockSource(long index); -/* Purpose: - Set the audio clock source - Parameter: - index as obtained from an inquiry to ASIOGetClockSources() - Returns: - If no input/output is present ASE_NotPresent will be returned. - If the clock can not be selected because an input channel which - carries the current clock source is active, ASE_InvalidMode - *may* be returned (this depends on the properties of the driver - and/or hardware). - Notes: - Should *not* return ASE_NoClock if there is no clock signal present - at the selected source; this will be inquired via ASIOGetSampleRate(). - It should call the host callback procedure sampleRateHasChanged(), - if the switch causes a sample rate change, or if no external clock - is present at the selected source. -*/ - -ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp); -/* Purpose: - Inquires the sample position/time stamp pair. - Parameter: - sPos will hold the sample position on return. The sample - position is reset to zero when ASIOStart() gets called. - tStamp will hold the system time when the sample position - was latched. - Returns: - If no input/output is present, ASE_NotPresent will be returned. - If there is no clock, ASE_SPNotAdvancing will be returned. - Notes: - - in order to be able to synchronise properly, - the sample position / time stamp pair must refer to the current block, - that is, the engine will call ASIOGetSamplePosition() in its bufferSwitch() - callback and expect the time for the current block. thus, when requested - in the very first bufferSwitch after ASIO_Start(), the sample position - should be zero, and the time stamp should refer to the very time where - the stream was started. it also means that the sample position must be - block aligned. the driver must ensure proper interpolation if the system - time can not be determined for the block position. the driver is responsible - for precise time stamps as it usually has most direct access to lower - level resources. proper behaviour of ASIO_GetSamplePosition() and ASIO_GetLatencies() - are essential for precise media synchronization! -*/ - -typedef struct ASIOChannelInfo -{ - long channel; // on input, channel index - ASIOBool isInput; // on input - ASIOBool isActive; // on exit - long channelGroup; // dto - ASIOSampleType type; // dto - char name[32]; // dto -} ASIOChannelInfo; - -ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info); -/* Purpose: - retreive information about the nature of a channel - Parameter: - info: pointer to a ASIOChannelInfo structure with - - channel: on input, the channel index of the channel in question. - - isInput: on input, ASIOTrue if info for an input channel is - requested, else output - - channelGroup: on return, the channel group that the channel - belongs to. For drivers which support different types of - channels, like analog, S/PDIF, AES/EBU, ADAT etc interfaces, - there should be a reasonable grouping of these types. Groups - are always independant form a channel index, that is, a channel - index always counts from 0 to numInputs/numOutputs regardless - of the group it may belong to. - There will always be at least one group (group 0). Please - also note that by default, the host may decide to activate - channels 0 and 1; thus, these should belong to the most - useful type (analog i/o, if present). - - type: on return, contains the sample type of the channel - - isActive: on return, ASIOTrue if channel is active as it was - installed by ASIOCreateBuffers(), ASIOFalse else - - name: describing the type of channel in question. Used to allow - for user selection, and enabling of specific channels. examples: - "Analog In", "SPDIF Out" etc - Returns: - If no input/output is present ASE_NotPresent will be returned. - Notes: - If possible, the string should be organised such that the first - characters are most significantly describing the nature of the - port, to allow for identification even if the view showing the - port name is too small to display more than 8 characters, for - instance. -*/ - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Buffer preparation -//- - - - - - - - - - - - - - - - - - - - - - - - - - -typedef struct ASIOBufferInfo -{ - ASIOBool isInput; // on input: ASIOTrue: input, else output - long channelNum; // on input: channel index - void *buffers[2]; // on output: double buffer addresses -} ASIOBufferInfo; - -ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels, - long bufferSize, ASIOCallbacks *callbacks); - -/* Purpose: - Allocates input/output buffers for all input and output channels to be activated. - Parameter: - bufferInfos is a pointer to an array of ASIOBufferInfo structures: - - isInput: on input, ASIOTrue if the buffer is to be allocated - for an input, output buffer else - - channelNum: on input, the index of the channel in question - (counting from 0) - - buffers: on exit, 2 pointers to the halves of the channels' double-buffer. - the size of the buffer(s) of course depend on both the ASIOSampleType - as obtained from ASIOGetChannelInfo(), and bufferSize - numChannels is the sum of all input and output channels to be created; - thus bufferInfos is a pointer to an array of numChannels ASIOBufferInfo - structures. - bufferSize selects one of the possible buffer sizes as obtained from - ASIOGetBufferSizes(). - callbacks is a pointer to an ASIOCallbacks structure. - Returns: - If not enough memory is available ASE_NoMemory will be returned. - If no input/output is present ASE_NotPresent will be returned. - If bufferSize is not supported, or one or more of the bufferInfos elements - contain invalid settings, ASE_InvalidMode will be returned. - Notes: - If individual channel selection is not possible but requested, - the driver has to handle this. namely, bufferSwitch() will only - have filled buffers of enabled outputs. If possible, processing - and buss activities overhead should be avoided for channels which - were not enabled here. -*/ - -ASIOError ASIODisposeBuffers(void); -/* Purpose: - Releases all buffers for the device. - Parameter: - None. - Returns: - If no buffer were ever prepared, ASE_InvalidMode will be returned. - If no input/output is present ASE_NotPresent will be returned. - Notes: - This implies ASIOStop(). -*/ - -ASIOError ASIOControlPanel(void); -/* Purpose: - request the driver to start a control panel component - for device specific user settings. This will not be - accessed on some platforms (where the component is accessed - instead). - Parameter: - None. - Returns: - If no panel is available ASE_NotPresent will be returned. - Actually, the return code is ignored. - Notes: - if the user applied settings which require a re-configuration - of parts or all of the enigine and/or driver (such as a change of - the block size), the asioMessage callback can be used (see - ASIO_Callbacks). -*/ - -ASIOError ASIOFuture(long selector, void *params); -/* Purpose: - various - Parameter: - selector: operation Code as to be defined. zero is reserved for - testing purposes. - params: depends on the selector; usually pointer to a structure - for passing and retreiving any type and amount of parameters. - Returns: - the return value is also selector dependant. if the selector - is unknown, ASE_InvalidParameter should be returned to prevent - further calls with this selector. on success, ASE_SUCCESS - must be returned (note: ASE_OK is *not* sufficient!) - Notes: - see selectors defined below. -*/ - -enum -{ - kAsioEnableTimeCodeRead = 1, // no arguments - kAsioDisableTimeCodeRead, // no arguments - kAsioSetInputMonitor, // ASIOInputMonitor* in params - kAsioTransport, // ASIOTransportParameters* in params - kAsioSetInputGain, // ASIOChannelControls* in params, apply gain - kAsioGetInputMeter, // ASIOChannelControls* in params, fill meter - kAsioSetOutputGain, // ASIOChannelControls* in params, apply gain - kAsioGetOutputMeter, // ASIOChannelControls* in params, fill meter - kAsioCanInputMonitor, // no arguments for kAsioCanXXX selectors - kAsioCanTimeInfo, - kAsioCanTimeCode, - kAsioCanTransport, - kAsioCanInputGain, - kAsioCanInputMeter, - kAsioCanOutputGain, - kAsioCanOutputMeter, - - // DSD support - // The following extensions are required to allow switching - // and control of the DSD subsystem. - kAsioSetIoFormat = 0x23111961, /* ASIOIoFormat * in params. */ - kAsioGetIoFormat = 0x23111983, /* ASIOIoFormat * in params. */ - kAsioCanDoIoFormat = 0x23112004, /* ASIOIoFormat * in params. */ -}; - -typedef struct ASIOInputMonitor -{ - long input; // this input was set to monitor (or off), -1: all - long output; // suggested output for monitoring the input (if so) - long gain; // suggested gain, ranging 0 - 0x7fffffffL (-inf to +12 dB) - ASIOBool state; // ASIOTrue => on, ASIOFalse => off - long pan; // suggested pan, 0 => all left, 0x7fffffff => right -} ASIOInputMonitor; - -typedef struct ASIOChannelControls -{ - long channel; // on input, channel index - ASIOBool isInput; // on input - long gain; // on input, ranges 0 thru 0x7fffffff - long meter; // on return, ranges 0 thru 0x7fffffff - char future[32]; -} ASIOChannelControls; - -typedef struct ASIOTransportParameters -{ - long command; // see enum below - ASIOSamples samplePosition; - long track; - long trackSwitches[16]; // 512 tracks on/off - char future[64]; -} ASIOTransportParameters; - -enum -{ - kTransStart = 1, - kTransStop, - kTransLocate, // to samplePosition - kTransPunchIn, - kTransPunchOut, - kTransArmOn, // track - kTransArmOff, // track - kTransMonitorOn, // track - kTransMonitorOff, // track - kTransArm, // trackSwitches - kTransMonitor // trackSwitches -}; - -/* -// DSD support -// Some notes on how to use ASIOIoFormatType. -// -// The caller will fill the format with the request types. -// If the board can do the request then it will leave the -// values unchanged. If the board does not support the -// request then it will change that entry to Invalid (-1) -// -// So to request DSD then -// -// ASIOIoFormat NeedThis={kASIODSDFormat}; -// -// if(ASE_SUCCESS != ASIOFuture(kAsioSetIoFormat,&NeedThis) ){ -// // If the board did not accept one of the parameters then the -// // whole call will fail and the failing parameter will -// // have had its value changes to -1. -// } -// -// Note: Switching between the formats need to be done before the "prepared" -// state (see ASIO 2 documentation) is entered. -*/ -typedef long int ASIOIoFormatType; -enum ASIOIoFormatType_e -{ - kASIOFormatInvalid = -1, - kASIOPCMFormat = 0, - kASIODSDFormat = 1, -}; - -typedef struct ASIOIoFormat_s -{ - ASIOIoFormatType FormatType; - char future[512-sizeof(ASIOIoFormatType)]; -} ASIOIoFormat; - - -ASIOError ASIOOutputReady(void); -/* Purpose: - this tells the driver that the host has completed processing - the output buffers. if the data format required by the hardware - differs from the supported asio formats, but the hardware - buffers are DMA buffers, the driver will have to convert - the audio stream data; as the bufferSwitch callback is - usually issued at dma block switch time, the driver will - have to convert the *previous* host buffer, which increases - the output latency by one block. - when the host finds out that ASIOOutputReady() returns - true, it will issue this call whenever it completed - output processing. then the driver can convert the - host data directly to the dma buffer to be played next, - reducing output latency by one block. - another way to look at it is, that the buffer switch is called - in order to pass the *input* stream to the host, so that it can - process the input into the output, and the output stream is passed - to the driver when the host has completed its process. - Parameter: - None - Returns: - only if the above mentioned scenario is given, and a reduction - of output latency can be acheived by this mechanism, should - ASE_OK be returned. otherwise (and usually), ASE_NotPresent - should be returned in order to prevent further calls to this - function. note that the host may want to determine if it is - to use this when the system is not yet fully initialized, so - ASE_OK should always be returned if the mechanism makes sense. - Notes: - please remeber to adjust ASIOGetLatencies() according to - whether ASIOOutputReady() was ever called or not, if your - driver supports this scenario. - also note that the engine may fail to call ASIO_OutputReady() - in time in overload cases. as already mentioned, bufferSwitch - should be called for every block regardless of whether a block - could be processed in time. -*/ - -// restore old alignment -#if defined(_MSC_VER) && !defined(__MWERKS__) -#pragma pack(pop) -#elif PRAGMA_ALIGN_SUPPORTED -#pragma options align = reset -#endif - -#endif - diff --git a/asio/asiodrivers.cpp b/asio/asiodrivers.cpp deleted file mode 100644 index 5f56454..0000000 --- a/asio/asiodrivers.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include -#include "asiodrivers.h" - -AsioDrivers* asioDrivers = 0; - -bool loadAsioDriver(char *name); - -bool loadAsioDriver(char *name) -{ - if(!asioDrivers) - asioDrivers = new AsioDrivers(); - if(asioDrivers) - return asioDrivers->loadDriver(name); - return false; -} - -//------------------------------------------------------------------------------------ - -#if MAC - -bool resolveASIO(unsigned long aconnID); - -AsioDrivers::AsioDrivers() : CodeFragments("ASIO Drivers", 'AsDr', 'Asio') -{ - connID = -1; - curIndex = -1; -} - -AsioDrivers::~AsioDrivers() -{ - removeCurrentDriver(); -} - -bool AsioDrivers::getCurrentDriverName(char *name) -{ - if(curIndex >= 0) - return getName(curIndex, name); - return false; -} - -long AsioDrivers::getDriverNames(char **names, long maxDrivers) -{ - for(long i = 0; i < getNumFragments() && i < maxDrivers; i++) - getName(i, names[i]); - return getNumFragments() < maxDrivers ? getNumFragments() : maxDrivers; -} - -bool AsioDrivers::loadDriver(char *name) -{ - char dname[64]; - unsigned long newID; - - for(long i = 0; i < getNumFragments(); i++) - { - if(getName(i, dname) && !strcmp(name, dname)) - { - if(newInstance(i, &newID)) - { - if(resolveASIO(newID)) - { - if(connID != -1) - removeInstance(curIndex, connID); - curIndex = i; - connID = newID; - return true; - } - } - break; - } - } - return false; -} - -void AsioDrivers::removeCurrentDriver() -{ - if(connID != -1) - removeInstance(curIndex, connID); - connID = -1; - curIndex = -1; -} - -//------------------------------------------------------------------------------------ - -#elif WINDOWS - -#include "iasiodrv.h" - -extern IASIO* theAsioDriver; - -AsioDrivers::AsioDrivers() : AsioDriverList() -{ - curIndex = -1; -} - -AsioDrivers::~AsioDrivers() -{ -} - -bool AsioDrivers::getCurrentDriverName(char *name) -{ - if(curIndex >= 0) - return asioGetDriverName(curIndex, name, 32) == 0 ? true : false; - name[0] = 0; - return false; -} - -long AsioDrivers::getDriverNames(char **names, long maxDrivers) -{ - for(long i = 0; i < asioGetNumDev() && i < maxDrivers; i++) - asioGetDriverName(i, names[i], 32); - return asioGetNumDev() < maxDrivers ? asioGetNumDev() : maxDrivers; -} - -bool AsioDrivers::loadDriver(char *name) -{ - char dname[64]; - char curName[64]; - - for(long i = 0; i < asioGetNumDev(); i++) - { - if(!asioGetDriverName(i, dname, 32) && !strcmp(name, dname)) - { - curName[0] = 0; - getCurrentDriverName(curName); // in case we fail... - removeCurrentDriver(); - - if(!asioOpenDriver(i, (void **)&theAsioDriver)) - { - curIndex = i; - return true; - } - else - { - theAsioDriver = 0; - if(curName[0] && strcmp(dname, curName)) - loadDriver(curName); // try restore - } - break; - } - } - return false; -} - -void AsioDrivers::removeCurrentDriver() -{ - if(curIndex != -1) - asioCloseDriver(curIndex); - curIndex = -1; -} - -#elif SGI || BEOS - -#include "asiolist.h" - -AsioDrivers::AsioDrivers() - : AsioDriverList() -{ - curIndex = -1; -} - -AsioDrivers::~AsioDrivers() -{ -} - -bool AsioDrivers::getCurrentDriverName(char *name) -{ - return false; -} - -long AsioDrivers::getDriverNames(char **names, long maxDrivers) -{ - return 0; -} - -bool AsioDrivers::loadDriver(char *name) -{ - return false; -} - -void AsioDrivers::removeCurrentDriver() -{ -} - -#else -#error implement me -#endif diff --git a/asio/asiodrivers.h b/asio/asiodrivers.h deleted file mode 100644 index 2ddf7ad..0000000 --- a/asio/asiodrivers.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __AsioDrivers__ -#define __AsioDrivers__ - -#include "ginclude.h" - -#if MAC -#include "CodeFragments.hpp" - -class AsioDrivers : public CodeFragments - -#elif WINDOWS -#include -#include "asiolist.h" - -class AsioDrivers : public AsioDriverList - -#elif SGI || BEOS -#include "asiolist.h" - -class AsioDrivers : public AsioDriverList - -#else -#error implement me -#endif - -{ -public: - AsioDrivers(); - ~AsioDrivers(); - - bool getCurrentDriverName(char *name); - long getDriverNames(char **names, long maxDrivers); - bool loadDriver(char *name); - void removeCurrentDriver(); - long getCurrentDriverIndex() {return curIndex;} -protected: - unsigned long connID; - long curIndex; -}; - -#endif diff --git a/asio/asiodrvr.h b/asio/asiodrvr.h deleted file mode 100644 index 663f75a..0000000 --- a/asio/asiodrvr.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Steinberg Audio Stream I/O API - (c) 1996, Steinberg Soft- und Hardware GmbH - charlie (May 1996) - - asiodrvr.h - c++ superclass to implement asio functionality. from this, - you can derive whatever required -*/ - -#ifndef _asiodrvr_ -#define _asiodrvr_ - -// cpu and os system we are running on -#include "asiosys.h" -// basic "C" interface -#include "asio.h" - -class AsioDriver; -extern AsioDriver *getDriver(); // for generic constructor - -#if WINDOWS -#include -#include "combase.h" -#include "iasiodrv.h" -class AsioDriver : public IASIO ,public CUnknown -{ -public: - AsioDriver(LPUNKNOWN pUnk, HRESULT *phr); - - DECLARE_IUNKNOWN - // Factory method - static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); - // IUnknown - virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject); - -#else - -class AsioDriver -{ -public: - AsioDriver(); -#endif - virtual ~AsioDriver(); - - virtual ASIOBool init(void* sysRef); - virtual void getDriverName(char *name); // max 32 bytes incl. terminating zero - virtual long getDriverVersion(); - virtual void getErrorMessage(char *string); // max 124 bytes incl. - - virtual ASIOError start(); - virtual ASIOError stop(); - - virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels); - virtual ASIOError getLatencies(long *inputLatency, long *outputLatency); - virtual ASIOError getBufferSize(long *minSize, long *maxSize, - long *preferredSize, long *granularity); - - virtual ASIOError canSampleRate(ASIOSampleRate sampleRate); - virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate); - virtual ASIOError setSampleRate(ASIOSampleRate sampleRate); - virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); - virtual ASIOError setClockSource(long reference); - - virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); - virtual ASIOError getChannelInfo(ASIOChannelInfo *info); - - virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, - long bufferSize, ASIOCallbacks *callbacks); - virtual ASIOError disposeBuffers(); - - virtual ASIOError controlPanel(); - virtual ASIOError future(long selector, void *opt); - virtual ASIOError outputReady(); -}; -#endif diff --git a/asio/asiolist.cpp b/asio/asiolist.cpp deleted file mode 100644 index 5a62f5b..0000000 --- a/asio/asiolist.cpp +++ /dev/null @@ -1,268 +0,0 @@ -#include -#include "iasiodrv.h" -#include "asiolist.h" - -#define ASIODRV_DESC "description" -#define INPROC_SERVER "InprocServer32" -#define ASIO_PATH "software\\asio" -#define COM_CLSID "clsid" - -// ****************************************************************** -// Local Functions -// ****************************************************************** -static LONG findDrvPath (char *clsidstr,char *dllpath,int dllpathsize) -{ - HKEY hkEnum,hksub,hkpath; - char databuf[512]; - LONG cr,rc = -1; - DWORD datatype,datasize; - DWORD index; - OFSTRUCT ofs; - HFILE hfile; - BOOL found = FALSE; - - CharLowerBuff(clsidstr,strlen(clsidstr)); - if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) { - - index = 0; - while (cr == ERROR_SUCCESS && !found) { - cr = RegEnumKey(hkEnum,index++,(LPTSTR)databuf,512); - if (cr == ERROR_SUCCESS) { - CharLowerBuff(databuf,strlen(databuf)); - if (!(strcmp(databuf,clsidstr))) { - if ((cr = RegOpenKeyEx(hkEnum,(LPCTSTR)databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) { - if ((cr = RegOpenKeyEx(hksub,(LPCTSTR)INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) { - datatype = REG_SZ; datasize = (DWORD)dllpathsize; - cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize); - if (cr == ERROR_SUCCESS) { - memset(&ofs,0,sizeof(OFSTRUCT)); - ofs.cBytes = sizeof(OFSTRUCT); - hfile = OpenFile(dllpath,&ofs,OF_EXIST); - if (hfile) rc = 0; - } - RegCloseKey(hkpath); - } - RegCloseKey(hksub); - } - found = TRUE; // break out - } - } - } - RegCloseKey(hkEnum); - } - return rc; -} - - -static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv) -{ - HKEY hksub; - char databuf[256]; - char dllpath[MAXPATHLEN]; - WORD wData[100]; - CLSID clsid; - DWORD datatype,datasize; - LONG cr,rc; - - if (!lpdrv) { - if ((cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) { - - datatype = REG_SZ; datasize = 256; - cr = RegQueryValueEx(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize); - if (cr == ERROR_SUCCESS) { - rc = findDrvPath (databuf,dllpath,MAXPATHLEN); - if (rc == 0) { - lpdrv = new ASIODRVSTRUCT[1]; - if (lpdrv) { - memset(lpdrv,0,sizeof(ASIODRVSTRUCT)); - lpdrv->drvID = drvID; - MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100); - if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) { - memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID)); - } - - datatype = REG_SZ; datasize = 256; - cr = RegQueryValueEx(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize); - if (cr == ERROR_SUCCESS) { - strcpy(lpdrv->drvname,databuf); - } - else strcpy(lpdrv->drvname,keyname); - } - } - } - RegCloseKey(hksub); - } - } - else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next); - - return lpdrv; -} - -static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv) -{ - IASIO *iasio; - - if (lpdrv != 0) { - deleteDrvStruct(lpdrv->next); - if (lpdrv->asiodrv) { - iasio = (IASIO *)lpdrv->asiodrv; - iasio->Release(); - } - delete lpdrv; - } -} - - -static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv) -{ - while (lpdrv) { - if (lpdrv->drvID == drvID) return lpdrv; - lpdrv = lpdrv->next; - } - return 0; -} -// ****************************************************************** - - -// ****************************************************************** -// AsioDriverList -// ****************************************************************** -AsioDriverList::AsioDriverList () -{ - HKEY hkEnum = 0; - char keyname[MAXDRVNAMELEN]; - LPASIODRVSTRUCT pdl; - LONG cr; - DWORD index = 0; - BOOL fin = FALSE; - - numdrv = 0; - lpdrvlist = 0; - - cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum); - while (cr == ERROR_SUCCESS) { - if ((cr = RegEnumKey(hkEnum,index++,(LPTSTR)keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) { - lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist); - } - else fin = TRUE; - } - if (hkEnum) RegCloseKey(hkEnum); - - pdl = lpdrvlist; - while (pdl) { - numdrv++; - pdl = pdl->next; - } - - if (numdrv) CoInitialize(0); // initialize COM -} - -AsioDriverList::~AsioDriverList () -{ - if (numdrv) { - deleteDrvStruct(lpdrvlist); - CoUninitialize(); - } -} - - -LONG AsioDriverList::asioGetNumDev (VOID) -{ - return (LONG)numdrv; -} - - -LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv) -{ - LPASIODRVSTRUCT lpdrv = 0; - long rc; - - if (!asiodrv) return DRVERR_INVALID_PARAM; - - if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { - if (!lpdrv->asiodrv) { - rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv); - if (rc == S_OK) { - lpdrv->asiodrv = *asiodrv; - return 0; - } - // else if (rc == REGDB_E_CLASSNOTREG) - // strcpy (info->messageText, "Driver not registered in the Registration Database!"); - } - else rc = DRVERR_DEVICE_ALREADY_OPEN; - } - else rc = DRVERR_DEVICE_NOT_FOUND; - - return rc; -} - - -LONG AsioDriverList::asioCloseDriver (int drvID) -{ - LPASIODRVSTRUCT lpdrv = 0; - IASIO *iasio; - - if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { - if (lpdrv->asiodrv) { - iasio = (IASIO *)lpdrv->asiodrv; - iasio->Release(); - lpdrv->asiodrv = 0; - } - } - - return 0; -} - -LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize) -{ - LPASIODRVSTRUCT lpdrv = 0; - - if (!drvname) return DRVERR_INVALID_PARAM; - - if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { - if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) { - strcpy(drvname,lpdrv->drvname); - } - else { - memcpy(drvname,lpdrv->drvname,drvnamesize-4); - drvname[drvnamesize-4] = '.'; - drvname[drvnamesize-3] = '.'; - drvname[drvnamesize-2] = '.'; - drvname[drvnamesize-1] = 0; - } - return 0; - } - return DRVERR_DEVICE_NOT_FOUND; -} - -LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize) -{ - LPASIODRVSTRUCT lpdrv = 0; - - if (!dllpath) return DRVERR_INVALID_PARAM; - - if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { - if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) { - strcpy(dllpath,lpdrv->dllpath); - return 0; - } - dllpath[0] = 0; - return DRVERR_INVALID_PARAM; - } - return DRVERR_DEVICE_NOT_FOUND; -} - -LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid) -{ - LPASIODRVSTRUCT lpdrv = 0; - - if (!clsid) return DRVERR_INVALID_PARAM; - - if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { - memcpy(clsid,&lpdrv->clsid,sizeof(CLSID)); - return 0; - } - return DRVERR_DEVICE_NOT_FOUND; -} - - diff --git a/asio/asiolist.h b/asio/asiolist.h deleted file mode 100644 index 01c64f0..0000000 --- a/asio/asiolist.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __asiolist__ -#define __asiolist__ - -#define DRVERR -5000 -#define DRVERR_INVALID_PARAM DRVERR-1 -#define DRVERR_DEVICE_ALREADY_OPEN DRVERR-2 -#define DRVERR_DEVICE_NOT_FOUND DRVERR-3 - -#define MAXPATHLEN 512 -#define MAXDRVNAMELEN 128 - -struct asiodrvstruct -{ - int drvID; - CLSID clsid; - char dllpath[MAXPATHLEN]; - char drvname[MAXDRVNAMELEN]; - LPVOID asiodrv; - struct asiodrvstruct *next; -}; - -typedef struct asiodrvstruct ASIODRVSTRUCT; -typedef ASIODRVSTRUCT *LPASIODRVSTRUCT; - -class AsioDriverList { -public: - AsioDriverList(); - ~AsioDriverList(); - - LONG asioOpenDriver (int,VOID **); - LONG asioCloseDriver (int); - - // nice to have - LONG asioGetNumDev (VOID); - LONG asioGetDriverName (int,char *,int); - LONG asioGetDriverPath (int,char *,int); - LONG asioGetDriverCLSID (int,CLSID *); - - // or use directly access - LPASIODRVSTRUCT lpdrvlist; - int numdrv; -}; - -typedef class AsioDriverList *LPASIODRIVERLIST; - -#endif diff --git a/asio/asiosys.h b/asio/asiosys.h deleted file mode 100644 index 37f7a48..0000000 --- a/asio/asiosys.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef __asiosys__ - #define __asiosys__ - - #ifdef WIN32 - #undef MAC - #define PPC 0 - #define WINDOWS 1 - #define SGI 0 - #define SUN 0 - #define LINUX 0 - #define BEOS 0 - - #define NATIVE_INT64 0 - #define IEEE754_64FLOAT 1 - - #elif BEOS - #define MAC 0 - #define PPC 0 - #define WINDOWS 0 - #define PC 0 - #define SGI 0 - #define SUN 0 - #define LINUX 0 - - #define NATIVE_INT64 0 - #define IEEE754_64FLOAT 1 - - #ifndef DEBUG - #define DEBUG 0 - #if DEBUG - void DEBUGGERMESSAGE(char *string); - #else - #define DEBUGGERMESSAGE(a) - #endif - #endif - - #elif SGI - #define MAC 0 - #define PPC 0 - #define WINDOWS 0 - #define PC 0 - #define SUN 0 - #define LINUX 0 - #define BEOS 0 - - #define NATIVE_INT64 0 - #define IEEE754_64FLOAT 1 - - #ifndef DEBUG - #define DEBUG 0 - #if DEBUG - void DEBUGGERMESSAGE(char *string); - #else - #define DEBUGGERMESSAGE(a) - #endif - #endif - - #else // MAC - - #define MAC 1 - #define PPC 1 - #define WINDOWS 0 - #define PC 0 - #define SGI 0 - #define SUN 0 - #define LINUX 0 - #define BEOS 0 - - #define NATIVE_INT64 0 - #define IEEE754_64FLOAT 1 - - #ifndef DEBUG - #define DEBUG 0 - #if DEBUG - void DEBUGGERMESSAGE(char *string); - #else - #define DEBUGGERMESSAGE(a) - #endif - #endif - #endif - -#endif diff --git a/asio/ginclude.h b/asio/ginclude.h deleted file mode 100644 index b627dc2..0000000 --- a/asio/ginclude.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __gInclude__ -#define __gInclude__ - -#if SGI - #undef BEOS - #undef MAC - #undef WINDOWS - // - #define ASIO_BIG_ENDIAN 1 - #define ASIO_CPU_MIPS 1 -#elif defined WIN32 - #undef BEOS - #undef MAC - #undef SGI - #define WINDOWS 1 - #define ASIO_LITTLE_ENDIAN 1 - #define ASIO_CPU_X86 1 -#elif BEOS - #undef MAC - #undef SGI - #undef WINDOWS - #define ASIO_LITTLE_ENDIAN 1 - #define ASIO_CPU_X86 1 - // -#else - #define MAC 1 - #undef BEOS - #undef WINDOWS - #undef SGI - #define ASIO_BIG_ENDIAN 1 - #define ASIO_CPU_PPC 1 -#endif - -// always -#define NATIVE_INT64 0 -#define IEEE754_64FLOAT 1 - -#endif // __gInclude__ diff --git a/asio/iasiodrv.h b/asio/iasiodrv.h deleted file mode 100644 index 64d2dbb..0000000 --- a/asio/iasiodrv.h +++ /dev/null @@ -1,37 +0,0 @@ -#include "asiosys.h" -#include "asio.h" - -/* Forward Declarations */ - -#ifndef __ASIODRIVER_FWD_DEFINED__ -#define __ASIODRIVER_FWD_DEFINED__ -typedef interface IASIO IASIO; -#endif /* __ASIODRIVER_FWD_DEFINED__ */ - -interface IASIO : public IUnknown -{ - - virtual ASIOBool init(void *sysHandle) = 0; - virtual void getDriverName(char *name) = 0; - virtual long getDriverVersion() = 0; - virtual void getErrorMessage(char *string) = 0; - virtual ASIOError start() = 0; - virtual ASIOError stop() = 0; - virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0; - virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0; - virtual ASIOError getBufferSize(long *minSize, long *maxSize, - long *preferredSize, long *granularity) = 0; - virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0; - virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0; - virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0; - virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0; - virtual ASIOError setClockSource(long reference) = 0; - virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0; - virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0; - virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, - long bufferSize, ASIOCallbacks *callbacks) = 0; - virtual ASIOError disposeBuffers() = 0; - virtual ASIOError controlPanel() = 0; - virtual ASIOError future(long selector,void *opt) = 0; - virtual ASIOError outputReady() = 0; -}; diff --git a/asio/iasiothiscallresolver.cpp b/asio/iasiothiscallresolver.cpp deleted file mode 100644 index 38c39d2..0000000 --- a/asio/iasiothiscallresolver.cpp +++ /dev/null @@ -1,563 +0,0 @@ -/* - IASIOThiscallResolver.cpp see the comments in iasiothiscallresolver.h for - the top level description - this comment describes the technical details of - the implementation. - - The latest version of this file is available from: - http://www.audiomulch.com/~rossb/code/calliasio - - please email comments to Ross Bencina - - BACKGROUND - - The IASIO interface declared in the Steinberg ASIO 2 SDK declares - functions with no explicit calling convention. This causes MSVC++ to default - to using the thiscall convention, which is a proprietary convention not - implemented by some non-microsoft compilers - notably borland BCC, - C++Builder, and gcc. MSVC++ is the defacto standard compiler used by - Steinberg. As a result of this situation, the ASIO sdk will compile with - any compiler, however attempting to execute the compiled code will cause a - crash due to different default calling conventions on non-Microsoft - compilers. - - IASIOThiscallResolver solves the problem by providing an adapter class that - delegates to the IASIO interface using the correct calling convention - (thiscall). Due to the lack of support for thiscall in the Borland and GCC - compilers, the calls have been implemented in assembly language. - - A number of macros are defined for thiscall function calls with different - numbers of parameters, with and without return values - it may be possible - to modify the format of these macros to make them work with other inline - assemblers. - - - THISCALL DEFINITION - - A number of definitions of the thiscall calling convention are floating - around the internet. The following definition has been validated against - output from the MSVC++ compiler: - - For non-vararg functions, thiscall works as follows: the object (this) - pointer is passed in ECX. All arguments are passed on the stack in - right to left order. The return value is placed in EAX. The callee - clears the passed arguments from the stack. - - - FINDING FUNCTION POINTERS FROM AN IASIO POINTER - - The first field of a COM object is a pointer to its vtble. Thus a pointer - to an object implementing the IASIO interface also points to a pointer to - that object's vtbl. The vtble is a table of function pointers for all of - the virtual functions exposed by the implemented interfaces. - - If we consider a variable declared as a pointer to IASO: - - IASIO *theAsioDriver - - theAsioDriver points to: - - object implementing IASIO - { - IASIOvtbl *vtbl - other data - } - - in other words, theAsioDriver points to a pointer to an IASIOvtbl - - vtbl points to a table of function pointers: - - IASIOvtbl ( interface IASIO : public IUnknown ) - { - (IUnknown functions) - 0 virtual HRESULT STDMETHODCALLTYPE (*QueryInterface)(REFIID riid, void **ppv) = 0; - 4 virtual ULONG STDMETHODCALLTYPE (*AddRef)() = 0; - 8 virtual ULONG STDMETHODCALLTYPE (*Release)() = 0; - - (IASIO functions) - 12 virtual ASIOBool (*init)(void *sysHandle) = 0; - 16 virtual void (*getDriverName)(char *name) = 0; - 20 virtual long (*getDriverVersion)() = 0; - 24 virtual void (*getErrorMessage)(char *string) = 0; - 28 virtual ASIOError (*start)() = 0; - 32 virtual ASIOError (*stop)() = 0; - 36 virtual ASIOError (*getChannels)(long *numInputChannels, long *numOutputChannels) = 0; - 40 virtual ASIOError (*getLatencies)(long *inputLatency, long *outputLatency) = 0; - 44 virtual ASIOError (*getBufferSize)(long *minSize, long *maxSize, - long *preferredSize, long *granularity) = 0; - 48 virtual ASIOError (*canSampleRate)(ASIOSampleRate sampleRate) = 0; - 52 virtual ASIOError (*getSampleRate)(ASIOSampleRate *sampleRate) = 0; - 56 virtual ASIOError (*setSampleRate)(ASIOSampleRate sampleRate) = 0; - 60 virtual ASIOError (*getClockSources)(ASIOClockSource *clocks, long *numSources) = 0; - 64 virtual ASIOError (*setClockSource)(long reference) = 0; - 68 virtual ASIOError (*getSamplePosition)(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0; - 72 virtual ASIOError (*getChannelInfo)(ASIOChannelInfo *info) = 0; - 76 virtual ASIOError (*createBuffers)(ASIOBufferInfo *bufferInfos, long numChannels, - long bufferSize, ASIOCallbacks *callbacks) = 0; - 80 virtual ASIOError (*disposeBuffers)() = 0; - 84 virtual ASIOError (*controlPanel)() = 0; - 88 virtual ASIOError (*future)(long selector,void *opt) = 0; - 92 virtual ASIOError (*outputReady)() = 0; - }; - - The numbers in the left column show the byte offset of each function ptr - from the beginning of the vtbl. These numbers are used in the code below - to select different functions. - - In order to find the address of a particular function, theAsioDriver - must first be dereferenced to find the value of the vtbl pointer: - - mov eax, theAsioDriver - mov edx, [theAsioDriver] // edx now points to vtbl[0] - - Then an offset must be added to the vtbl pointer to select a - particular function, for example vtbl+44 points to the slot containing - a pointer to the getBufferSize function. - - Finally vtbl+x must be dereferenced to obtain the value of the function - pointer stored in that address: - - call [edx+44] // call the function pointed to by - // the value in the getBufferSize field of the vtbl - - - SEE ALSO - - Martin Fay's OpenASIO DLL at http://www.martinfay.com solves the same - problem by providing a new COM interface which wraps IASIO with an - interface that uses portable calling conventions. OpenASIO must be compiled - with MSVC, and requires that you ship the OpenASIO DLL with your - application. - - - ACKNOWLEDGEMENTS - - Ross Bencina: worked out the thiscall details above, wrote the original - Borland asm macros, and a patch for asio.cpp (which is no longer needed). - Thanks to Martin Fay for introducing me to the issues discussed here, - and to Rene G. Ceballos for assisting with asm dumps from MSVC++. - - Antti Silvast: converted the original calliasio to work with gcc and NASM - by implementing the asm code in a separate file. - - Fraser Adams: modified the original calliasio containing the Borland inline - asm to add inline asm for gcc i.e. Intel syntax for Borland and AT&T syntax - for gcc. This seems a neater approach for gcc than to have a separate .asm - file and it means that we only need one version of the thiscall patch. - - Fraser Adams: rewrote the original calliasio patch in the form of the - IASIOThiscallResolver class in order to avoid modifications to files from - the Steinberg SDK, which may have had potential licence issues. - - Andrew Baldwin: contributed fixes for compatibility problems with more - recent versions of the gcc assembler. -*/ - - -// We only need IASIOThiscallResolver at all if we are on Win32. For other -// platforms we simply bypass the IASIOThiscallResolver definition to allow us -// to be safely #include'd whatever the platform to keep client code portable -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) - - -// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver -// is not used. -#if !defined(_MSC_VER) - - -#include -#include - -// We have a mechanism in iasiothiscallresolver.h to ensure that asio.h is -// #include'd before it in client code, we do NOT want to do this test here. -#define iasiothiscallresolver_sourcefile 1 -#include "iasiothiscallresolver.h" -#undef iasiothiscallresolver_sourcefile - -// iasiothiscallresolver.h redefines ASIOInit for clients, but we don't want -// this macro defined in this translation unit. -#undef ASIOInit - - -// theAsioDriver is a global pointer to the current IASIO instance which the -// ASIO SDK uses to perform all actions on the IASIO interface. We substitute -// our own forwarding interface into this pointer. -extern IASIO* theAsioDriver; - - -// The following macros define the inline assembler for BORLAND first then gcc - -#if defined(__BCPLUSPLUS__) || defined(__BORLANDC__) - - -#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )\ - void *this_ = (thisPtr); \ - __asm { \ - mov ecx, this_ ; \ - mov eax, [ecx] ; \ - call [eax+funcOffset] ; \ - mov resultName, eax ; \ - } - - -#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )\ - void *this_ = (thisPtr); \ - __asm { \ - mov eax, param1 ; \ - push eax ; \ - mov ecx, this_ ; \ - mov eax, [ecx] ; \ - call [eax+funcOffset] ; \ - } - - -#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )\ - void *this_ = (thisPtr); \ - __asm { \ - mov eax, param1 ; \ - push eax ; \ - mov ecx, this_ ; \ - mov eax, [ecx] ; \ - call [eax+funcOffset] ; \ - mov resultName, eax ; \ - } - - -#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )\ - void *this_ = (thisPtr); \ - void *doubleParamPtr_ (¶m1); \ - __asm { \ - mov eax, doubleParamPtr_ ; \ - push [eax+4] ; \ - push [eax] ; \ - mov ecx, this_ ; \ - mov eax, [ecx] ; \ - call [eax+funcOffset] ; \ - mov resultName, eax ; \ - } - - -#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )\ - void *this_ = (thisPtr); \ - __asm { \ - mov eax, param2 ; \ - push eax ; \ - mov eax, param1 ; \ - push eax ; \ - mov ecx, this_ ; \ - mov eax, [ecx] ; \ - call [eax+funcOffset] ; \ - mov resultName, eax ; \ - } - - -#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\ - void *this_ = (thisPtr); \ - __asm { \ - mov eax, param4 ; \ - push eax ; \ - mov eax, param3 ; \ - push eax ; \ - mov eax, param2 ; \ - push eax ; \ - mov eax, param1 ; \ - push eax ; \ - mov ecx, this_ ; \ - mov eax, [ecx] ; \ - call [eax+funcOffset] ; \ - mov resultName, eax ; \ - } - - -#elif defined(__GNUC__) - - -#define CALL_THISCALL_0( resultName, thisPtr, funcOffset ) \ - __asm__ __volatile__ ("movl (%1), %%edx\n\t" \ - "call *"#funcOffset"(%%edx)\n\t" \ - :"=a"(resultName) /* Output Operands */ \ - :"c"(thisPtr) /* Input Operands */ \ - ); \ - - -#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 ) \ - __asm__ __volatile__ ("pushl %0\n\t" \ - "movl (%1), %%edx\n\t" \ - "call *"#funcOffset"(%%edx)\n\t" \ - : /* Output Operands */ \ - :"r"(param1), /* Input Operands */ \ - "c"(thisPtr) \ - ); \ - - -#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 ) \ - __asm__ __volatile__ ("pushl %1\n\t" \ - "movl (%2), %%edx\n\t" \ - "call *"#funcOffset"(%%edx)\n\t" \ - :"=a"(resultName) /* Output Operands */ \ - :"r"(param1), /* Input Operands */ \ - "c"(thisPtr) \ - ); \ - - -#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 ) \ - __asm__ __volatile__ ("pushl 4(%1)\n\t" \ - "pushl (%1)\n\t" \ - "movl (%2), %%edx\n\t" \ - "call *"#funcOffset"(%%edx);\n\t" \ - :"=a"(resultName) /* Output Operands */ \ - :"a"(¶m1), /* Input Operands */ \ - /* Note: Using "r" above instead of "a" fails */ \ - /* when using GCC 3.3.3, and maybe later versions*/\ - "c"(thisPtr) \ - ); \ - - -#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 ) \ - __asm__ __volatile__ ("pushl %1\n\t" \ - "pushl %2\n\t" \ - "movl (%3), %%edx\n\t" \ - "call *"#funcOffset"(%%edx)\n\t" \ - :"=a"(resultName) /* Output Operands */ \ - :"r"(param2), /* Input Operands */ \ - "r"(param1), \ - "c"(thisPtr) \ - ); \ - - -#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\ - __asm__ __volatile__ ("pushl %1\n\t" \ - "pushl %2\n\t" \ - "pushl %3\n\t" \ - "pushl %4\n\t" \ - "movl (%5), %%edx\n\t" \ - "call *"#funcOffset"(%%edx)\n\t" \ - :"=a"(resultName) /* Output Operands */ \ - :"r"(param4), /* Input Operands */ \ - "r"(param3), \ - "r"(param2), \ - "r"(param1), \ - "c"(thisPtr) \ - ); \ - -#endif - - - -// Our static singleton instance. -IASIOThiscallResolver IASIOThiscallResolver::instance; - -// Constructor called to initialize static Singleton instance above. Note that -// it is important not to clear that_ incase it has already been set by the call -// to placement new in ASIOInit(). -IASIOThiscallResolver::IASIOThiscallResolver() -{ -} - -// Constructor called from ASIOInit() below -IASIOThiscallResolver::IASIOThiscallResolver(IASIO* that) -: that_( that ) -{ -} - -// Implement IUnknown methods as assert(false). IASIOThiscallResolver is not -// really a COM object, just a wrapper which will work with the ASIO SDK. -// If you wanted to use ASIO without the SDK you might want to implement COM -// aggregation in these methods. -HRESULT STDMETHODCALLTYPE IASIOThiscallResolver::QueryInterface(REFIID riid, void **ppv) -{ - (void)riid; // suppress unused variable warning - - assert( false ); // this function should never be called by the ASIO SDK. - - *ppv = NULL; - return E_NOINTERFACE; -} - -ULONG STDMETHODCALLTYPE IASIOThiscallResolver::AddRef() -{ - assert( false ); // this function should never be called by the ASIO SDK. - - return 1; -} - -ULONG STDMETHODCALLTYPE IASIOThiscallResolver::Release() -{ - assert( false ); // this function should never be called by the ASIO SDK. - - return 1; -} - - -// Implement the IASIO interface methods by performing the vptr manipulation -// described above then delegating to the real implementation. -ASIOBool IASIOThiscallResolver::init(void *sysHandle) -{ - ASIOBool result; - CALL_THISCALL_1( result, that_, 12, sysHandle ); - return result; -} - -void IASIOThiscallResolver::getDriverName(char *name) -{ - CALL_VOID_THISCALL_1( that_, 16, name ); -} - -long IASIOThiscallResolver::getDriverVersion() -{ - ASIOBool result; - CALL_THISCALL_0( result, that_, 20 ); - return result; -} - -void IASIOThiscallResolver::getErrorMessage(char *string) -{ - CALL_VOID_THISCALL_1( that_, 24, string ); -} - -ASIOError IASIOThiscallResolver::start() -{ - ASIOBool result; - CALL_THISCALL_0( result, that_, 28 ); - return result; -} - -ASIOError IASIOThiscallResolver::stop() -{ - ASIOBool result; - CALL_THISCALL_0( result, that_, 32 ); - return result; -} - -ASIOError IASIOThiscallResolver::getChannels(long *numInputChannels, long *numOutputChannels) -{ - ASIOBool result; - CALL_THISCALL_2( result, that_, 36, numInputChannels, numOutputChannels ); - return result; -} - -ASIOError IASIOThiscallResolver::getLatencies(long *inputLatency, long *outputLatency) -{ - ASIOBool result; - CALL_THISCALL_2( result, that_, 40, inputLatency, outputLatency ); - return result; -} - -ASIOError IASIOThiscallResolver::getBufferSize(long *minSize, long *maxSize, - long *preferredSize, long *granularity) -{ - ASIOBool result; - CALL_THISCALL_4( result, that_, 44, minSize, maxSize, preferredSize, granularity ); - return result; -} - -ASIOError IASIOThiscallResolver::canSampleRate(ASIOSampleRate sampleRate) -{ - ASIOBool result; - CALL_THISCALL_1_DOUBLE( result, that_, 48, sampleRate ); - return result; -} - -ASIOError IASIOThiscallResolver::getSampleRate(ASIOSampleRate *sampleRate) -{ - ASIOBool result; - CALL_THISCALL_1( result, that_, 52, sampleRate ); - return result; -} - -ASIOError IASIOThiscallResolver::setSampleRate(ASIOSampleRate sampleRate) -{ - ASIOBool result; - CALL_THISCALL_1_DOUBLE( result, that_, 56, sampleRate ); - return result; -} - -ASIOError IASIOThiscallResolver::getClockSources(ASIOClockSource *clocks, long *numSources) -{ - ASIOBool result; - CALL_THISCALL_2( result, that_, 60, clocks, numSources ); - return result; -} - -ASIOError IASIOThiscallResolver::setClockSource(long reference) -{ - ASIOBool result; - CALL_THISCALL_1( result, that_, 64, reference ); - return result; -} - -ASIOError IASIOThiscallResolver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) -{ - ASIOBool result; - CALL_THISCALL_2( result, that_, 68, sPos, tStamp ); - return result; -} - -ASIOError IASIOThiscallResolver::getChannelInfo(ASIOChannelInfo *info) -{ - ASIOBool result; - CALL_THISCALL_1( result, that_, 72, info ); - return result; -} - -ASIOError IASIOThiscallResolver::createBuffers(ASIOBufferInfo *bufferInfos, - long numChannels, long bufferSize, ASIOCallbacks *callbacks) -{ - ASIOBool result; - CALL_THISCALL_4( result, that_, 76, bufferInfos, numChannels, bufferSize, callbacks ); - return result; -} - -ASIOError IASIOThiscallResolver::disposeBuffers() -{ - ASIOBool result; - CALL_THISCALL_0( result, that_, 80 ); - return result; -} - -ASIOError IASIOThiscallResolver::controlPanel() -{ - ASIOBool result; - CALL_THISCALL_0( result, that_, 84 ); - return result; -} - -ASIOError IASIOThiscallResolver::future(long selector,void *opt) -{ - ASIOBool result; - CALL_THISCALL_2( result, that_, 88, selector, opt ); - return result; -} - -ASIOError IASIOThiscallResolver::outputReady() -{ - ASIOBool result; - CALL_THISCALL_0( result, that_, 92 ); - return result; -} - - -// Implement our substitute ASIOInit() method -ASIOError IASIOThiscallResolver::ASIOInit(ASIODriverInfo *info) -{ - // To ensure that our instance's vptr is correctly constructed, even if - // ASIOInit is called prior to main(), we explicitly call its constructor - // (potentially over the top of an existing instance). Note that this is - // pretty ugly, and is only safe because IASIOThiscallResolver has no - // destructor and contains no objects with destructors. - new((void*)&instance) IASIOThiscallResolver( theAsioDriver ); - - // Interpose between ASIO client code and the real driver. - theAsioDriver = &instance; - - // Note that we never need to switch theAsioDriver back to point to the - // real driver because theAsioDriver is reset to zero in ASIOExit(). - - // Delegate to the real ASIOInit - return ::ASIOInit(info); -} - - -#endif /* !defined(_MSC_VER) */ - -#endif /* Win32 */ - diff --git a/asio/iasiothiscallresolver.h b/asio/iasiothiscallresolver.h deleted file mode 100644 index b59d910..0000000 --- a/asio/iasiothiscallresolver.h +++ /dev/null @@ -1,201 +0,0 @@ -// **************************************************************************** -// -// Changed: I have modified this file slightly (includes) to work with -// RtAudio. RtAudio.cpp must include this file after asio.h. -// -// File: IASIOThiscallResolver.h -// Description: The IASIOThiscallResolver class implements the IASIO -// interface and acts as a proxy to the real IASIO interface by -// calling through its vptr table using the thiscall calling -// convention. To put it another way, we interpose -// IASIOThiscallResolver between ASIO SDK code and the driver. -// This is necessary because most non-Microsoft compilers don't -// implement the thiscall calling convention used by IASIO. -// -// iasiothiscallresolver.cpp contains the background of this -// problem plus a technical description of the vptr -// manipulations. -// -// In order to use this mechanism one simply has to add -// iasiothiscallresolver.cpp to the list of files to compile -// and #include -// -// Note that this #include must come after the other ASIO SDK -// #includes, for example: -// -// #include -// #include -// #include -// #include -// #include -// -// Actually the important thing is to #include -// after . We have -// incorporated a test to enforce this ordering. -// -// The code transparently takes care of the interposition by -// using macro substitution to intercept calls to ASIOInit() -// and ASIOExit(). We save the original ASIO global -// "theAsioDriver" in our "that" variable, and then set -// "theAsioDriver" to equal our IASIOThiscallResolver instance. -// -// Whilst this method of resolving the thiscall problem requires -// the addition of #include to client -// code it has the advantage that it does not break the terms -// of the ASIO licence by publishing it. We are NOT modifying -// any Steinberg code here, we are merely implementing the IASIO -// interface in the same way that we would need to do if we -// wished to provide an open source ASIO driver. -// -// For compilation with MinGW -lole32 needs to be added to the -// linker options. For BORLAND, linking with Import32.lib is -// sufficient. -// -// The dependencies are with: CoInitialize, CoUninitialize, -// CoCreateInstance, CLSIDFromString - used by asiolist.cpp -// and are required on Windows whether ThiscallResolver is used -// or not. -// -// Searching for the above strings in the root library path -// of your compiler should enable the correct libraries to be -// identified if they aren't immediately obvious. -// -// Note that the current implementation of IASIOThiscallResolver -// is not COM compliant - it does not correctly implement the -// IUnknown interface. Implementing it is not necessary because -// it is not called by parts of the ASIO SDK which call through -// theAsioDriver ptr. The IUnknown methods are implemented as -// assert(false) to ensure that the code fails if they are -// ever called. -// Restrictions: None. Public Domain & Open Source distribute freely -// You may use IASIOThiscallResolver commercially as well as -// privately. -// You the user assume the responsibility for the use of the -// files, binary or text, and there is no guarantee or warranty, -// expressed or implied, including but not limited to the -// implied warranties of merchantability and fitness for a -// particular purpose. You assume all responsibility and agree -// to hold no entity, copyright holder or distributors liable -// for any loss of data or inaccurate representations of data -// as a result of using IASIOThiscallResolver. -// Version: 1.4 Added separate macro CALL_THISCALL_1_DOUBLE from -// Andrew Baldwin, and volatile for whole gcc asm blocks, -// both for compatibility with newer gcc versions. Cleaned up -// Borland asm to use one less register. -// 1.3 Switched to including assert.h for better compatibility. -// Wrapped entire .h and .cpp contents with a check for -// _MSC_VER to provide better compatibility with MS compilers. -// Changed Singleton implementation to use static instance -// instead of freestore allocated instance. Removed ASIOExit -// macro as it is no longer needed. -// 1.2 Removed semicolons from ASIOInit and ASIOExit macros to -// allow them to be embedded in expressions (if statements). -// Cleaned up some comments. Removed combase.c dependency (it -// doesn't compile with BCB anyway) by stubbing IUnknown. -// 1.1 Incorporated comments from Ross Bencina including things -// such as changing name from ThiscallResolver to -// IASIOThiscallResolver, tidying up the constructor, fixing -// a bug in IASIOThiscallResolver::ASIOExit() and improving -// portability through the use of conditional compilation -// 1.0 Initial working version. -// Created: 6/09/2003 -// Authors: Fraser Adams -// Ross Bencina -// Rene G. Ceballos -// Martin Fay -// Antti Silvast -// Andrew Baldwin -// -// **************************************************************************** - - -#ifndef included_iasiothiscallresolver_h -#define included_iasiothiscallresolver_h - -// We only need IASIOThiscallResolver at all if we are on Win32. For other -// platforms we simply bypass the IASIOThiscallResolver definition to allow us -// to be safely #include'd whatever the platform to keep client code portable -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) - - -// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver -// is not used. -#if !defined(_MSC_VER) - - -// The following is in order to ensure that this header is only included after -// the other ASIO headers (except for the case of iasiothiscallresolver.cpp). -// We need to do this because IASIOThiscallResolver works by eclipsing the -// original definition of ASIOInit() with a macro (see below). -#if !defined(iasiothiscallresolver_sourcefile) - #if !defined(__ASIO_H) - #error iasiothiscallresolver.h must be included AFTER asio.h - #endif -#endif - -#include -#include "iasiodrv.h" /* From ASIO SDK */ - - -class IASIOThiscallResolver : public IASIO { -private: - IASIO* that_; // Points to the real IASIO - - static IASIOThiscallResolver instance; // Singleton instance - - // Constructors - declared private so construction is limited to - // our Singleton instance - IASIOThiscallResolver(); - IASIOThiscallResolver(IASIO* that); -public: - - // Methods from the IUnknown interface. We don't fully implement IUnknown - // because the ASIO SDK never calls these methods through theAsioDriver ptr. - // These methods are implemented as assert(false). - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv); - virtual ULONG STDMETHODCALLTYPE AddRef(); - virtual ULONG STDMETHODCALLTYPE Release(); - - // Methods from the IASIO interface, implemented as forwarning calls to that. - virtual ASIOBool init(void *sysHandle); - virtual void getDriverName(char *name); - virtual long getDriverVersion(); - virtual void getErrorMessage(char *string); - virtual ASIOError start(); - virtual ASIOError stop(); - virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels); - virtual ASIOError getLatencies(long *inputLatency, long *outputLatency); - virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); - virtual ASIOError canSampleRate(ASIOSampleRate sampleRate); - virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate); - virtual ASIOError setSampleRate(ASIOSampleRate sampleRate); - virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); - virtual ASIOError setClockSource(long reference); - virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); - virtual ASIOError getChannelInfo(ASIOChannelInfo *info); - virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks); - virtual ASIOError disposeBuffers(); - virtual ASIOError controlPanel(); - virtual ASIOError future(long selector,void *opt); - virtual ASIOError outputReady(); - - // Class method, see ASIOInit() macro below. - static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit -}; - - -// Replace calls to ASIOInit with our interposing version. -// This macro enables us to perform thiscall resolution simply by #including -// after the asio #includes (this file _must_ be -// included _after_ the asio #includes) - -#define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name)) - - -#endif /* !defined(_MSC_VER) */ - -#endif /* Win32 */ - -#endif /* included_iasiothiscallresolver_h */ - - diff --git a/configure.ac b/configure.ac index e0fac8b..5949a5e 100644 --- a/configure.ac +++ b/configure.ac @@ -15,11 +15,6 @@ if [[ $AR = "no" ]] ; then AC_MSG_ERROR("Could not find ar - needed to create a library"); fi -# Checks for libraries. -AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(RtAudio requires the pthread library!)) - - - # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(sys/ioctl.h unistd.h) @@ -51,6 +46,7 @@ case $host in AC_MSG_RESULT(using OSS) AC_SUBST( audio_apis, [-D__LINUX_OSS__] ) cflags=$cflags" -lossaudio" + AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(RtAudio requires the pthread library!)) ;; *-*-linux*) @@ -64,7 +60,7 @@ case $host in audio_apis="-D__UNIX_JACK__" fi - # Look for Alsa flag + # Look for ALSA flag AC_ARG_WITH(alsa, [ --with-alsa = choose native ALSA API support (linux only)], [AC_SUBST( sound_api, [-D__LINUX_ALSA__] ) AC_MSG_RESULT(using ALSA)], ) if [test $sound_api = -D__LINUX_ALSA__;] then AC_CHECK_LIB(asound, snd_pcm_open, , AC_MSG_ERROR(ALSA support requires the asound library!)) @@ -77,12 +73,14 @@ case $host in audio_apis="-D__LINUX_OSS__ $audio_apis" fi - # If no audio api flags specified, use OSS + # If no audio api flags specified, use ALSA if [test $sound_api = _NO_API_;] then - AC_SUBST( sound_api, [-D__LINUX_OSS__] ) - AC_MSG_RESULT(using OSS) - AC_SUBST( audio_apis, [-D__LINUX_OSS__] ) + AC_MSG_RESULT(using ALSA) + AC_SUBST( audio_apis, [-D__LINUX_ALSA__] ) + AC_CHECK_LIB(asound, snd_pcm_open, , AC_MSG_ERROR(ALSA support requires the asound library!)) fi + + AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(RtAudio requires the pthread library!)) ;; *-apple*) @@ -110,13 +108,16 @@ case $host in [AC_MSG_ERROR(CoreAudio header files not found!)] ) AC_SUBST( frameworks, ["-framework CoreAudio -framework CoreFoundation"] ) fi + + AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(RtAudio requires the pthread library!)) ;; *-mingw32*) AC_SUBST( sound_api, [_NO_API_] ) AC_ARG_WITH(asio, [ --with-asio = choose ASIO API support (windoze only)], [AC_SUBST( sound_api, [-D__WINDOWS_ASIO__] ) AC_MSG_RESULT(using ASIO)], ) - if [test $sound_api = -D__UNIX_ASIO__;] then + if [test $sound_api = -D__WINDOWS_ASIO__;] then audio_apis="-D__WINDOWS_ASIO__" + AC_SUBST( objects, ["asio.o asiodrivers.o asiolist.o iasiothiscallresolver.o"] ) fi # Look for DirectSound flag @@ -133,6 +134,8 @@ case $host in audio_apis="-D__WINDOWS_DS__" LIBS="-ldsound -lwinmm $LIBS" fi + + LIBS="-lole32 $LIBS" ;; *) diff --git a/include/asio.cpp b/include/asio.cpp new file mode 100644 index 0000000..b241663 --- /dev/null +++ b/include/asio.cpp @@ -0,0 +1,257 @@ +/* + Steinberg Audio Stream I/O API + (c) 1996, Steinberg Soft- und Hardware GmbH + + asio.cpp + + asio functions entries which translate the + asio interface to the asiodrvr class methods +*/ + +#include +#include "asiosys.h" // platform definition +#include "asio.h" + +#if MAC +#include "asiodrvr.h" + +#pragma export on + +AsioDriver *theAsioDriver = 0; + +extern "C" +{ + +long main() +{ + return 'ASIO'; +} + +#elif WINDOWS + +#include "windows.h" +#include "iasiodrv.h" +#include "asiodrivers.h" + +IASIO *theAsioDriver = 0; +extern AsioDrivers *asioDrivers; + +#elif SGI || SUN || BEOS || LINUX +#include "asiodrvr.h" +static AsioDriver *theAsioDriver = 0; +#endif + +//----------------------------------------------------------------------------------------------------- +ASIOError ASIOInit(ASIODriverInfo *info) +{ +#if MAC || SGI || SUN || BEOS || LINUX + if(theAsioDriver) + { + delete theAsioDriver; + theAsioDriver = 0; + } + info->driverVersion = 0; + strcpy(info->name, "No ASIO Driver"); + theAsioDriver = getDriver(); + if(!theAsioDriver) + { + strcpy(info->errorMessage, "Not enough memory for the ASIO driver!"); + return ASE_NotPresent; + } + if(!theAsioDriver->init(info->sysRef)) + { + theAsioDriver->getErrorMessage(info->errorMessage); + delete theAsioDriver; + theAsioDriver = 0; + return ASE_NotPresent; + } + strcpy(info->errorMessage, "No ASIO Driver Error"); + theAsioDriver->getDriverName(info->name); + info->driverVersion = theAsioDriver->getDriverVersion(); + return ASE_OK; + +#else + + info->driverVersion = 0; + strcpy(info->name, "No ASIO Driver"); + if(theAsioDriver) // must be loaded! + { + if(!theAsioDriver->init(info->sysRef)) + { + theAsioDriver->getErrorMessage(info->errorMessage); + theAsioDriver = 0; + return ASE_NotPresent; + } + + strcpy(info->errorMessage, "No ASIO Driver Error"); + theAsioDriver->getDriverName(info->name); + info->driverVersion = theAsioDriver->getDriverVersion(); + return ASE_OK; + } + return ASE_NotPresent; + +#endif // !MAC +} + +ASIOError ASIOExit(void) +{ + if(theAsioDriver) + { +#if WINDOWS + asioDrivers->removeCurrentDriver(); +#else + delete theAsioDriver; +#endif + } + theAsioDriver = 0; + return ASE_OK; +} + +ASIOError ASIOStart(void) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->start(); +} + +ASIOError ASIOStop(void) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->stop(); +} + +ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels) +{ + if(!theAsioDriver) + { + *numInputChannels = *numOutputChannels = 0; + return ASE_NotPresent; + } + return theAsioDriver->getChannels(numInputChannels, numOutputChannels); +} + +ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency) +{ + if(!theAsioDriver) + { + *inputLatency = *outputLatency = 0; + return ASE_NotPresent; + } + return theAsioDriver->getLatencies(inputLatency, outputLatency); +} + +ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity) +{ + if(!theAsioDriver) + { + *minSize = *maxSize = *preferredSize = *granularity = 0; + return ASE_NotPresent; + } + return theAsioDriver->getBufferSize(minSize, maxSize, preferredSize, granularity); +} + +ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->canSampleRate(sampleRate); +} + +ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->getSampleRate(currentRate); +} + +ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->setSampleRate(sampleRate); +} + +ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources) +{ + if(!theAsioDriver) + { + *numSources = 0; + return ASE_NotPresent; + } + return theAsioDriver->getClockSources(clocks, numSources); +} + +ASIOError ASIOSetClockSource(long reference) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->setClockSource(reference); +} + +ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->getSamplePosition(sPos, tStamp); +} + +ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info) +{ + if(!theAsioDriver) + { + info->channelGroup = -1; + info->type = ASIOSTInt16MSB; + strcpy(info->name, "None"); + return ASE_NotPresent; + } + return theAsioDriver->getChannelInfo(info); +} + +ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels, + long bufferSize, ASIOCallbacks *callbacks) +{ + if(!theAsioDriver) + { + ASIOBufferInfo *info = bufferInfos; + for(long i = 0; i < numChannels; i++, info++) + info->buffers[0] = info->buffers[1] = 0; + return ASE_NotPresent; + } + return theAsioDriver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks); +} + +ASIOError ASIODisposeBuffers(void) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->disposeBuffers(); +} + +ASIOError ASIOControlPanel(void) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->controlPanel(); +} + +ASIOError ASIOFuture(long selector, void *opt) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->future(selector, opt); +} + +ASIOError ASIOOutputReady(void) +{ + if(!theAsioDriver) + return ASE_NotPresent; + return theAsioDriver->outputReady(); +} + +#if MAC +} // extern "C" +#pragma export off +#endif + + diff --git a/include/asio.h b/include/asio.h new file mode 100644 index 0000000..8ec811f --- /dev/null +++ b/include/asio.h @@ -0,0 +1,1054 @@ +//--------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------- + +/* + Steinberg Audio Stream I/O API + (c) 1997 - 2005, Steinberg Media Technologies GmbH + + ASIO Interface Specification v 2.1 + + 2005 - Added support for DSD sample data (in cooperation with Sony) + + + basic concept is an i/o synchronous double-buffer scheme: + + on bufferSwitch(index == 0), host will read/write: + + after ASIOStart(), the + read first input buffer A (index 0) + | will be invalid (empty) + * ------------------------ + |------------------------|-----------------------| + | | | + | Input Buffer A (0) | Input Buffer B (1) | + | | | + |------------------------|-----------------------| + | | | + | Output Buffer A (0) | Output Buffer B (1) | + | | | + |------------------------|-----------------------| + * ------------------------- + | before calling ASIOStart(), + write host will have filled output + buffer B (index 1) already + + *please* take special care of proper statement of input + and output latencies (see ASIOGetLatencies()), these + control sequencer sync accuracy + +*/ + +//--------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------- + +/* + +prototypes summary: + +ASIOError ASIOInit(ASIODriverInfo *info); +ASIOError ASIOExit(void); +ASIOError ASIOStart(void); +ASIOError ASIOStop(void); +ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels); +ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency); +ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); +ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate); +ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate); +ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate); +ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources); +ASIOError ASIOSetClockSource(long reference); +ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp); +ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info); +ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels, + long bufferSize, ASIOCallbacks *callbacks); +ASIOError ASIODisposeBuffers(void); +ASIOError ASIOControlPanel(void); +void *ASIOFuture(long selector, void *params); +ASIOError ASIOOutputReady(void); + +*/ + +//--------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------- + +#ifndef __ASIO_H +#define __ASIO_H + +// force 4 byte alignment +#if defined(_MSC_VER) && !defined(__MWERKS__) +#pragma pack(push,4) +#elif PRAGMA_ALIGN_SUPPORTED +#pragma options align = native +#endif + +//- - - - - - - - - - - - - - - - - - - - - - - - - +// Type definitions +//- - - - - - - - - - - - - - - - - - - - - - - - - + +// number of samples data type is 64 bit integer +#if NATIVE_INT64 + typedef long long int ASIOSamples; +#else + typedef struct ASIOSamples { + unsigned long hi; + unsigned long lo; + } ASIOSamples; +#endif + +// Timestamp data type is 64 bit integer, +// Time format is Nanoseconds. +#if NATIVE_INT64 + typedef long long int ASIOTimeStamp ; +#else + typedef struct ASIOTimeStamp { + unsigned long hi; + unsigned long lo; + } ASIOTimeStamp; +#endif + +// Samplerates are expressed in IEEE 754 64 bit double float, +// native format as host computer +#if IEEE754_64FLOAT + typedef double ASIOSampleRate; +#else + typedef struct ASIOSampleRate { + char ieee[8]; + } ASIOSampleRate; +#endif + +// Boolean values are expressed as long +typedef long ASIOBool; +enum { + ASIOFalse = 0, + ASIOTrue = 1 +}; + +// Sample Types are expressed as long +typedef long ASIOSampleType; +enum { + ASIOSTInt16MSB = 0, + ASIOSTInt24MSB = 1, // used for 20 bits as well + ASIOSTInt32MSB = 2, + ASIOSTFloat32MSB = 3, // IEEE 754 32 bit float + ASIOSTFloat64MSB = 4, // IEEE 754 64 bit double float + + // these are used for 32 bit data buffer, with different alignment of the data inside + // 32 bit PCI bus systems can be more easily used with these + ASIOSTInt32MSB16 = 8, // 32 bit data with 16 bit alignment + ASIOSTInt32MSB18 = 9, // 32 bit data with 18 bit alignment + ASIOSTInt32MSB20 = 10, // 32 bit data with 20 bit alignment + ASIOSTInt32MSB24 = 11, // 32 bit data with 24 bit alignment + + ASIOSTInt16LSB = 16, + ASIOSTInt24LSB = 17, // used for 20 bits as well + ASIOSTInt32LSB = 18, + ASIOSTFloat32LSB = 19, // IEEE 754 32 bit float, as found on Intel x86 architecture + ASIOSTFloat64LSB = 20, // IEEE 754 64 bit double float, as found on Intel x86 architecture + + // these are used for 32 bit data buffer, with different alignment of the data inside + // 32 bit PCI bus systems can more easily used with these + ASIOSTInt32LSB16 = 24, // 32 bit data with 18 bit alignment + ASIOSTInt32LSB18 = 25, // 32 bit data with 18 bit alignment + ASIOSTInt32LSB20 = 26, // 32 bit data with 20 bit alignment + ASIOSTInt32LSB24 = 27, // 32 bit data with 24 bit alignment + + // ASIO DSD format. + ASIOSTDSDInt8LSB1 = 32, // DSD 1 bit data, 8 samples per byte. First sample in Least significant bit. + ASIOSTDSDInt8MSB1 = 33, // DSD 1 bit data, 8 samples per byte. First sample in Most significant bit. + ASIOSTDSDInt8NER8 = 40, // DSD 8 bit data, 1 sample per byte. No Endianness required. + + ASIOSTLastEntry +}; + +/*----------------------------------------------------------------------------- +// DSD operation and buffer layout +// Definition by Steinberg/Sony Oxford. +// +// We have tried to treat DSD as PCM and so keep a consistant structure across +// the ASIO interface. +// +// DSD's sample rate is normally referenced as a multiple of 44.1Khz, so +// the standard sample rate is refered to as 64Fs (or 2.8224Mhz). We looked +// at making a special case for DSD and adding a field to the ASIOFuture that +// would allow the user to select the Over Sampleing Rate (OSR) as a seperate +// entity but decided in the end just to treat it as a simple value of +// 2.8224Mhz and use the standard interface to set it. +// +// The second problem was the "word" size, in PCM the word size is always a +// greater than or equal to 8 bits (a byte). This makes life easy as we can +// then pack the samples into the "natural" size for the machine. +// In DSD the "word" size is 1 bit. This is not a major problem and can easily +// be dealt with if we ensure that we always deal with a multiple of 8 samples. +// +// DSD brings with it another twist to the Endianness religion. How are the +// samples packed into the byte. It would be nice to just say the most significant +// bit is always the first sample, however there would then be a performance hit +// on little endian machines. Looking at how some of the processing goes... +// Little endian machines like the first sample to be in the Least Significant Bit, +// this is because when you write it to memory the data is in the correct format +// to be shifted in and out of the words. +// Big endian machine prefer the first sample to be in the Most Significant Bit, +// again for the same reasion. +// +// And just when things were looking really muddy there is a proposed extension to +// DSD that uses 8 bit word sizes. It does not care what endianness you use. +// +// Switching the driver between DSD and PCM mode +// ASIOFuture allows for extending the ASIO API quite transparently. +// See kAsioSetIoFormat, kAsioGetIoFormat, kAsioCanDoIoFormat +// +//-----------------------------------------------------------------------------*/ + + +//- - - - - - - - - - - - - - - - - - - - - - - - - +// Error codes +//- - - - - - - - - - - - - - - - - - - - - - - - - + +typedef long ASIOError; +enum { + ASE_OK = 0, // This value will be returned whenever the call succeeded + ASE_SUCCESS = 0x3f4847a0, // unique success return value for ASIOFuture calls + ASE_NotPresent = -1000, // hardware input or output is not present or available + ASE_HWMalfunction, // hardware is malfunctioning (can be returned by any ASIO function) + ASE_InvalidParameter, // input parameter invalid + ASE_InvalidMode, // hardware is in a bad mode or used in a bad mode + ASE_SPNotAdvancing, // hardware is not running when sample position is inquired + ASE_NoClock, // sample clock or rate cannot be determined or is not present + ASE_NoMemory // not enough memory for completing the request +}; + +//--------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------- + +//- - - - - - - - - - - - - - - - - - - - - - - - - +// Time Info support +//- - - - - - - - - - - - - - - - - - - - - - - - - + +typedef struct ASIOTimeCode +{ + double speed; // speed relation (fraction of nominal speed) + // optional; set to 0. or 1. if not supported + ASIOSamples timeCodeSamples; // time in samples + unsigned long flags; // some information flags (see below) + char future[64]; +} ASIOTimeCode; + +typedef enum ASIOTimeCodeFlags +{ + kTcValid = 1, + kTcRunning = 1 << 1, + kTcReverse = 1 << 2, + kTcOnspeed = 1 << 3, + kTcStill = 1 << 4, + + kTcSpeedValid = 1 << 8 +} ASIOTimeCodeFlags; + +typedef struct AsioTimeInfo +{ + double speed; // absolute speed (1. = nominal) + ASIOTimeStamp systemTime; // system time related to samplePosition, in nanoseconds + // on mac, must be derived from Microseconds() (not UpTime()!) + // on windows, must be derived from timeGetTime() + ASIOSamples samplePosition; + ASIOSampleRate sampleRate; // current rate + unsigned long flags; // (see below) + char reserved[12]; +} AsioTimeInfo; + +typedef enum AsioTimeInfoFlags +{ + kSystemTimeValid = 1, // must always be valid + kSamplePositionValid = 1 << 1, // must always be valid + kSampleRateValid = 1 << 2, + kSpeedValid = 1 << 3, + + kSampleRateChanged = 1 << 4, + kClockSourceChanged = 1 << 5 +} AsioTimeInfoFlags; + +typedef struct ASIOTime // both input/output +{ + long reserved[4]; // must be 0 + struct AsioTimeInfo timeInfo; // required + struct ASIOTimeCode timeCode; // optional, evaluated if (timeCode.flags & kTcValid) +} ASIOTime; + +/* + +using time info: +it is recommended to use the new method with time info even if the asio +device does not support timecode; continuous calls to ASIOGetSamplePosition +and ASIOGetSampleRate are avoided, and there is a more defined relationship +between callback time and the time info. + +see the example below. +to initiate time info mode, after you have received the callbacks pointer in +ASIOCreateBuffers, you will call the asioMessage callback with kAsioSupportsTimeInfo +as the argument. if this returns 1, host has accepted time info mode. +now host expects the new callback bufferSwitchTimeInfo to be used instead +of the old bufferSwitch method. the ASIOTime structure is assumed to be valid +and accessible until the callback returns. + +using time code: +if the device supports reading time code, it will call host's asioMessage callback +with kAsioSupportsTimeCode as the selector. it may then fill the according +fields and set the kTcValid flag. +host will call the future method with the kAsioEnableTimeCodeRead selector when +it wants to enable or disable tc reading by the device. you should also support +the kAsioCanTimeInfo and kAsioCanTimeCode selectors in ASIOFuture (see example). + +note: +the AsioTimeInfo/ASIOTimeCode pair is supposed to work in both directions. +as a matter of convention, the relationship between the sample +position counter and the time code at buffer switch time is +(ignoring offset between tc and sample pos when tc is running): + +on input: sample 0 -> input buffer sample 0 -> time code 0 +on output: sample 0 -> output buffer sample 0 -> time code 0 + +this means that for 'real' calculations, one has to take into account +the according latencies. + +example: + +ASIOTime asioTime; + +in createBuffers() +{ + memset(&asioTime, 0, sizeof(ASIOTime)); + AsioTimeInfo* ti = &asioTime.timeInfo; + ti->sampleRate = theSampleRate; + ASIOTimeCode* tc = &asioTime.timeCode; + tc->speed = 1.; + timeInfoMode = false; + canTimeCode = false; + if(callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0) == 1) + { + timeInfoMode = true; +#if kCanTimeCode + if(callbacks->asioMessage(kAsioSupportsTimeCode, 0, 0, 0) == 1) + canTimeCode = true; +#endif + } +} + +void switchBuffers(long doubleBufferIndex, bool processNow) +{ + if(timeInfoMode) + { + AsioTimeInfo* ti = &asioTime.timeInfo; + ti->flags = kSystemTimeValid | kSamplePositionValid | kSampleRateValid; + ti->systemTime = theNanoSeconds; + ti->samplePosition = theSamplePosition; + if(ti->sampleRate != theSampleRate) + ti->flags |= kSampleRateChanged; + ti->sampleRate = theSampleRate; + +#if kCanTimeCode + if(canTimeCode && timeCodeEnabled) + { + ASIOTimeCode* tc = &asioTime.timeCode; + tc->timeCodeSamples = tcSamples; // tc in samples + tc->flags = kTcValid | kTcRunning | kTcOnspeed; // if so... + } + ASIOTime* bb = callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse); +#else + callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse); +#endif + } + else + callbacks->bufferSwitch(doubleBufferIndex, ASIOFalse); +} + +ASIOError ASIOFuture(long selector, void *params) +{ + switch(selector) + { + case kAsioEnableTimeCodeRead: + timeCodeEnabled = true; + return ASE_SUCCESS; + case kAsioDisableTimeCodeRead: + timeCodeEnabled = false; + return ASE_SUCCESS; + case kAsioCanTimeInfo: + return ASE_SUCCESS; + #if kCanTimeCode + case kAsioCanTimeCode: + return ASE_SUCCESS; + #endif + } + return ASE_NotPresent; +}; + +*/ + +//- - - - - - - - - - - - - - - - - - - - - - - - - +// application's audio stream handler callbacks +//- - - - - - - - - - - - - - - - - - - - - - - - - + +typedef struct ASIOCallbacks +{ + void (*bufferSwitch) (long doubleBufferIndex, ASIOBool directProcess); + // bufferSwitch indicates that both input and output are to be processed. + // the current buffer half index (0 for A, 1 for B) determines + // - the output buffer that the host should start to fill. the other buffer + // will be passed to output hardware regardless of whether it got filled + // in time or not. + // - the input buffer that is now filled with incoming data. Note that + // because of the synchronicity of i/o, the input always has at + // least one buffer latency in relation to the output. + // directProcess suggests to the host whether it should immedeately + // start processing (directProcess == ASIOTrue), or whether its process + // should be deferred because the call comes from a very low level + // (for instance, a high level priority interrupt), and direct processing + // would cause timing instabilities for the rest of the system. If in doubt, + // directProcess should be set to ASIOFalse. + // Note: bufferSwitch may be called at interrupt time for highest efficiency. + + void (*sampleRateDidChange) (ASIOSampleRate sRate); + // gets called when the AudioStreamIO detects a sample rate change + // If sample rate is unknown, 0 is passed (for instance, clock loss + // when externally synchronized). + + long (*asioMessage) (long selector, long value, void* message, double* opt); + // generic callback for various purposes, see selectors below. + // note this is only present if the asio version is 2 or higher + + ASIOTime* (*bufferSwitchTimeInfo) (ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess); + // new callback with time info. makes ASIOGetSamplePosition() and various + // calls to ASIOGetSampleRate obsolete, + // and allows for timecode sync etc. to be preferred; will be used if + // the driver calls asioMessage with selector kAsioSupportsTimeInfo. +} ASIOCallbacks; + +// asioMessage selectors +enum +{ + kAsioSelectorSupported = 1, // selector in , returns 1L if supported, + // 0 otherwise + kAsioEngineVersion, // returns engine (host) asio implementation version, + // 2 or higher + kAsioResetRequest, // request driver reset. if accepted, this + // will close the driver (ASIO_Exit() ) and + // re-open it again (ASIO_Init() etc). some + // drivers need to reconfigure for instance + // when the sample rate changes, or some basic + // changes have been made in ASIO_ControlPanel(). + // returns 1L; note the request is merely passed + // to the application, there is no way to determine + // if it gets accepted at this time (but it usually + // will be). + kAsioBufferSizeChange, // not yet supported, will currently always return 0L. + // for now, use kAsioResetRequest instead. + // once implemented, the new buffer size is expected + // in , and on success returns 1L + kAsioResyncRequest, // the driver went out of sync, such that + // the timestamp is no longer valid. this + // is a request to re-start the engine and + // slave devices (sequencer). returns 1 for ok, + // 0 if not supported. + kAsioLatenciesChanged, // the drivers latencies have changed. The engine + // will refetch the latencies. + kAsioSupportsTimeInfo, // if host returns true here, it will expect the + // callback bufferSwitchTimeInfo to be called instead + // of bufferSwitch + kAsioSupportsTimeCode, // + kAsioMMCCommand, // unused - value: number of commands, message points to mmc commands + kAsioSupportsInputMonitor, // kAsioSupportsXXX return 1 if host supports this + kAsioSupportsInputGain, // unused and undefined + kAsioSupportsInputMeter, // unused and undefined + kAsioSupportsOutputGain, // unused and undefined + kAsioSupportsOutputMeter, // unused and undefined + kAsioOverload, // driver detected an overload + + kAsioNumMessageSelectors +}; + +//--------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------- + +//- - - - - - - - - - - - - - - - - - - - - - - - - +// (De-)Construction +//- - - - - - - - - - - - - - - - - - - - - - - - - + +typedef struct ASIODriverInfo +{ + long asioVersion; // currently, 2 + long driverVersion; // driver specific + char name[32]; + char errorMessage[124]; + void *sysRef; // on input: system reference + // (Windows: application main window handle, Mac & SGI: 0) +} ASIODriverInfo; + +ASIOError ASIOInit(ASIODriverInfo *info); +/* Purpose: + Initialize the AudioStreamIO. + Parameter: + info: pointer to an ASIODriver structure: + - asioVersion: + - on input, the host version. *** Note *** this is 0 for earlier asio + implementations, and the asioMessage callback is implemeted + only if asioVersion is 2 or greater. sorry but due to a design fault + the driver doesn't have access to the host version in ASIOInit :-( + added selector for host (engine) version in the asioMessage callback + so we're ok from now on. + - on return, asio implementation version. + older versions are 1 + if you support this version (namely, ASIO_outputReady() ) + this should be 2 or higher. also see the note in + ASIO_getTimeStamp() ! + - version: on return, the driver version (format is driver specific) + - name: on return, a null-terminated string containing the driver's name + - error message: on return, should contain a user message describing + the type of error that occured during ASIOInit(), if any. + - sysRef: platform specific + Returns: + If neither input nor output is present ASE_NotPresent + will be returned. + ASE_NoMemory, ASE_HWMalfunction are other possible error conditions +*/ + +ASIOError ASIOExit(void); +/* Purpose: + Terminates the AudioStreamIO. + Parameter: + None. + Returns: + If neither input nor output is present ASE_NotPresent + will be returned. + Notes: this implies ASIOStop() and ASIODisposeBuffers(), + meaning that no host callbacks must be accessed after ASIOExit(). +*/ + +//- - - - - - - - - - - - - - - - - - - - - - - - - +// Start/Stop +//- - - - - - - - - - - - - - - - - - - - - - - - - + +ASIOError ASIOStart(void); +/* Purpose: + Start input and output processing synchronously. + This will + - reset the sample counter to zero + - start the hardware (both input and output) + The first call to the hosts' bufferSwitch(index == 0) then tells + the host to read from input buffer A (index 0), and start + processing to output buffer A while output buffer B (which + has been filled by the host prior to calling ASIOStart()) + is possibly sounding (see also ASIOGetLatencies()) + Parameter: + None. + Returns: + If neither input nor output is present, ASE_NotPresent + will be returned. + If the hardware fails to start, ASE_HWMalfunction will be returned. + Notes: + There is no restriction on the time that ASIOStart() takes + to perform (that is, it is not considered a realtime trigger). +*/ + +ASIOError ASIOStop(void); +/* Purpose: + Stops input and output processing altogether. + Parameter: + None. + Returns: + If neither input nor output is present ASE_NotPresent + will be returned. + Notes: + On return from ASIOStop(), the driver must in no + case call the hosts' bufferSwitch() routine. +*/ + +//- - - - - - - - - - - - - - - - - - - - - - - - - +// Inquiry methods and sample rate +//- - - - - - - - - - - - - - - - - - - - - - - - - + +ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels); +/* Purpose: + Returns number of individual input/output channels. + Parameter: + numInputChannels will hold the number of available input channels + numOutputChannels will hold the number of available output channels + Returns: + If no input/output is present ASE_NotPresent will be returned. + If only inputs, or only outputs are available, the according + other parameter will be zero, and ASE_OK is returned. +*/ + +ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency); +/* Purpose: + Returns the input and output latencies. This includes + device specific delays, like FIFOs etc. + Parameter: + inputLatency will hold the 'age' of the first sample frame + in the input buffer when the hosts reads it in bufferSwitch() + (this is theoretical, meaning it does not include the overhead + and delay between the actual physical switch, and the time + when bufferSitch() enters). + This will usually be the size of one block in sample frames, plus + device specific latencies. + + outputLatency will specify the time between the buffer switch, + and the time when the next play buffer will start to sound. + The next play buffer is defined as the one the host starts + processing after (or at) bufferSwitch(), indicated by the + index parameter (0 for buffer A, 1 for buffer B). + It will usually be either one block, if the host writes directly + to a dma buffer, or two or more blocks if the buffer is 'latched' by + the driver. As an example, on ASIOStart(), the host will have filled + the play buffer at index 1 already; when it gets the callback (with + the parameter index == 0), this tells it to read from the input + buffer 0, and start to fill the play buffer 0 (assuming that now + play buffer 1 is already sounding). In this case, the output + latency is one block. If the driver decides to copy buffer 1 + at that time, and pass it to the hardware at the next slot (which + is most commonly done, but should be avoided), the output latency + becomes two blocks instead, resulting in a total i/o latency of at least + 3 blocks. As memory access is the main bottleneck in native dsp processing, + and to acheive less latency, it is highly recommended to try to avoid + copying (this is also why the driver is the owner of the buffers). To + summarize, the minimum i/o latency can be acheived if the input buffer + is processed by the host into the output buffer which will physically + start to sound on the next time slice. Also note that the host expects + the bufferSwitch() callback to be accessed for each time slice in order + to retain sync, possibly recursively; if it fails to process a block in + time, it will suspend its operation for some time in order to recover. + Returns: + If no input/output is present ASE_NotPresent will be returned. +*/ + +ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); +/* Purpose: + Returns min, max, and preferred buffer sizes for input/output + Parameter: + minSize will hold the minimum buffer size + maxSize will hold the maxium possible buffer size + preferredSize will hold the preferred buffer size (a size which + best fits performance and hardware requirements) + granularity will hold the granularity at which buffer sizes + may differ. Usually, the buffer size will be a power of 2; + in this case, granularity will hold -1 on return, signalling + possible buffer sizes starting from minSize, increased in + powers of 2 up to maxSize. + Returns: + If no input/output is present ASE_NotPresent will be returned. + Notes: + When minimum and maximum buffer size are equal, + the preferred buffer size has to be the same value as well; granularity + should be 0 in this case. +*/ + +ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate); +/* Purpose: + Inquires the hardware for the available sample rates. + Parameter: + sampleRate is the rate in question. + Returns: + If the inquired sample rate is not supported, ASE_NoClock will be returned. + If no input/output is present ASE_NotPresent will be returned. +*/ +ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate); +/* Purpose: + Get the current sample Rate. + Parameter: + currentRate will hold the current sample rate on return. + Returns: + If sample rate is unknown, sampleRate will be 0 and ASE_NoClock will be returned. + If no input/output is present ASE_NotPresent will be returned. + Notes: +*/ + +ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate); +/* Purpose: + Set the hardware to the requested sample Rate. If sampleRate == 0, + enable external sync. + Parameter: + sampleRate: on input, the requested rate + Returns: + If sampleRate is unknown ASE_NoClock will be returned. + If the current clock is external, and sampleRate is != 0, + ASE_InvalidMode will be returned + If no input/output is present ASE_NotPresent will be returned. + Notes: +*/ + +typedef struct ASIOClockSource +{ + long index; // as used for ASIOSetClockSource() + long associatedChannel; // for instance, S/PDIF or AES/EBU + long associatedGroup; // see channel groups (ASIOGetChannelInfo()) + ASIOBool isCurrentSource; // ASIOTrue if this is the current clock source + char name[32]; // for user selection +} ASIOClockSource; + +ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources); +/* Purpose: + Get the available external audio clock sources + Parameter: + clocks points to an array of ASIOClockSource structures: + - index: this is used to identify the clock source + when ASIOSetClockSource() is accessed, should be + an index counting from zero + - associatedInputChannel: the first channel of an associated + input group, if any. + - associatedGroup: the group index of that channel. + groups of channels are defined to seperate for + instance analog, S/PDIF, AES/EBU, ADAT connectors etc, + when present simultaniously. Note that associated channel + is enumerated according to numInputs/numOutputs, means it + is independant from a group (see also ASIOGetChannelInfo()) + inputs are associated to a clock if the physical connection + transfers both data and clock (like S/PDIF, AES/EBU, or + ADAT inputs). if there is no input channel associated with + the clock source (like Word Clock, or internal oscillator), both + associatedChannel and associatedGroup should be set to -1. + - isCurrentSource: on exit, ASIOTrue if this is the current clock + source, ASIOFalse else + - name: a null-terminated string for user selection of the available sources. + numSources: + on input: the number of allocated array members + on output: the number of available clock sources, at least + 1 (internal clock generator). + Returns: + If no input/output is present ASE_NotPresent will be returned. + Notes: +*/ + +ASIOError ASIOSetClockSource(long index); +/* Purpose: + Set the audio clock source + Parameter: + index as obtained from an inquiry to ASIOGetClockSources() + Returns: + If no input/output is present ASE_NotPresent will be returned. + If the clock can not be selected because an input channel which + carries the current clock source is active, ASE_InvalidMode + *may* be returned (this depends on the properties of the driver + and/or hardware). + Notes: + Should *not* return ASE_NoClock if there is no clock signal present + at the selected source; this will be inquired via ASIOGetSampleRate(). + It should call the host callback procedure sampleRateHasChanged(), + if the switch causes a sample rate change, or if no external clock + is present at the selected source. +*/ + +ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp); +/* Purpose: + Inquires the sample position/time stamp pair. + Parameter: + sPos will hold the sample position on return. The sample + position is reset to zero when ASIOStart() gets called. + tStamp will hold the system time when the sample position + was latched. + Returns: + If no input/output is present, ASE_NotPresent will be returned. + If there is no clock, ASE_SPNotAdvancing will be returned. + Notes: + + in order to be able to synchronise properly, + the sample position / time stamp pair must refer to the current block, + that is, the engine will call ASIOGetSamplePosition() in its bufferSwitch() + callback and expect the time for the current block. thus, when requested + in the very first bufferSwitch after ASIO_Start(), the sample position + should be zero, and the time stamp should refer to the very time where + the stream was started. it also means that the sample position must be + block aligned. the driver must ensure proper interpolation if the system + time can not be determined for the block position. the driver is responsible + for precise time stamps as it usually has most direct access to lower + level resources. proper behaviour of ASIO_GetSamplePosition() and ASIO_GetLatencies() + are essential for precise media synchronization! +*/ + +typedef struct ASIOChannelInfo +{ + long channel; // on input, channel index + ASIOBool isInput; // on input + ASIOBool isActive; // on exit + long channelGroup; // dto + ASIOSampleType type; // dto + char name[32]; // dto +} ASIOChannelInfo; + +ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info); +/* Purpose: + retreive information about the nature of a channel + Parameter: + info: pointer to a ASIOChannelInfo structure with + - channel: on input, the channel index of the channel in question. + - isInput: on input, ASIOTrue if info for an input channel is + requested, else output + - channelGroup: on return, the channel group that the channel + belongs to. For drivers which support different types of + channels, like analog, S/PDIF, AES/EBU, ADAT etc interfaces, + there should be a reasonable grouping of these types. Groups + are always independant form a channel index, that is, a channel + index always counts from 0 to numInputs/numOutputs regardless + of the group it may belong to. + There will always be at least one group (group 0). Please + also note that by default, the host may decide to activate + channels 0 and 1; thus, these should belong to the most + useful type (analog i/o, if present). + - type: on return, contains the sample type of the channel + - isActive: on return, ASIOTrue if channel is active as it was + installed by ASIOCreateBuffers(), ASIOFalse else + - name: describing the type of channel in question. Used to allow + for user selection, and enabling of specific channels. examples: + "Analog In", "SPDIF Out" etc + Returns: + If no input/output is present ASE_NotPresent will be returned. + Notes: + If possible, the string should be organised such that the first + characters are most significantly describing the nature of the + port, to allow for identification even if the view showing the + port name is too small to display more than 8 characters, for + instance. +*/ + +//- - - - - - - - - - - - - - - - - - - - - - - - - +// Buffer preparation +//- - - - - - - - - - - - - - - - - - - - - - - - - + +typedef struct ASIOBufferInfo +{ + ASIOBool isInput; // on input: ASIOTrue: input, else output + long channelNum; // on input: channel index + void *buffers[2]; // on output: double buffer addresses +} ASIOBufferInfo; + +ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels, + long bufferSize, ASIOCallbacks *callbacks); + +/* Purpose: + Allocates input/output buffers for all input and output channels to be activated. + Parameter: + bufferInfos is a pointer to an array of ASIOBufferInfo structures: + - isInput: on input, ASIOTrue if the buffer is to be allocated + for an input, output buffer else + - channelNum: on input, the index of the channel in question + (counting from 0) + - buffers: on exit, 2 pointers to the halves of the channels' double-buffer. + the size of the buffer(s) of course depend on both the ASIOSampleType + as obtained from ASIOGetChannelInfo(), and bufferSize + numChannels is the sum of all input and output channels to be created; + thus bufferInfos is a pointer to an array of numChannels ASIOBufferInfo + structures. + bufferSize selects one of the possible buffer sizes as obtained from + ASIOGetBufferSizes(). + callbacks is a pointer to an ASIOCallbacks structure. + Returns: + If not enough memory is available ASE_NoMemory will be returned. + If no input/output is present ASE_NotPresent will be returned. + If bufferSize is not supported, or one or more of the bufferInfos elements + contain invalid settings, ASE_InvalidMode will be returned. + Notes: + If individual channel selection is not possible but requested, + the driver has to handle this. namely, bufferSwitch() will only + have filled buffers of enabled outputs. If possible, processing + and buss activities overhead should be avoided for channels which + were not enabled here. +*/ + +ASIOError ASIODisposeBuffers(void); +/* Purpose: + Releases all buffers for the device. + Parameter: + None. + Returns: + If no buffer were ever prepared, ASE_InvalidMode will be returned. + If no input/output is present ASE_NotPresent will be returned. + Notes: + This implies ASIOStop(). +*/ + +ASIOError ASIOControlPanel(void); +/* Purpose: + request the driver to start a control panel component + for device specific user settings. This will not be + accessed on some platforms (where the component is accessed + instead). + Parameter: + None. + Returns: + If no panel is available ASE_NotPresent will be returned. + Actually, the return code is ignored. + Notes: + if the user applied settings which require a re-configuration + of parts or all of the enigine and/or driver (such as a change of + the block size), the asioMessage callback can be used (see + ASIO_Callbacks). +*/ + +ASIOError ASIOFuture(long selector, void *params); +/* Purpose: + various + Parameter: + selector: operation Code as to be defined. zero is reserved for + testing purposes. + params: depends on the selector; usually pointer to a structure + for passing and retreiving any type and amount of parameters. + Returns: + the return value is also selector dependant. if the selector + is unknown, ASE_InvalidParameter should be returned to prevent + further calls with this selector. on success, ASE_SUCCESS + must be returned (note: ASE_OK is *not* sufficient!) + Notes: + see selectors defined below. +*/ + +enum +{ + kAsioEnableTimeCodeRead = 1, // no arguments + kAsioDisableTimeCodeRead, // no arguments + kAsioSetInputMonitor, // ASIOInputMonitor* in params + kAsioTransport, // ASIOTransportParameters* in params + kAsioSetInputGain, // ASIOChannelControls* in params, apply gain + kAsioGetInputMeter, // ASIOChannelControls* in params, fill meter + kAsioSetOutputGain, // ASIOChannelControls* in params, apply gain + kAsioGetOutputMeter, // ASIOChannelControls* in params, fill meter + kAsioCanInputMonitor, // no arguments for kAsioCanXXX selectors + kAsioCanTimeInfo, + kAsioCanTimeCode, + kAsioCanTransport, + kAsioCanInputGain, + kAsioCanInputMeter, + kAsioCanOutputGain, + kAsioCanOutputMeter, + + // DSD support + // The following extensions are required to allow switching + // and control of the DSD subsystem. + kAsioSetIoFormat = 0x23111961, /* ASIOIoFormat * in params. */ + kAsioGetIoFormat = 0x23111983, /* ASIOIoFormat * in params. */ + kAsioCanDoIoFormat = 0x23112004, /* ASIOIoFormat * in params. */ +}; + +typedef struct ASIOInputMonitor +{ + long input; // this input was set to monitor (or off), -1: all + long output; // suggested output for monitoring the input (if so) + long gain; // suggested gain, ranging 0 - 0x7fffffffL (-inf to +12 dB) + ASIOBool state; // ASIOTrue => on, ASIOFalse => off + long pan; // suggested pan, 0 => all left, 0x7fffffff => right +} ASIOInputMonitor; + +typedef struct ASIOChannelControls +{ + long channel; // on input, channel index + ASIOBool isInput; // on input + long gain; // on input, ranges 0 thru 0x7fffffff + long meter; // on return, ranges 0 thru 0x7fffffff + char future[32]; +} ASIOChannelControls; + +typedef struct ASIOTransportParameters +{ + long command; // see enum below + ASIOSamples samplePosition; + long track; + long trackSwitches[16]; // 512 tracks on/off + char future[64]; +} ASIOTransportParameters; + +enum +{ + kTransStart = 1, + kTransStop, + kTransLocate, // to samplePosition + kTransPunchIn, + kTransPunchOut, + kTransArmOn, // track + kTransArmOff, // track + kTransMonitorOn, // track + kTransMonitorOff, // track + kTransArm, // trackSwitches + kTransMonitor // trackSwitches +}; + +/* +// DSD support +// Some notes on how to use ASIOIoFormatType. +// +// The caller will fill the format with the request types. +// If the board can do the request then it will leave the +// values unchanged. If the board does not support the +// request then it will change that entry to Invalid (-1) +// +// So to request DSD then +// +// ASIOIoFormat NeedThis={kASIODSDFormat}; +// +// if(ASE_SUCCESS != ASIOFuture(kAsioSetIoFormat,&NeedThis) ){ +// // If the board did not accept one of the parameters then the +// // whole call will fail and the failing parameter will +// // have had its value changes to -1. +// } +// +// Note: Switching between the formats need to be done before the "prepared" +// state (see ASIO 2 documentation) is entered. +*/ +typedef long int ASIOIoFormatType; +enum ASIOIoFormatType_e +{ + kASIOFormatInvalid = -1, + kASIOPCMFormat = 0, + kASIODSDFormat = 1, +}; + +typedef struct ASIOIoFormat_s +{ + ASIOIoFormatType FormatType; + char future[512-sizeof(ASIOIoFormatType)]; +} ASIOIoFormat; + + +ASIOError ASIOOutputReady(void); +/* Purpose: + this tells the driver that the host has completed processing + the output buffers. if the data format required by the hardware + differs from the supported asio formats, but the hardware + buffers are DMA buffers, the driver will have to convert + the audio stream data; as the bufferSwitch callback is + usually issued at dma block switch time, the driver will + have to convert the *previous* host buffer, which increases + the output latency by one block. + when the host finds out that ASIOOutputReady() returns + true, it will issue this call whenever it completed + output processing. then the driver can convert the + host data directly to the dma buffer to be played next, + reducing output latency by one block. + another way to look at it is, that the buffer switch is called + in order to pass the *input* stream to the host, so that it can + process the input into the output, and the output stream is passed + to the driver when the host has completed its process. + Parameter: + None + Returns: + only if the above mentioned scenario is given, and a reduction + of output latency can be acheived by this mechanism, should + ASE_OK be returned. otherwise (and usually), ASE_NotPresent + should be returned in order to prevent further calls to this + function. note that the host may want to determine if it is + to use this when the system is not yet fully initialized, so + ASE_OK should always be returned if the mechanism makes sense. + Notes: + please remeber to adjust ASIOGetLatencies() according to + whether ASIOOutputReady() was ever called or not, if your + driver supports this scenario. + also note that the engine may fail to call ASIO_OutputReady() + in time in overload cases. as already mentioned, bufferSwitch + should be called for every block regardless of whether a block + could be processed in time. +*/ + +// restore old alignment +#if defined(_MSC_VER) && !defined(__MWERKS__) +#pragma pack(pop) +#elif PRAGMA_ALIGN_SUPPORTED +#pragma options align = reset +#endif + +#endif + diff --git a/include/asiodrivers.cpp b/include/asiodrivers.cpp new file mode 100644 index 0000000..5f56454 --- /dev/null +++ b/include/asiodrivers.cpp @@ -0,0 +1,186 @@ +#include +#include "asiodrivers.h" + +AsioDrivers* asioDrivers = 0; + +bool loadAsioDriver(char *name); + +bool loadAsioDriver(char *name) +{ + if(!asioDrivers) + asioDrivers = new AsioDrivers(); + if(asioDrivers) + return asioDrivers->loadDriver(name); + return false; +} + +//------------------------------------------------------------------------------------ + +#if MAC + +bool resolveASIO(unsigned long aconnID); + +AsioDrivers::AsioDrivers() : CodeFragments("ASIO Drivers", 'AsDr', 'Asio') +{ + connID = -1; + curIndex = -1; +} + +AsioDrivers::~AsioDrivers() +{ + removeCurrentDriver(); +} + +bool AsioDrivers::getCurrentDriverName(char *name) +{ + if(curIndex >= 0) + return getName(curIndex, name); + return false; +} + +long AsioDrivers::getDriverNames(char **names, long maxDrivers) +{ + for(long i = 0; i < getNumFragments() && i < maxDrivers; i++) + getName(i, names[i]); + return getNumFragments() < maxDrivers ? getNumFragments() : maxDrivers; +} + +bool AsioDrivers::loadDriver(char *name) +{ + char dname[64]; + unsigned long newID; + + for(long i = 0; i < getNumFragments(); i++) + { + if(getName(i, dname) && !strcmp(name, dname)) + { + if(newInstance(i, &newID)) + { + if(resolveASIO(newID)) + { + if(connID != -1) + removeInstance(curIndex, connID); + curIndex = i; + connID = newID; + return true; + } + } + break; + } + } + return false; +} + +void AsioDrivers::removeCurrentDriver() +{ + if(connID != -1) + removeInstance(curIndex, connID); + connID = -1; + curIndex = -1; +} + +//------------------------------------------------------------------------------------ + +#elif WINDOWS + +#include "iasiodrv.h" + +extern IASIO* theAsioDriver; + +AsioDrivers::AsioDrivers() : AsioDriverList() +{ + curIndex = -1; +} + +AsioDrivers::~AsioDrivers() +{ +} + +bool AsioDrivers::getCurrentDriverName(char *name) +{ + if(curIndex >= 0) + return asioGetDriverName(curIndex, name, 32) == 0 ? true : false; + name[0] = 0; + return false; +} + +long AsioDrivers::getDriverNames(char **names, long maxDrivers) +{ + for(long i = 0; i < asioGetNumDev() && i < maxDrivers; i++) + asioGetDriverName(i, names[i], 32); + return asioGetNumDev() < maxDrivers ? asioGetNumDev() : maxDrivers; +} + +bool AsioDrivers::loadDriver(char *name) +{ + char dname[64]; + char curName[64]; + + for(long i = 0; i < asioGetNumDev(); i++) + { + if(!asioGetDriverName(i, dname, 32) && !strcmp(name, dname)) + { + curName[0] = 0; + getCurrentDriverName(curName); // in case we fail... + removeCurrentDriver(); + + if(!asioOpenDriver(i, (void **)&theAsioDriver)) + { + curIndex = i; + return true; + } + else + { + theAsioDriver = 0; + if(curName[0] && strcmp(dname, curName)) + loadDriver(curName); // try restore + } + break; + } + } + return false; +} + +void AsioDrivers::removeCurrentDriver() +{ + if(curIndex != -1) + asioCloseDriver(curIndex); + curIndex = -1; +} + +#elif SGI || BEOS + +#include "asiolist.h" + +AsioDrivers::AsioDrivers() + : AsioDriverList() +{ + curIndex = -1; +} + +AsioDrivers::~AsioDrivers() +{ +} + +bool AsioDrivers::getCurrentDriverName(char *name) +{ + return false; +} + +long AsioDrivers::getDriverNames(char **names, long maxDrivers) +{ + return 0; +} + +bool AsioDrivers::loadDriver(char *name) +{ + return false; +} + +void AsioDrivers::removeCurrentDriver() +{ +} + +#else +#error implement me +#endif diff --git a/include/asiodrivers.h b/include/asiodrivers.h new file mode 100644 index 0000000..2ddf7ad --- /dev/null +++ b/include/asiodrivers.h @@ -0,0 +1,41 @@ +#ifndef __AsioDrivers__ +#define __AsioDrivers__ + +#include "ginclude.h" + +#if MAC +#include "CodeFragments.hpp" + +class AsioDrivers : public CodeFragments + +#elif WINDOWS +#include +#include "asiolist.h" + +class AsioDrivers : public AsioDriverList + +#elif SGI || BEOS +#include "asiolist.h" + +class AsioDrivers : public AsioDriverList + +#else +#error implement me +#endif + +{ +public: + AsioDrivers(); + ~AsioDrivers(); + + bool getCurrentDriverName(char *name); + long getDriverNames(char **names, long maxDrivers); + bool loadDriver(char *name); + void removeCurrentDriver(); + long getCurrentDriverIndex() {return curIndex;} +protected: + unsigned long connID; + long curIndex; +}; + +#endif diff --git a/include/asiodrvr.h b/include/asiodrvr.h new file mode 100644 index 0000000..663f75a --- /dev/null +++ b/include/asiodrvr.h @@ -0,0 +1,76 @@ +/* + Steinberg Audio Stream I/O API + (c) 1996, Steinberg Soft- und Hardware GmbH + charlie (May 1996) + + asiodrvr.h + c++ superclass to implement asio functionality. from this, + you can derive whatever required +*/ + +#ifndef _asiodrvr_ +#define _asiodrvr_ + +// cpu and os system we are running on +#include "asiosys.h" +// basic "C" interface +#include "asio.h" + +class AsioDriver; +extern AsioDriver *getDriver(); // for generic constructor + +#if WINDOWS +#include +#include "combase.h" +#include "iasiodrv.h" +class AsioDriver : public IASIO ,public CUnknown +{ +public: + AsioDriver(LPUNKNOWN pUnk, HRESULT *phr); + + DECLARE_IUNKNOWN + // Factory method + static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); + // IUnknown + virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject); + +#else + +class AsioDriver +{ +public: + AsioDriver(); +#endif + virtual ~AsioDriver(); + + virtual ASIOBool init(void* sysRef); + virtual void getDriverName(char *name); // max 32 bytes incl. terminating zero + virtual long getDriverVersion(); + virtual void getErrorMessage(char *string); // max 124 bytes incl. + + virtual ASIOError start(); + virtual ASIOError stop(); + + virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels); + virtual ASIOError getLatencies(long *inputLatency, long *outputLatency); + virtual ASIOError getBufferSize(long *minSize, long *maxSize, + long *preferredSize, long *granularity); + + virtual ASIOError canSampleRate(ASIOSampleRate sampleRate); + virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate); + virtual ASIOError setSampleRate(ASIOSampleRate sampleRate); + virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); + virtual ASIOError setClockSource(long reference); + + virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); + virtual ASIOError getChannelInfo(ASIOChannelInfo *info); + + virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, + long bufferSize, ASIOCallbacks *callbacks); + virtual ASIOError disposeBuffers(); + + virtual ASIOError controlPanel(); + virtual ASIOError future(long selector, void *opt); + virtual ASIOError outputReady(); +}; +#endif diff --git a/include/asiolist.cpp b/include/asiolist.cpp new file mode 100644 index 0000000..5a62f5b --- /dev/null +++ b/include/asiolist.cpp @@ -0,0 +1,268 @@ +#include +#include "iasiodrv.h" +#include "asiolist.h" + +#define ASIODRV_DESC "description" +#define INPROC_SERVER "InprocServer32" +#define ASIO_PATH "software\\asio" +#define COM_CLSID "clsid" + +// ****************************************************************** +// Local Functions +// ****************************************************************** +static LONG findDrvPath (char *clsidstr,char *dllpath,int dllpathsize) +{ + HKEY hkEnum,hksub,hkpath; + char databuf[512]; + LONG cr,rc = -1; + DWORD datatype,datasize; + DWORD index; + OFSTRUCT ofs; + HFILE hfile; + BOOL found = FALSE; + + CharLowerBuff(clsidstr,strlen(clsidstr)); + if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) { + + index = 0; + while (cr == ERROR_SUCCESS && !found) { + cr = RegEnumKey(hkEnum,index++,(LPTSTR)databuf,512); + if (cr == ERROR_SUCCESS) { + CharLowerBuff(databuf,strlen(databuf)); + if (!(strcmp(databuf,clsidstr))) { + if ((cr = RegOpenKeyEx(hkEnum,(LPCTSTR)databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) { + if ((cr = RegOpenKeyEx(hksub,(LPCTSTR)INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) { + datatype = REG_SZ; datasize = (DWORD)dllpathsize; + cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize); + if (cr == ERROR_SUCCESS) { + memset(&ofs,0,sizeof(OFSTRUCT)); + ofs.cBytes = sizeof(OFSTRUCT); + hfile = OpenFile(dllpath,&ofs,OF_EXIST); + if (hfile) rc = 0; + } + RegCloseKey(hkpath); + } + RegCloseKey(hksub); + } + found = TRUE; // break out + } + } + } + RegCloseKey(hkEnum); + } + return rc; +} + + +static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv) +{ + HKEY hksub; + char databuf[256]; + char dllpath[MAXPATHLEN]; + WORD wData[100]; + CLSID clsid; + DWORD datatype,datasize; + LONG cr,rc; + + if (!lpdrv) { + if ((cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) { + + datatype = REG_SZ; datasize = 256; + cr = RegQueryValueEx(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize); + if (cr == ERROR_SUCCESS) { + rc = findDrvPath (databuf,dllpath,MAXPATHLEN); + if (rc == 0) { + lpdrv = new ASIODRVSTRUCT[1]; + if (lpdrv) { + memset(lpdrv,0,sizeof(ASIODRVSTRUCT)); + lpdrv->drvID = drvID; + MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100); + if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) { + memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID)); + } + + datatype = REG_SZ; datasize = 256; + cr = RegQueryValueEx(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize); + if (cr == ERROR_SUCCESS) { + strcpy(lpdrv->drvname,databuf); + } + else strcpy(lpdrv->drvname,keyname); + } + } + } + RegCloseKey(hksub); + } + } + else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next); + + return lpdrv; +} + +static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv) +{ + IASIO *iasio; + + if (lpdrv != 0) { + deleteDrvStruct(lpdrv->next); + if (lpdrv->asiodrv) { + iasio = (IASIO *)lpdrv->asiodrv; + iasio->Release(); + } + delete lpdrv; + } +} + + +static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv) +{ + while (lpdrv) { + if (lpdrv->drvID == drvID) return lpdrv; + lpdrv = lpdrv->next; + } + return 0; +} +// ****************************************************************** + + +// ****************************************************************** +// AsioDriverList +// ****************************************************************** +AsioDriverList::AsioDriverList () +{ + HKEY hkEnum = 0; + char keyname[MAXDRVNAMELEN]; + LPASIODRVSTRUCT pdl; + LONG cr; + DWORD index = 0; + BOOL fin = FALSE; + + numdrv = 0; + lpdrvlist = 0; + + cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum); + while (cr == ERROR_SUCCESS) { + if ((cr = RegEnumKey(hkEnum,index++,(LPTSTR)keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) { + lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist); + } + else fin = TRUE; + } + if (hkEnum) RegCloseKey(hkEnum); + + pdl = lpdrvlist; + while (pdl) { + numdrv++; + pdl = pdl->next; + } + + if (numdrv) CoInitialize(0); // initialize COM +} + +AsioDriverList::~AsioDriverList () +{ + if (numdrv) { + deleteDrvStruct(lpdrvlist); + CoUninitialize(); + } +} + + +LONG AsioDriverList::asioGetNumDev (VOID) +{ + return (LONG)numdrv; +} + + +LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv) +{ + LPASIODRVSTRUCT lpdrv = 0; + long rc; + + if (!asiodrv) return DRVERR_INVALID_PARAM; + + if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { + if (!lpdrv->asiodrv) { + rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv); + if (rc == S_OK) { + lpdrv->asiodrv = *asiodrv; + return 0; + } + // else if (rc == REGDB_E_CLASSNOTREG) + // strcpy (info->messageText, "Driver not registered in the Registration Database!"); + } + else rc = DRVERR_DEVICE_ALREADY_OPEN; + } + else rc = DRVERR_DEVICE_NOT_FOUND; + + return rc; +} + + +LONG AsioDriverList::asioCloseDriver (int drvID) +{ + LPASIODRVSTRUCT lpdrv = 0; + IASIO *iasio; + + if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { + if (lpdrv->asiodrv) { + iasio = (IASIO *)lpdrv->asiodrv; + iasio->Release(); + lpdrv->asiodrv = 0; + } + } + + return 0; +} + +LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize) +{ + LPASIODRVSTRUCT lpdrv = 0; + + if (!drvname) return DRVERR_INVALID_PARAM; + + if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { + if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) { + strcpy(drvname,lpdrv->drvname); + } + else { + memcpy(drvname,lpdrv->drvname,drvnamesize-4); + drvname[drvnamesize-4] = '.'; + drvname[drvnamesize-3] = '.'; + drvname[drvnamesize-2] = '.'; + drvname[drvnamesize-1] = 0; + } + return 0; + } + return DRVERR_DEVICE_NOT_FOUND; +} + +LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize) +{ + LPASIODRVSTRUCT lpdrv = 0; + + if (!dllpath) return DRVERR_INVALID_PARAM; + + if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { + if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) { + strcpy(dllpath,lpdrv->dllpath); + return 0; + } + dllpath[0] = 0; + return DRVERR_INVALID_PARAM; + } + return DRVERR_DEVICE_NOT_FOUND; +} + +LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid) +{ + LPASIODRVSTRUCT lpdrv = 0; + + if (!clsid) return DRVERR_INVALID_PARAM; + + if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { + memcpy(clsid,&lpdrv->clsid,sizeof(CLSID)); + return 0; + } + return DRVERR_DEVICE_NOT_FOUND; +} + + diff --git a/include/asiolist.h b/include/asiolist.h new file mode 100644 index 0000000..01c64f0 --- /dev/null +++ b/include/asiolist.h @@ -0,0 +1,46 @@ +#ifndef __asiolist__ +#define __asiolist__ + +#define DRVERR -5000 +#define DRVERR_INVALID_PARAM DRVERR-1 +#define DRVERR_DEVICE_ALREADY_OPEN DRVERR-2 +#define DRVERR_DEVICE_NOT_FOUND DRVERR-3 + +#define MAXPATHLEN 512 +#define MAXDRVNAMELEN 128 + +struct asiodrvstruct +{ + int drvID; + CLSID clsid; + char dllpath[MAXPATHLEN]; + char drvname[MAXDRVNAMELEN]; + LPVOID asiodrv; + struct asiodrvstruct *next; +}; + +typedef struct asiodrvstruct ASIODRVSTRUCT; +typedef ASIODRVSTRUCT *LPASIODRVSTRUCT; + +class AsioDriverList { +public: + AsioDriverList(); + ~AsioDriverList(); + + LONG asioOpenDriver (int,VOID **); + LONG asioCloseDriver (int); + + // nice to have + LONG asioGetNumDev (VOID); + LONG asioGetDriverName (int,char *,int); + LONG asioGetDriverPath (int,char *,int); + LONG asioGetDriverCLSID (int,CLSID *); + + // or use directly access + LPASIODRVSTRUCT lpdrvlist; + int numdrv; +}; + +typedef class AsioDriverList *LPASIODRIVERLIST; + +#endif diff --git a/include/asiosys.h b/include/asiosys.h new file mode 100644 index 0000000..37f7a48 --- /dev/null +++ b/include/asiosys.h @@ -0,0 +1,82 @@ +#ifndef __asiosys__ + #define __asiosys__ + + #ifdef WIN32 + #undef MAC + #define PPC 0 + #define WINDOWS 1 + #define SGI 0 + #define SUN 0 + #define LINUX 0 + #define BEOS 0 + + #define NATIVE_INT64 0 + #define IEEE754_64FLOAT 1 + + #elif BEOS + #define MAC 0 + #define PPC 0 + #define WINDOWS 0 + #define PC 0 + #define SGI 0 + #define SUN 0 + #define LINUX 0 + + #define NATIVE_INT64 0 + #define IEEE754_64FLOAT 1 + + #ifndef DEBUG + #define DEBUG 0 + #if DEBUG + void DEBUGGERMESSAGE(char *string); + #else + #define DEBUGGERMESSAGE(a) + #endif + #endif + + #elif SGI + #define MAC 0 + #define PPC 0 + #define WINDOWS 0 + #define PC 0 + #define SUN 0 + #define LINUX 0 + #define BEOS 0 + + #define NATIVE_INT64 0 + #define IEEE754_64FLOAT 1 + + #ifndef DEBUG + #define DEBUG 0 + #if DEBUG + void DEBUGGERMESSAGE(char *string); + #else + #define DEBUGGERMESSAGE(a) + #endif + #endif + + #else // MAC + + #define MAC 1 + #define PPC 1 + #define WINDOWS 0 + #define PC 0 + #define SGI 0 + #define SUN 0 + #define LINUX 0 + #define BEOS 0 + + #define NATIVE_INT64 0 + #define IEEE754_64FLOAT 1 + + #ifndef DEBUG + #define DEBUG 0 + #if DEBUG + void DEBUGGERMESSAGE(char *string); + #else + #define DEBUGGERMESSAGE(a) + #endif + #endif + #endif + +#endif diff --git a/include/dsound.h b/include/dsound.h new file mode 100644 index 0000000..cb19cca --- /dev/null +++ b/include/dsound.h @@ -0,0 +1,2369 @@ +/*==========================================================================; + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * File: dsound.h + * Content: DirectSound include file + * + **************************************************************************/ + +#define COM_NO_WINDOWS_H +#include +#include + +#ifndef DIRECTSOUND_VERSION +#define DIRECTSOUND_VERSION 0x0900 /* Version 9.0 */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#ifndef __DSOUND_INCLUDED__ +#define __DSOUND_INCLUDED__ + +/* Type definitions shared with Direct3D */ + +#ifndef DX_SHARED_DEFINES + +typedef float D3DVALUE, *LPD3DVALUE; + +#ifndef D3DCOLOR_DEFINED +typedef DWORD D3DCOLOR; +#define D3DCOLOR_DEFINED +#endif + +#ifndef LPD3DCOLOR_DEFINED +typedef DWORD *LPD3DCOLOR; +#define LPD3DCOLOR_DEFINED +#endif + +#ifndef D3DVECTOR_DEFINED +typedef struct _D3DVECTOR { + float x; + float y; + float z; +} D3DVECTOR; +#define D3DVECTOR_DEFINED +#endif + +#ifndef LPD3DVECTOR_DEFINED +typedef D3DVECTOR *LPD3DVECTOR; +#define LPD3DVECTOR_DEFINED +#endif + +#define DX_SHARED_DEFINES +#endif // DX_SHARED_DEFINES + +#define _FACDS 0x878 /* DirectSound's facility code */ +#define MAKE_DSHRESULT(code) MAKE_HRESULT(1, _FACDS, code) + +// DirectSound Component GUID {47D4D946-62E8-11CF-93BC-444553540000} +DEFINE_GUID(CLSID_DirectSound, 0x47d4d946, 0x62e8, 0x11cf, 0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0); + +// DirectSound 8.0 Component GUID {3901CC3F-84B5-4FA4-BA35-AA8172B8A09B} +DEFINE_GUID(CLSID_DirectSound8, 0x3901cc3f, 0x84b5, 0x4fa4, 0xba, 0x35, 0xaa, 0x81, 0x72, 0xb8, 0xa0, 0x9b); + +// DirectSound Capture Component GUID {B0210780-89CD-11D0-AF08-00A0C925CD16} +DEFINE_GUID(CLSID_DirectSoundCapture, 0xb0210780, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +// DirectSound 8.0 Capture Component GUID {E4BCAC13-7F99-4908-9A8E-74E3BF24B6E1} +DEFINE_GUID(CLSID_DirectSoundCapture8, 0xe4bcac13, 0x7f99, 0x4908, 0x9a, 0x8e, 0x74, 0xe3, 0xbf, 0x24, 0xb6, 0xe1); + +// DirectSound Full Duplex Component GUID {FEA4300C-7959-4147-B26A-2377B9E7A91D} +DEFINE_GUID(CLSID_DirectSoundFullDuplex, 0xfea4300c, 0x7959, 0x4147, 0xb2, 0x6a, 0x23, 0x77, 0xb9, 0xe7, 0xa9, 0x1d); + + +// DirectSound default playback device GUID {DEF00000-9C6D-47ED-AAF1-4DDA8F2B5C03} +DEFINE_GUID(DSDEVID_DefaultPlayback, 0xdef00000, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03); + +// DirectSound default capture device GUID {DEF00001-9C6D-47ED-AAF1-4DDA8F2B5C03} +DEFINE_GUID(DSDEVID_DefaultCapture, 0xdef00001, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03); + +// DirectSound default device for voice playback {DEF00002-9C6D-47ED-AAF1-4DDA8F2B5C03} +DEFINE_GUID(DSDEVID_DefaultVoicePlayback, 0xdef00002, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03); + +// DirectSound default device for voice capture {DEF00003-9C6D-47ED-AAF1-4DDA8F2B5C03} +DEFINE_GUID(DSDEVID_DefaultVoiceCapture, 0xdef00003, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03); + + +// +// Forward declarations for interfaces. +// 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined +// + +#ifdef __cplusplus +struct IDirectSound; +struct IDirectSoundBuffer; +struct IDirectSound3DListener; +struct IDirectSound3DBuffer; +struct IDirectSoundCapture; +struct IDirectSoundCaptureBuffer; +struct IDirectSoundNotify; +#endif // __cplusplus + + +// +// DirectSound 8.0 interfaces. +// + +#if DIRECTSOUND_VERSION >= 0x0800 + +#ifdef __cplusplus +struct IDirectSound8; +struct IDirectSoundBuffer8; +struct IDirectSoundCaptureBuffer8; +struct IDirectSoundFXGargle; +struct IDirectSoundFXChorus; +struct IDirectSoundFXFlanger; +struct IDirectSoundFXEcho; +struct IDirectSoundFXDistortion; +struct IDirectSoundFXCompressor; +struct IDirectSoundFXParamEq; +struct IDirectSoundFXWavesReverb; +struct IDirectSoundFXI3DL2Reverb; +struct IDirectSoundCaptureFXAec; +struct IDirectSoundCaptureFXNoiseSuppress; +struct IDirectSoundFullDuplex; +#endif // __cplusplus + +// IDirectSound8, IDirectSoundBuffer8 and IDirectSoundCaptureBuffer8 are the +// only DirectSound 7.0 interfaces with changed functionality in version 8.0. +// The other level 8 interfaces as equivalent to their level 7 counterparts: + +#define IDirectSoundCapture8 IDirectSoundCapture +#define IDirectSound3DListener8 IDirectSound3DListener +#define IDirectSound3DBuffer8 IDirectSound3DBuffer +#define IDirectSoundNotify8 IDirectSoundNotify +#define IDirectSoundFXGargle8 IDirectSoundFXGargle +#define IDirectSoundFXChorus8 IDirectSoundFXChorus +#define IDirectSoundFXFlanger8 IDirectSoundFXFlanger +#define IDirectSoundFXEcho8 IDirectSoundFXEcho +#define IDirectSoundFXDistortion8 IDirectSoundFXDistortion +#define IDirectSoundFXCompressor8 IDirectSoundFXCompressor +#define IDirectSoundFXParamEq8 IDirectSoundFXParamEq +#define IDirectSoundFXWavesReverb8 IDirectSoundFXWavesReverb +#define IDirectSoundFXI3DL2Reverb8 IDirectSoundFXI3DL2Reverb +#define IDirectSoundCaptureFXAec8 IDirectSoundCaptureFXAec +#define IDirectSoundCaptureFXNoiseSuppress8 IDirectSoundCaptureFXNoiseSuppress +#define IDirectSoundFullDuplex8 IDirectSoundFullDuplex + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +typedef struct IDirectSound *LPDIRECTSOUND; +typedef struct IDirectSoundBuffer *LPDIRECTSOUNDBUFFER; +typedef struct IDirectSound3DListener *LPDIRECTSOUND3DLISTENER; +typedef struct IDirectSound3DBuffer *LPDIRECTSOUND3DBUFFER; +typedef struct IDirectSoundCapture *LPDIRECTSOUNDCAPTURE; +typedef struct IDirectSoundCaptureBuffer *LPDIRECTSOUNDCAPTUREBUFFER; +typedef struct IDirectSoundNotify *LPDIRECTSOUNDNOTIFY; + + +#if DIRECTSOUND_VERSION >= 0x0800 + +typedef struct IDirectSoundFXGargle *LPDIRECTSOUNDFXGARGLE; +typedef struct IDirectSoundFXChorus *LPDIRECTSOUNDFXCHORUS; +typedef struct IDirectSoundFXFlanger *LPDIRECTSOUNDFXFLANGER; +typedef struct IDirectSoundFXEcho *LPDIRECTSOUNDFXECHO; +typedef struct IDirectSoundFXDistortion *LPDIRECTSOUNDFXDISTORTION; +typedef struct IDirectSoundFXCompressor *LPDIRECTSOUNDFXCOMPRESSOR; +typedef struct IDirectSoundFXParamEq *LPDIRECTSOUNDFXPARAMEQ; +typedef struct IDirectSoundFXWavesReverb *LPDIRECTSOUNDFXWAVESREVERB; +typedef struct IDirectSoundFXI3DL2Reverb *LPDIRECTSOUNDFXI3DL2REVERB; +typedef struct IDirectSoundCaptureFXAec *LPDIRECTSOUNDCAPTUREFXAEC; +typedef struct IDirectSoundCaptureFXNoiseSuppress *LPDIRECTSOUNDCAPTUREFXNOISESUPPRESS; +typedef struct IDirectSoundFullDuplex *LPDIRECTSOUNDFULLDUPLEX; + +typedef struct IDirectSound8 *LPDIRECTSOUND8; +typedef struct IDirectSoundBuffer8 *LPDIRECTSOUNDBUFFER8; +typedef struct IDirectSound3DListener8 *LPDIRECTSOUND3DLISTENER8; +typedef struct IDirectSound3DBuffer8 *LPDIRECTSOUND3DBUFFER8; +typedef struct IDirectSoundCapture8 *LPDIRECTSOUNDCAPTURE8; +typedef struct IDirectSoundCaptureBuffer8 *LPDIRECTSOUNDCAPTUREBUFFER8; +typedef struct IDirectSoundNotify8 *LPDIRECTSOUNDNOTIFY8; +typedef struct IDirectSoundFXGargle8 *LPDIRECTSOUNDFXGARGLE8; +typedef struct IDirectSoundFXChorus8 *LPDIRECTSOUNDFXCHORUS8; +typedef struct IDirectSoundFXFlanger8 *LPDIRECTSOUNDFXFLANGER8; +typedef struct IDirectSoundFXEcho8 *LPDIRECTSOUNDFXECHO8; +typedef struct IDirectSoundFXDistortion8 *LPDIRECTSOUNDFXDISTORTION8; +typedef struct IDirectSoundFXCompressor8 *LPDIRECTSOUNDFXCOMPRESSOR8; +typedef struct IDirectSoundFXParamEq8 *LPDIRECTSOUNDFXPARAMEQ8; +typedef struct IDirectSoundFXWavesReverb8 *LPDIRECTSOUNDFXWAVESREVERB8; +typedef struct IDirectSoundFXI3DL2Reverb8 *LPDIRECTSOUNDFXI3DL2REVERB8; +typedef struct IDirectSoundCaptureFXAec8 *LPDIRECTSOUNDCAPTUREFXAEC8; +typedef struct IDirectSoundCaptureFXNoiseSuppress8 *LPDIRECTSOUNDCAPTUREFXNOISESUPPRESS8; +typedef struct IDirectSoundFullDuplex8 *LPDIRECTSOUNDFULLDUPLEX8; + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// IID definitions for the unchanged DirectSound 8.0 interfaces +// + +#if DIRECTSOUND_VERSION >= 0x0800 + +#define IID_IDirectSoundCapture8 IID_IDirectSoundCapture +#define IID_IDirectSound3DListener8 IID_IDirectSound3DListener +#define IID_IDirectSound3DBuffer8 IID_IDirectSound3DBuffer +#define IID_IDirectSoundNotify8 IID_IDirectSoundNotify +#define IID_IDirectSoundFXGargle8 IID_IDirectSoundFXGargle +#define IID_IDirectSoundFXChorus8 IID_IDirectSoundFXChorus +#define IID_IDirectSoundFXFlanger8 IID_IDirectSoundFXFlanger +#define IID_IDirectSoundFXEcho8 IID_IDirectSoundFXEcho +#define IID_IDirectSoundFXDistortion8 IID_IDirectSoundFXDistortion +#define IID_IDirectSoundFXCompressor8 IID_IDirectSoundFXCompressor +#define IID_IDirectSoundFXParamEq8 IID_IDirectSoundFXParamEq +#define IID_IDirectSoundFXWavesReverb8 IID_IDirectSoundFXWavesReverb +#define IID_IDirectSoundFXI3DL2Reverb8 IID_IDirectSoundFXI3DL2Reverb +#define IID_IDirectSoundCaptureFXAec8 IID_IDirectSoundCaptureFXAec +#define IID_IDirectSoundCaptureFXNoiseSuppress8 IID_IDirectSoundCaptureFXNoiseSuppress +#define IID_IDirectSoundFullDuplex8 IID_IDirectSoundFullDuplex + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// Compatibility typedefs +// + +#ifndef _LPCWAVEFORMATEX_DEFINED +#define _LPCWAVEFORMATEX_DEFINED +typedef const WAVEFORMATEX *LPCWAVEFORMATEX; +#endif // _LPCWAVEFORMATEX_DEFINED + +#ifndef __LPCGUID_DEFINED__ +#define __LPCGUID_DEFINED__ +typedef const GUID *LPCGUID; +#endif // __LPCGUID_DEFINED__ + +typedef LPDIRECTSOUND *LPLPDIRECTSOUND; +typedef LPDIRECTSOUNDBUFFER *LPLPDIRECTSOUNDBUFFER; +typedef LPDIRECTSOUND3DLISTENER *LPLPDIRECTSOUND3DLISTENER; +typedef LPDIRECTSOUND3DBUFFER *LPLPDIRECTSOUND3DBUFFER; +typedef LPDIRECTSOUNDCAPTURE *LPLPDIRECTSOUNDCAPTURE; +typedef LPDIRECTSOUNDCAPTUREBUFFER *LPLPDIRECTSOUNDCAPTUREBUFFER; +typedef LPDIRECTSOUNDNOTIFY *LPLPDIRECTSOUNDNOTIFY; + +#if DIRECTSOUND_VERSION >= 0x0800 +typedef LPDIRECTSOUND8 *LPLPDIRECTSOUND8; +typedef LPDIRECTSOUNDBUFFER8 *LPLPDIRECTSOUNDBUFFER8; +typedef LPDIRECTSOUNDCAPTURE8 *LPLPDIRECTSOUNDCAPTURE8; +typedef LPDIRECTSOUNDCAPTUREBUFFER8 *LPLPDIRECTSOUNDCAPTUREBUFFER8; +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// Structures +// + +typedef struct _DSCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwMinSecondarySampleRate; + DWORD dwMaxSecondarySampleRate; + DWORD dwPrimaryBuffers; + DWORD dwMaxHwMixingAllBuffers; + DWORD dwMaxHwMixingStaticBuffers; + DWORD dwMaxHwMixingStreamingBuffers; + DWORD dwFreeHwMixingAllBuffers; + DWORD dwFreeHwMixingStaticBuffers; + DWORD dwFreeHwMixingStreamingBuffers; + DWORD dwMaxHw3DAllBuffers; + DWORD dwMaxHw3DStaticBuffers; + DWORD dwMaxHw3DStreamingBuffers; + DWORD dwFreeHw3DAllBuffers; + DWORD dwFreeHw3DStaticBuffers; + DWORD dwFreeHw3DStreamingBuffers; + DWORD dwTotalHwMemBytes; + DWORD dwFreeHwMemBytes; + DWORD dwMaxContigFreeHwMemBytes; + DWORD dwUnlockTransferRateHwBuffers; + DWORD dwPlayCpuOverheadSwBuffers; + DWORD dwReserved1; + DWORD dwReserved2; +} DSCAPS, *LPDSCAPS; + +typedef const DSCAPS *LPCDSCAPS; + +typedef struct _DSBCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwUnlockTransferRate; + DWORD dwPlayCpuOverhead; +} DSBCAPS, *LPDSBCAPS; + +typedef const DSBCAPS *LPCDSBCAPS; + +#if DIRECTSOUND_VERSION >= 0x0800 + + typedef struct _DSEFFECTDESC + { + DWORD dwSize; + DWORD dwFlags; + GUID guidDSFXClass; + DWORD_PTR dwReserved1; + DWORD_PTR dwReserved2; + } DSEFFECTDESC, *LPDSEFFECTDESC; + typedef const DSEFFECTDESC *LPCDSEFFECTDESC; + + #define DSFX_LOCHARDWARE 0x00000001 + #define DSFX_LOCSOFTWARE 0x00000002 + + enum + { + DSFXR_PRESENT, // 0 + DSFXR_LOCHARDWARE, // 1 + DSFXR_LOCSOFTWARE, // 2 + DSFXR_UNALLOCATED, // 3 + DSFXR_FAILED, // 4 + DSFXR_UNKNOWN, // 5 + DSFXR_SENDLOOP // 6 + }; + + typedef struct _DSCEFFECTDESC + { + DWORD dwSize; + DWORD dwFlags; + GUID guidDSCFXClass; + GUID guidDSCFXInstance; + DWORD dwReserved1; + DWORD dwReserved2; + } DSCEFFECTDESC, *LPDSCEFFECTDESC; + typedef const DSCEFFECTDESC *LPCDSCEFFECTDESC; + + #define DSCFX_LOCHARDWARE 0x00000001 + #define DSCFX_LOCSOFTWARE 0x00000002 + + #define DSCFXR_LOCHARDWARE 0x00000010 + #define DSCFXR_LOCSOFTWARE 0x00000020 + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +typedef struct _DSBUFFERDESC +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +#if DIRECTSOUND_VERSION >= 0x0700 + GUID guid3DAlgorithm; +#endif +} DSBUFFERDESC, *LPDSBUFFERDESC; + +typedef const DSBUFFERDESC *LPCDSBUFFERDESC; + +// Older version of this structure: + +typedef struct _DSBUFFERDESC1 +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +} DSBUFFERDESC1, *LPDSBUFFERDESC1; + +typedef const DSBUFFERDESC1 *LPCDSBUFFERDESC1; + +typedef struct _DS3DBUFFER +{ + DWORD dwSize; + D3DVECTOR vPosition; + D3DVECTOR vVelocity; + DWORD dwInsideConeAngle; + DWORD dwOutsideConeAngle; + D3DVECTOR vConeOrientation; + LONG lConeOutsideVolume; + D3DVALUE flMinDistance; + D3DVALUE flMaxDistance; + DWORD dwMode; +} DS3DBUFFER, *LPDS3DBUFFER; + +typedef const DS3DBUFFER *LPCDS3DBUFFER; + +typedef struct _DS3DLISTENER +{ + DWORD dwSize; + D3DVECTOR vPosition; + D3DVECTOR vVelocity; + D3DVECTOR vOrientFront; + D3DVECTOR vOrientTop; + D3DVALUE flDistanceFactor; + D3DVALUE flRolloffFactor; + D3DVALUE flDopplerFactor; +} DS3DLISTENER, *LPDS3DLISTENER; + +typedef const DS3DLISTENER *LPCDS3DLISTENER; + +typedef struct _DSCCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwFormats; + DWORD dwChannels; +} DSCCAPS, *LPDSCCAPS; + +typedef const DSCCAPS *LPCDSCCAPS; + +typedef struct _DSCBUFFERDESC1 +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +} DSCBUFFERDESC1, *LPDSCBUFFERDESC1; + +typedef struct _DSCBUFFERDESC +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +#if DIRECTSOUND_VERSION >= 0x0800 + DWORD dwFXCount; + LPDSCEFFECTDESC lpDSCFXDesc; +#endif +} DSCBUFFERDESC, *LPDSCBUFFERDESC; + +typedef const DSCBUFFERDESC *LPCDSCBUFFERDESC; + +typedef struct _DSCBCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; +} DSCBCAPS, *LPDSCBCAPS; + +typedef const DSCBCAPS *LPCDSCBCAPS; + +typedef struct _DSBPOSITIONNOTIFY +{ + DWORD dwOffset; + HANDLE hEventNotify; +} DSBPOSITIONNOTIFY, *LPDSBPOSITIONNOTIFY; + +typedef const DSBPOSITIONNOTIFY *LPCDSBPOSITIONNOTIFY; + +// +// DirectSound API +// + +typedef BOOL (CALLBACK *LPDSENUMCALLBACKA)(LPGUID, LPCSTR, LPCSTR, LPVOID); +typedef BOOL (CALLBACK *LPDSENUMCALLBACKW)(LPGUID, LPCWSTR, LPCWSTR, LPVOID); + +extern HRESULT WINAPI DirectSoundCreate(LPCGUID pcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter); +extern HRESULT WINAPI DirectSoundEnumerateA(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext); +extern HRESULT WINAPI DirectSoundEnumerateW(LPDSENUMCALLBACKW pDSEnumCallback, LPVOID pContext); + +extern HRESULT WINAPI DirectSoundCaptureCreate(LPCGUID pcGuidDevice, LPDIRECTSOUNDCAPTURE *ppDSC, LPUNKNOWN pUnkOuter); +extern HRESULT WINAPI DirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext); +extern HRESULT WINAPI DirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW pDSEnumCallback, LPVOID pContext); + +#if DIRECTSOUND_VERSION >= 0x0800 +extern HRESULT WINAPI DirectSoundCreate8(LPCGUID pcGuidDevice, LPDIRECTSOUND8 *ppDS8, LPUNKNOWN pUnkOuter); +extern HRESULT WINAPI DirectSoundCaptureCreate8(LPCGUID pcGuidDevice, LPDIRECTSOUNDCAPTURE8 *ppDSC8, LPUNKNOWN pUnkOuter); +extern HRESULT WINAPI DirectSoundFullDuplexCreate(LPCGUID pcGuidCaptureDevice, LPCGUID pcGuidRenderDevice, + LPCDSCBUFFERDESC pcDSCBufferDesc, LPCDSBUFFERDESC pcDSBufferDesc, HWND hWnd, + DWORD dwLevel, LPDIRECTSOUNDFULLDUPLEX* ppDSFD, LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8, + LPDIRECTSOUNDBUFFER8 *ppDSBuffer8, LPUNKNOWN pUnkOuter); +#define DirectSoundFullDuplexCreate8 DirectSoundFullDuplexCreate + +extern HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest); +#endif // DIRECTSOUND_VERSION >= 0x0800 + +#ifdef UNICODE +#define LPDSENUMCALLBACK LPDSENUMCALLBACKW +#define DirectSoundEnumerate DirectSoundEnumerateW +#define DirectSoundCaptureEnumerate DirectSoundCaptureEnumerateW +#else // UNICODE +#define LPDSENUMCALLBACK LPDSENUMCALLBACKA +#define DirectSoundEnumerate DirectSoundEnumerateA +#define DirectSoundCaptureEnumerate DirectSoundCaptureEnumerateA +#endif // UNICODE + +// +// IUnknown +// + +#if !defined(__cplusplus) || defined(CINTERFACE) +#ifndef IUnknown_QueryInterface +#define IUnknown_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#endif // IUnknown_QueryInterface +#ifndef IUnknown_AddRef +#define IUnknown_AddRef(p) (p)->lpVtbl->AddRef(p) +#endif // IUnknown_AddRef +#ifndef IUnknown_Release +#define IUnknown_Release(p) (p)->lpVtbl->Release(p) +#endif // IUnknown_Release +#else // !defined(__cplusplus) || defined(CINTERFACE) +#ifndef IUnknown_QueryInterface +#define IUnknown_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#endif // IUnknown_QueryInterface +#ifndef IUnknown_AddRef +#define IUnknown_AddRef(p) (p)->AddRef() +#endif // IUnknown_AddRef +#ifndef IUnknown_Release +#define IUnknown_Release(p) (p)->Release() +#endif // IUnknown_Release +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#ifndef __IReferenceClock_INTERFACE_DEFINED__ +#define __IReferenceClock_INTERFACE_DEFINED__ + +typedef LONGLONG REFERENCE_TIME; +typedef REFERENCE_TIME *LPREFERENCE_TIME; + +DEFINE_GUID(IID_IReferenceClock, 0x56a86897, 0x0ad4, 0x11ce, 0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); + +#undef INTERFACE +#define INTERFACE IReferenceClock + +DECLARE_INTERFACE_(IReferenceClock, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IReferenceClock methods + STDMETHOD(GetTime) (THIS_ REFERENCE_TIME *pTime) PURE; + STDMETHOD(AdviseTime) (THIS_ REFERENCE_TIME rtBaseTime, REFERENCE_TIME rtStreamTime, + HANDLE hEvent, LPDWORD pdwAdviseCookie) PURE; + STDMETHOD(AdvisePeriodic) (THIS_ REFERENCE_TIME rtStartTime, REFERENCE_TIME rtPeriodTime, + HANDLE hSemaphore, LPDWORD pdwAdviseCookie) PURE; + STDMETHOD(Unadvise) (THIS_ DWORD dwAdviseCookie) PURE; +}; + +#endif // __IReferenceClock_INTERFACE_DEFINED__ + +#ifndef IReferenceClock_QueryInterface + +#define IReferenceClock_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IReferenceClock_AddRef(p) IUnknown_AddRef(p) +#define IReferenceClock_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IReferenceClock_GetTime(p,a) (p)->lpVtbl->GetTime(p,a) +#define IReferenceClock_AdviseTime(p,a,b,c,d) (p)->lpVtbl->AdviseTime(p,a,b,c,d) +#define IReferenceClock_AdvisePeriodic(p,a,b,c,d) (p)->lpVtbl->AdvisePeriodic(p,a,b,c,d) +#define IReferenceClock_Unadvise(p,a) (p)->lpVtbl->Unadvise(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IReferenceClock_GetTime(p,a) (p)->GetTime(a) +#define IReferenceClock_AdviseTime(p,a,b,c,d) (p)->AdviseTime(a,b,c,d) +#define IReferenceClock_AdvisePeriodic(p,a,b,c,d) (p)->AdvisePeriodic(a,b,c,d) +#define IReferenceClock_Unadvise(p,a) (p)->Unadvise(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // IReferenceClock_QueryInterface + +// +// IDirectSound +// + +DEFINE_GUID(IID_IDirectSound, 0x279AFA83, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSound + +DECLARE_INTERFACE_(IDirectSound, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSound methods + STDMETHOD(CreateSoundBuffer) (THIS_ LPCDSBUFFERDESC pcDSBufferDesc, LPDIRECTSOUNDBUFFER *ppDSBuffer, LPUNKNOWN pUnkOuter) PURE; + STDMETHOD(GetCaps) (THIS_ LPDSCAPS pDSCaps) PURE; + STDMETHOD(DuplicateSoundBuffer) (THIS_ LPDIRECTSOUNDBUFFER pDSBufferOriginal, LPDIRECTSOUNDBUFFER *ppDSBufferDuplicate) PURE; + STDMETHOD(SetCooperativeLevel) (THIS_ HWND hwnd, DWORD dwLevel) PURE; + STDMETHOD(Compact) (THIS) PURE; + STDMETHOD(GetSpeakerConfig) (THIS_ LPDWORD pdwSpeakerConfig) PURE; + STDMETHOD(SetSpeakerConfig) (THIS_ DWORD dwSpeakerConfig) PURE; + STDMETHOD(Initialize) (THIS_ LPCGUID pcGuidDevice) PURE; +}; + +#define IDirectSound_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSound_AddRef(p) IUnknown_AddRef(p) +#define IDirectSound_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound_CreateSoundBuffer(p,a,b,c) (p)->lpVtbl->CreateSoundBuffer(p,a,b,c) +#define IDirectSound_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSound_DuplicateSoundBuffer(p,a,b) (p)->lpVtbl->DuplicateSoundBuffer(p,a,b) +#define IDirectSound_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) +#define IDirectSound_Compact(p) (p)->lpVtbl->Compact(p) +#define IDirectSound_GetSpeakerConfig(p,a) (p)->lpVtbl->GetSpeakerConfig(p,a) +#define IDirectSound_SetSpeakerConfig(p,b) (p)->lpVtbl->SetSpeakerConfig(p,b) +#define IDirectSound_Initialize(p,a) (p)->lpVtbl->Initialize(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound_CreateSoundBuffer(p,a,b,c) (p)->CreateSoundBuffer(a,b,c) +#define IDirectSound_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSound_DuplicateSoundBuffer(p,a,b) (p)->DuplicateSoundBuffer(a,b) +#define IDirectSound_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) +#define IDirectSound_Compact(p) (p)->Compact() +#define IDirectSound_GetSpeakerConfig(p,a) (p)->GetSpeakerConfig(a) +#define IDirectSound_SetSpeakerConfig(p,b) (p)->SetSpeakerConfig(b) +#define IDirectSound_Initialize(p,a) (p)->Initialize(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#if DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSound8 +// + +DEFINE_GUID(IID_IDirectSound8, 0xC50A7E93, 0xF395, 0x4834, 0x9E, 0xF6, 0x7F, 0xA9, 0x9D, 0xE5, 0x09, 0x66); + +#undef INTERFACE +#define INTERFACE IDirectSound8 + +DECLARE_INTERFACE_(IDirectSound8, IDirectSound) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSound methods + STDMETHOD(CreateSoundBuffer) (THIS_ LPCDSBUFFERDESC pcDSBufferDesc, LPDIRECTSOUNDBUFFER *ppDSBuffer, LPUNKNOWN pUnkOuter) PURE; + STDMETHOD(GetCaps) (THIS_ LPDSCAPS pDSCaps) PURE; + STDMETHOD(DuplicateSoundBuffer) (THIS_ LPDIRECTSOUNDBUFFER pDSBufferOriginal, LPDIRECTSOUNDBUFFER *ppDSBufferDuplicate) PURE; + STDMETHOD(SetCooperativeLevel) (THIS_ HWND hwnd, DWORD dwLevel) PURE; + STDMETHOD(Compact) (THIS) PURE; + STDMETHOD(GetSpeakerConfig) (THIS_ LPDWORD pdwSpeakerConfig) PURE; + STDMETHOD(SetSpeakerConfig) (THIS_ DWORD dwSpeakerConfig) PURE; + STDMETHOD(Initialize) (THIS_ LPCGUID pcGuidDevice) PURE; + + // IDirectSound8 methods + STDMETHOD(VerifyCertification) (THIS_ LPDWORD pdwCertified) PURE; +}; + +#define IDirectSound8_QueryInterface(p,a,b) IDirectSound_QueryInterface(p,a,b) +#define IDirectSound8_AddRef(p) IDirectSound_AddRef(p) +#define IDirectSound8_Release(p) IDirectSound_Release(p) +#define IDirectSound8_CreateSoundBuffer(p,a,b,c) IDirectSound_CreateSoundBuffer(p,a,b,c) +#define IDirectSound8_GetCaps(p,a) IDirectSound_GetCaps(p,a) +#define IDirectSound8_DuplicateSoundBuffer(p,a,b) IDirectSound_DuplicateSoundBuffer(p,a,b) +#define IDirectSound8_SetCooperativeLevel(p,a,b) IDirectSound_SetCooperativeLevel(p,a,b) +#define IDirectSound8_Compact(p) IDirectSound_Compact(p) +#define IDirectSound8_GetSpeakerConfig(p,a) IDirectSound_GetSpeakerConfig(p,a) +#define IDirectSound8_SetSpeakerConfig(p,a) IDirectSound_SetSpeakerConfig(p,a) +#define IDirectSound8_Initialize(p,a) IDirectSound_Initialize(p,a) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound8_VerifyCertification(p,a) (p)->lpVtbl->VerifyCertification(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound8_VerifyCertification(p,a) (p)->VerifyCertification(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSoundBuffer +// + +DEFINE_GUID(IID_IDirectSoundBuffer, 0x279AFA85, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSoundBuffer + +DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundBuffer methods + STDMETHOD(GetCaps) (THIS_ LPDSBCAPS pDSBufferCaps) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD pdwCurrentPlayCursor, LPDWORD pdwCurrentWriteCursor) PURE; + STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX pwfxFormat, DWORD dwSizeAllocated, LPDWORD pdwSizeWritten) PURE; + STDMETHOD(GetVolume) (THIS_ LPLONG plVolume) PURE; + STDMETHOD(GetPan) (THIS_ LPLONG plPan) PURE; + STDMETHOD(GetFrequency) (THIS_ LPDWORD pdwFrequency) PURE; + STDMETHOD(GetStatus) (THIS_ LPDWORD pdwStatus) PURE; + STDMETHOD(Initialize) (THIS_ LPDIRECTSOUND pDirectSound, LPCDSBUFFERDESC pcDSBufferDesc) PURE; + STDMETHOD(Lock) (THIS_ DWORD dwOffset, DWORD dwBytes, LPVOID *ppvAudioPtr1, LPDWORD pdwAudioBytes1, + LPVOID *ppvAudioPtr2, LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE; + STDMETHOD(Play) (THIS_ DWORD dwReserved1, DWORD dwPriority, DWORD dwFlags) PURE; + STDMETHOD(SetCurrentPosition) (THIS_ DWORD dwNewPosition) PURE; + STDMETHOD(SetFormat) (THIS_ LPCWAVEFORMATEX pcfxFormat) PURE; + STDMETHOD(SetVolume) (THIS_ LONG lVolume) PURE; + STDMETHOD(SetPan) (THIS_ LONG lPan) PURE; + STDMETHOD(SetFrequency) (THIS_ DWORD dwFrequency) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ LPVOID pvAudioPtr1, DWORD dwAudioBytes1, LPVOID pvAudioPtr2, DWORD dwAudioBytes2) PURE; + STDMETHOD(Restore) (THIS) PURE; +}; + +#define IDirectSoundBuffer_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundBuffer_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundBuffer_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSoundBuffer_GetCurrentPosition(p,a,b) (p)->lpVtbl->GetCurrentPosition(p,a,b) +#define IDirectSoundBuffer_GetFormat(p,a,b,c) (p)->lpVtbl->GetFormat(p,a,b,c) +#define IDirectSoundBuffer_GetVolume(p,a) (p)->lpVtbl->GetVolume(p,a) +#define IDirectSoundBuffer_GetPan(p,a) (p)->lpVtbl->GetPan(p,a) +#define IDirectSoundBuffer_GetFrequency(p,a) (p)->lpVtbl->GetFrequency(p,a) +#define IDirectSoundBuffer_GetStatus(p,a) (p)->lpVtbl->GetStatus(p,a) +#define IDirectSoundBuffer_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundBuffer_Play(p,a,b,c) (p)->lpVtbl->Play(p,a,b,c) +#define IDirectSoundBuffer_SetCurrentPosition(p,a) (p)->lpVtbl->SetCurrentPosition(p,a) +#define IDirectSoundBuffer_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a) +#define IDirectSoundBuffer_SetVolume(p,a) (p)->lpVtbl->SetVolume(p,a) +#define IDirectSoundBuffer_SetPan(p,a) (p)->lpVtbl->SetPan(p,a) +#define IDirectSoundBuffer_SetFrequency(p,a) (p)->lpVtbl->SetFrequency(p,a) +#define IDirectSoundBuffer_Stop(p) (p)->lpVtbl->Stop(p) +#define IDirectSoundBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d) +#define IDirectSoundBuffer_Restore(p) (p)->lpVtbl->Restore(p) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSoundBuffer_GetCurrentPosition(p,a,b) (p)->GetCurrentPosition(a,b) +#define IDirectSoundBuffer_GetFormat(p,a,b,c) (p)->GetFormat(a,b,c) +#define IDirectSoundBuffer_GetVolume(p,a) (p)->GetVolume(a) +#define IDirectSoundBuffer_GetPan(p,a) (p)->GetPan(a) +#define IDirectSoundBuffer_GetFrequency(p,a) (p)->GetFrequency(a) +#define IDirectSoundBuffer_GetStatus(p,a) (p)->GetStatus(a) +#define IDirectSoundBuffer_Initialize(p,a,b) (p)->Initialize(a,b) +#define IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) (p)->Lock(a,b,c,d,e,f,g) +#define IDirectSoundBuffer_Play(p,a,b,c) (p)->Play(a,b,c) +#define IDirectSoundBuffer_SetCurrentPosition(p,a) (p)->SetCurrentPosition(a) +#define IDirectSoundBuffer_SetFormat(p,a) (p)->SetFormat(a) +#define IDirectSoundBuffer_SetVolume(p,a) (p)->SetVolume(a) +#define IDirectSoundBuffer_SetPan(p,a) (p)->SetPan(a) +#define IDirectSoundBuffer_SetFrequency(p,a) (p)->SetFrequency(a) +#define IDirectSoundBuffer_Stop(p) (p)->Stop() +#define IDirectSoundBuffer_Unlock(p,a,b,c,d) (p)->Unlock(a,b,c,d) +#define IDirectSoundBuffer_Restore(p) (p)->Restore() +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#if DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSoundBuffer8 +// + +DEFINE_GUID(IID_IDirectSoundBuffer8, 0x6825a449, 0x7524, 0x4d82, 0x92, 0x0f, 0x50, 0xe3, 0x6a, 0xb3, 0xab, 0x1e); + +#undef INTERFACE +#define INTERFACE IDirectSoundBuffer8 + +DECLARE_INTERFACE_(IDirectSoundBuffer8, IDirectSoundBuffer) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundBuffer methods + STDMETHOD(GetCaps) (THIS_ LPDSBCAPS pDSBufferCaps) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD pdwCurrentPlayCursor, LPDWORD pdwCurrentWriteCursor) PURE; + STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX pwfxFormat, DWORD dwSizeAllocated, LPDWORD pdwSizeWritten) PURE; + STDMETHOD(GetVolume) (THIS_ LPLONG plVolume) PURE; + STDMETHOD(GetPan) (THIS_ LPLONG plPan) PURE; + STDMETHOD(GetFrequency) (THIS_ LPDWORD pdwFrequency) PURE; + STDMETHOD(GetStatus) (THIS_ LPDWORD pdwStatus) PURE; + STDMETHOD(Initialize) (THIS_ LPDIRECTSOUND pDirectSound, LPCDSBUFFERDESC pcDSBufferDesc) PURE; + STDMETHOD(Lock) (THIS_ DWORD dwOffset, DWORD dwBytes, LPVOID *ppvAudioPtr1, LPDWORD pdwAudioBytes1, + LPVOID *ppvAudioPtr2, LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE; + STDMETHOD(Play) (THIS_ DWORD dwReserved1, DWORD dwPriority, DWORD dwFlags) PURE; + STDMETHOD(SetCurrentPosition) (THIS_ DWORD dwNewPosition) PURE; + STDMETHOD(SetFormat) (THIS_ LPCWAVEFORMATEX pcfxFormat) PURE; + STDMETHOD(SetVolume) (THIS_ LONG lVolume) PURE; + STDMETHOD(SetPan) (THIS_ LONG lPan) PURE; + STDMETHOD(SetFrequency) (THIS_ DWORD dwFrequency) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ LPVOID pvAudioPtr1, DWORD dwAudioBytes1, LPVOID pvAudioPtr2, DWORD dwAudioBytes2) PURE; + STDMETHOD(Restore) (THIS) PURE; + + // IDirectSoundBuffer8 methods + STDMETHOD(SetFX) (THIS_ DWORD dwEffectsCount, LPDSEFFECTDESC pDSFXDesc, LPDWORD pdwResultCodes) PURE; + STDMETHOD(AcquireResources) (THIS_ DWORD dwFlags, DWORD dwEffectsCount, LPDWORD pdwResultCodes) PURE; + STDMETHOD(GetObjectInPath) (THIS_ REFGUID rguidObject, DWORD dwIndex, REFGUID rguidInterface, LPVOID *ppObject) PURE; +}; + +// Special GUID meaning "select all objects" for use in GetObjectInPath() +DEFINE_GUID(GUID_All_Objects, 0xaa114de5, 0xc262, 0x4169, 0xa1, 0xc8, 0x23, 0xd6, 0x98, 0xcc, 0x73, 0xb5); + +#define IDirectSoundBuffer8_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundBuffer8_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundBuffer8_Release(p) IUnknown_Release(p) + +#define IDirectSoundBuffer8_GetCaps(p,a) IDirectSoundBuffer_GetCaps(p,a) +#define IDirectSoundBuffer8_GetCurrentPosition(p,a,b) IDirectSoundBuffer_GetCurrentPosition(p,a,b) +#define IDirectSoundBuffer8_GetFormat(p,a,b,c) IDirectSoundBuffer_GetFormat(p,a,b,c) +#define IDirectSoundBuffer8_GetVolume(p,a) IDirectSoundBuffer_GetVolume(p,a) +#define IDirectSoundBuffer8_GetPan(p,a) IDirectSoundBuffer_GetPan(p,a) +#define IDirectSoundBuffer8_GetFrequency(p,a) IDirectSoundBuffer_GetFrequency(p,a) +#define IDirectSoundBuffer8_GetStatus(p,a) IDirectSoundBuffer_GetStatus(p,a) +#define IDirectSoundBuffer8_Initialize(p,a,b) IDirectSoundBuffer_Initialize(p,a,b) +#define IDirectSoundBuffer8_Lock(p,a,b,c,d,e,f,g) IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundBuffer8_Play(p,a,b,c) IDirectSoundBuffer_Play(p,a,b,c) +#define IDirectSoundBuffer8_SetCurrentPosition(p,a) IDirectSoundBuffer_SetCurrentPosition(p,a) +#define IDirectSoundBuffer8_SetFormat(p,a) IDirectSoundBuffer_SetFormat(p,a) +#define IDirectSoundBuffer8_SetVolume(p,a) IDirectSoundBuffer_SetVolume(p,a) +#define IDirectSoundBuffer8_SetPan(p,a) IDirectSoundBuffer_SetPan(p,a) +#define IDirectSoundBuffer8_SetFrequency(p,a) IDirectSoundBuffer_SetFrequency(p,a) +#define IDirectSoundBuffer8_Stop(p) IDirectSoundBuffer_Stop(p) +#define IDirectSoundBuffer8_Unlock(p,a,b,c,d) IDirectSoundBuffer_Unlock(p,a,b,c,d) +#define IDirectSoundBuffer8_Restore(p) IDirectSoundBuffer_Restore(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer8_SetFX(p,a,b,c) (p)->lpVtbl->SetFX(p,a,b,c) +#define IDirectSoundBuffer8_AcquireResources(p,a,b,c) (p)->lpVtbl->AcquireResources(p,a,b,c) +#define IDirectSoundBuffer8_GetObjectInPath(p,a,b,c,d) (p)->lpVtbl->GetObjectInPath(p,a,b,c,d) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer8_SetFX(p,a,b,c) (p)->SetFX(a,b,c) +#define IDirectSoundBuffer8_AcquireResources(p,a,b,c) (p)->AcquireResources(a,b,c) +#define IDirectSoundBuffer8_GetObjectInPath(p,a,b,c,d) (p)->GetObjectInPath(a,b,c,d) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSound3DListener +// + +DEFINE_GUID(IID_IDirectSound3DListener, 0x279AFA84, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSound3DListener + +DECLARE_INTERFACE_(IDirectSound3DListener, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSound3DListener methods + STDMETHOD(GetAllParameters) (THIS_ LPDS3DLISTENER pListener) PURE; + STDMETHOD(GetDistanceFactor) (THIS_ D3DVALUE* pflDistanceFactor) PURE; + STDMETHOD(GetDopplerFactor) (THIS_ D3DVALUE* pflDopplerFactor) PURE; + STDMETHOD(GetOrientation) (THIS_ D3DVECTOR* pvOrientFront, D3DVECTOR* pvOrientTop) PURE; + STDMETHOD(GetPosition) (THIS_ D3DVECTOR* pvPosition) PURE; + STDMETHOD(GetRolloffFactor) (THIS_ D3DVALUE* pflRolloffFactor) PURE; + STDMETHOD(GetVelocity) (THIS_ D3DVECTOR* pvVelocity) PURE; + STDMETHOD(SetAllParameters) (THIS_ LPCDS3DLISTENER pcListener, DWORD dwApply) PURE; + STDMETHOD(SetDistanceFactor) (THIS_ D3DVALUE flDistanceFactor, DWORD dwApply) PURE; + STDMETHOD(SetDopplerFactor) (THIS_ D3DVALUE flDopplerFactor, DWORD dwApply) PURE; + STDMETHOD(SetOrientation) (THIS_ D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront, + D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop, DWORD dwApply) PURE; + STDMETHOD(SetPosition) (THIS_ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply) PURE; + STDMETHOD(SetRolloffFactor) (THIS_ D3DVALUE flRolloffFactor, DWORD dwApply) PURE; + STDMETHOD(SetVelocity) (THIS_ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply) PURE; + STDMETHOD(CommitDeferredSettings) (THIS) PURE; +}; + +#define IDirectSound3DListener_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSound3DListener_AddRef(p) IUnknown_AddRef(p) +#define IDirectSound3DListener_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DListener_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#define IDirectSound3DListener_GetDistanceFactor(p,a) (p)->lpVtbl->GetDistanceFactor(p,a) +#define IDirectSound3DListener_GetDopplerFactor(p,a) (p)->lpVtbl->GetDopplerFactor(p,a) +#define IDirectSound3DListener_GetOrientation(p,a,b) (p)->lpVtbl->GetOrientation(p,a,b) +#define IDirectSound3DListener_GetPosition(p,a) (p)->lpVtbl->GetPosition(p,a) +#define IDirectSound3DListener_GetRolloffFactor(p,a) (p)->lpVtbl->GetRolloffFactor(p,a) +#define IDirectSound3DListener_GetVelocity(p,a) (p)->lpVtbl->GetVelocity(p,a) +#define IDirectSound3DListener_SetAllParameters(p,a,b) (p)->lpVtbl->SetAllParameters(p,a,b) +#define IDirectSound3DListener_SetDistanceFactor(p,a,b) (p)->lpVtbl->SetDistanceFactor(p,a,b) +#define IDirectSound3DListener_SetDopplerFactor(p,a,b) (p)->lpVtbl->SetDopplerFactor(p,a,b) +#define IDirectSound3DListener_SetOrientation(p,a,b,c,d,e,f,g) (p)->lpVtbl->SetOrientation(p,a,b,c,d,e,f,g) +#define IDirectSound3DListener_SetPosition(p,a,b,c,d) (p)->lpVtbl->SetPosition(p,a,b,c,d) +#define IDirectSound3DListener_SetRolloffFactor(p,a,b) (p)->lpVtbl->SetRolloffFactor(p,a,b) +#define IDirectSound3DListener_SetVelocity(p,a,b,c,d) (p)->lpVtbl->SetVelocity(p,a,b,c,d) +#define IDirectSound3DListener_CommitDeferredSettings(p) (p)->lpVtbl->CommitDeferredSettings(p) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DListener_GetAllParameters(p,a) (p)->GetAllParameters(a) +#define IDirectSound3DListener_GetDistanceFactor(p,a) (p)->GetDistanceFactor(a) +#define IDirectSound3DListener_GetDopplerFactor(p,a) (p)->GetDopplerFactor(a) +#define IDirectSound3DListener_GetOrientation(p,a,b) (p)->GetOrientation(a,b) +#define IDirectSound3DListener_GetPosition(p,a) (p)->GetPosition(a) +#define IDirectSound3DListener_GetRolloffFactor(p,a) (p)->GetRolloffFactor(a) +#define IDirectSound3DListener_GetVelocity(p,a) (p)->GetVelocity(a) +#define IDirectSound3DListener_SetAllParameters(p,a,b) (p)->SetAllParameters(a,b) +#define IDirectSound3DListener_SetDistanceFactor(p,a,b) (p)->SetDistanceFactor(a,b) +#define IDirectSound3DListener_SetDopplerFactor(p,a,b) (p)->SetDopplerFactor(a,b) +#define IDirectSound3DListener_SetOrientation(p,a,b,c,d,e,f,g) (p)->SetOrientation(a,b,c,d,e,f,g) +#define IDirectSound3DListener_SetPosition(p,a,b,c,d) (p)->SetPosition(a,b,c,d) +#define IDirectSound3DListener_SetRolloffFactor(p,a,b) (p)->SetRolloffFactor(a,b) +#define IDirectSound3DListener_SetVelocity(p,a,b,c,d) (p)->SetVelocity(a,b,c,d) +#define IDirectSound3DListener_CommitDeferredSettings(p) (p)->CommitDeferredSettings() +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSound3DBuffer +// + +DEFINE_GUID(IID_IDirectSound3DBuffer, 0x279AFA86, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSound3DBuffer + +DECLARE_INTERFACE_(IDirectSound3DBuffer, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSound3DBuffer methods + STDMETHOD(GetAllParameters) (THIS_ LPDS3DBUFFER pDs3dBuffer) PURE; + STDMETHOD(GetConeAngles) (THIS_ LPDWORD pdwInsideConeAngle, LPDWORD pdwOutsideConeAngle) PURE; + STDMETHOD(GetConeOrientation) (THIS_ D3DVECTOR* pvOrientation) PURE; + STDMETHOD(GetConeOutsideVolume) (THIS_ LPLONG plConeOutsideVolume) PURE; + STDMETHOD(GetMaxDistance) (THIS_ D3DVALUE* pflMaxDistance) PURE; + STDMETHOD(GetMinDistance) (THIS_ D3DVALUE* pflMinDistance) PURE; + STDMETHOD(GetMode) (THIS_ LPDWORD pdwMode) PURE; + STDMETHOD(GetPosition) (THIS_ D3DVECTOR* pvPosition) PURE; + STDMETHOD(GetVelocity) (THIS_ D3DVECTOR* pvVelocity) PURE; + STDMETHOD(SetAllParameters) (THIS_ LPCDS3DBUFFER pcDs3dBuffer, DWORD dwApply) PURE; + STDMETHOD(SetConeAngles) (THIS_ DWORD dwInsideConeAngle, DWORD dwOutsideConeAngle, DWORD dwApply) PURE; + STDMETHOD(SetConeOrientation) (THIS_ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply) PURE; + STDMETHOD(SetConeOutsideVolume) (THIS_ LONG lConeOutsideVolume, DWORD dwApply) PURE; + STDMETHOD(SetMaxDistance) (THIS_ D3DVALUE flMaxDistance, DWORD dwApply) PURE; + STDMETHOD(SetMinDistance) (THIS_ D3DVALUE flMinDistance, DWORD dwApply) PURE; + STDMETHOD(SetMode) (THIS_ DWORD dwMode, DWORD dwApply) PURE; + STDMETHOD(SetPosition) (THIS_ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply) PURE; + STDMETHOD(SetVelocity) (THIS_ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply) PURE; +}; + +#define IDirectSound3DBuffer_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSound3DBuffer_AddRef(p) IUnknown_AddRef(p) +#define IDirectSound3DBuffer_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DBuffer_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#define IDirectSound3DBuffer_GetConeAngles(p,a,b) (p)->lpVtbl->GetConeAngles(p,a,b) +#define IDirectSound3DBuffer_GetConeOrientation(p,a) (p)->lpVtbl->GetConeOrientation(p,a) +#define IDirectSound3DBuffer_GetConeOutsideVolume(p,a) (p)->lpVtbl->GetConeOutsideVolume(p,a) +#define IDirectSound3DBuffer_GetPosition(p,a) (p)->lpVtbl->GetPosition(p,a) +#define IDirectSound3DBuffer_GetMinDistance(p,a) (p)->lpVtbl->GetMinDistance(p,a) +#define IDirectSound3DBuffer_GetMaxDistance(p,a) (p)->lpVtbl->GetMaxDistance(p,a) +#define IDirectSound3DBuffer_GetMode(p,a) (p)->lpVtbl->GetMode(p,a) +#define IDirectSound3DBuffer_GetVelocity(p,a) (p)->lpVtbl->GetVelocity(p,a) +#define IDirectSound3DBuffer_SetAllParameters(p,a,b) (p)->lpVtbl->SetAllParameters(p,a,b) +#define IDirectSound3DBuffer_SetConeAngles(p,a,b,c) (p)->lpVtbl->SetConeAngles(p,a,b,c) +#define IDirectSound3DBuffer_SetConeOrientation(p,a,b,c,d) (p)->lpVtbl->SetConeOrientation(p,a,b,c,d) +#define IDirectSound3DBuffer_SetConeOutsideVolume(p,a,b) (p)->lpVtbl->SetConeOutsideVolume(p,a,b) +#define IDirectSound3DBuffer_SetPosition(p,a,b,c,d) (p)->lpVtbl->SetPosition(p,a,b,c,d) +#define IDirectSound3DBuffer_SetMinDistance(p,a,b) (p)->lpVtbl->SetMinDistance(p,a,b) +#define IDirectSound3DBuffer_SetMaxDistance(p,a,b) (p)->lpVtbl->SetMaxDistance(p,a,b) +#define IDirectSound3DBuffer_SetMode(p,a,b) (p)->lpVtbl->SetMode(p,a,b) +#define IDirectSound3DBuffer_SetVelocity(p,a,b,c,d) (p)->lpVtbl->SetVelocity(p,a,b,c,d) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DBuffer_GetAllParameters(p,a) (p)->GetAllParameters(a) +#define IDirectSound3DBuffer_GetConeAngles(p,a,b) (p)->GetConeAngles(a,b) +#define IDirectSound3DBuffer_GetConeOrientation(p,a) (p)->GetConeOrientation(a) +#define IDirectSound3DBuffer_GetConeOutsideVolume(p,a) (p)->GetConeOutsideVolume(a) +#define IDirectSound3DBuffer_GetPosition(p,a) (p)->GetPosition(a) +#define IDirectSound3DBuffer_GetMinDistance(p,a) (p)->GetMinDistance(a) +#define IDirectSound3DBuffer_GetMaxDistance(p,a) (p)->GetMaxDistance(a) +#define IDirectSound3DBuffer_GetMode(p,a) (p)->GetMode(a) +#define IDirectSound3DBuffer_GetVelocity(p,a) (p)->GetVelocity(a) +#define IDirectSound3DBuffer_SetAllParameters(p,a,b) (p)->SetAllParameters(a,b) +#define IDirectSound3DBuffer_SetConeAngles(p,a,b,c) (p)->SetConeAngles(a,b,c) +#define IDirectSound3DBuffer_SetConeOrientation(p,a,b,c,d) (p)->SetConeOrientation(a,b,c,d) +#define IDirectSound3DBuffer_SetConeOutsideVolume(p,a,b) (p)->SetConeOutsideVolume(a,b) +#define IDirectSound3DBuffer_SetPosition(p,a,b,c,d) (p)->SetPosition(a,b,c,d) +#define IDirectSound3DBuffer_SetMinDistance(p,a,b) (p)->SetMinDistance(a,b) +#define IDirectSound3DBuffer_SetMaxDistance(p,a,b) (p)->SetMaxDistance(a,b) +#define IDirectSound3DBuffer_SetMode(p,a,b) (p)->SetMode(a,b) +#define IDirectSound3DBuffer_SetVelocity(p,a,b,c,d) (p)->SetVelocity(a,b,c,d) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundCapture +// + +DEFINE_GUID(IID_IDirectSoundCapture, 0xb0210781, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +#undef INTERFACE +#define INTERFACE IDirectSoundCapture + +DECLARE_INTERFACE_(IDirectSoundCapture, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCapture methods + STDMETHOD(CreateCaptureBuffer) (THIS_ LPCDSCBUFFERDESC pcDSCBufferDesc, LPDIRECTSOUNDCAPTUREBUFFER *ppDSCBuffer, LPUNKNOWN pUnkOuter) PURE; + STDMETHOD(GetCaps) (THIS_ LPDSCCAPS pDSCCaps) PURE; + STDMETHOD(Initialize) (THIS_ LPCGUID pcGuidDevice) PURE; +}; + +#define IDirectSoundCapture_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundCapture_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundCapture_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCapture_CreateCaptureBuffer(p,a,b,c) (p)->lpVtbl->CreateCaptureBuffer(p,a,b,c) +#define IDirectSoundCapture_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSoundCapture_Initialize(p,a) (p)->lpVtbl->Initialize(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCapture_CreateCaptureBuffer(p,a,b,c) (p)->CreateCaptureBuffer(a,b,c) +#define IDirectSoundCapture_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSoundCapture_Initialize(p,a) (p)->Initialize(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundCaptureBuffer +// + +DEFINE_GUID(IID_IDirectSoundCaptureBuffer, 0xb0210782, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +#undef INTERFACE +#define INTERFACE IDirectSoundCaptureBuffer + +DECLARE_INTERFACE_(IDirectSoundCaptureBuffer, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCaptureBuffer methods + STDMETHOD(GetCaps) (THIS_ LPDSCBCAPS pDSCBCaps) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD pdwCapturePosition, LPDWORD pdwReadPosition) PURE; + STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX pwfxFormat, DWORD dwSizeAllocated, LPDWORD pdwSizeWritten) PURE; + STDMETHOD(GetStatus) (THIS_ LPDWORD pdwStatus) PURE; + STDMETHOD(Initialize) (THIS_ LPDIRECTSOUNDCAPTURE pDirectSoundCapture, LPCDSCBUFFERDESC pcDSCBufferDesc) PURE; + STDMETHOD(Lock) (THIS_ DWORD dwOffset, DWORD dwBytes, LPVOID *ppvAudioPtr1, LPDWORD pdwAudioBytes1, + LPVOID *ppvAudioPtr2, LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE; + STDMETHOD(Start) (THIS_ DWORD dwFlags) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ LPVOID pvAudioPtr1, DWORD dwAudioBytes1, LPVOID pvAudioPtr2, DWORD dwAudioBytes2) PURE; +}; + +#define IDirectSoundCaptureBuffer_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundCaptureBuffer_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundCaptureBuffer_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureBuffer_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSoundCaptureBuffer_GetCurrentPosition(p,a,b) (p)->lpVtbl->GetCurrentPosition(p,a,b) +#define IDirectSoundCaptureBuffer_GetFormat(p,a,b,c) (p)->lpVtbl->GetFormat(p,a,b,c) +#define IDirectSoundCaptureBuffer_GetStatus(p,a) (p)->lpVtbl->GetStatus(p,a) +#define IDirectSoundCaptureBuffer_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectSoundCaptureBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundCaptureBuffer_Start(p,a) (p)->lpVtbl->Start(p,a) +#define IDirectSoundCaptureBuffer_Stop(p) (p)->lpVtbl->Stop(p) +#define IDirectSoundCaptureBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureBuffer_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSoundCaptureBuffer_GetCurrentPosition(p,a,b) (p)->GetCurrentPosition(a,b) +#define IDirectSoundCaptureBuffer_GetFormat(p,a,b,c) (p)->GetFormat(a,b,c) +#define IDirectSoundCaptureBuffer_GetStatus(p,a) (p)->GetStatus(a) +#define IDirectSoundCaptureBuffer_Initialize(p,a,b) (p)->Initialize(a,b) +#define IDirectSoundCaptureBuffer_Lock(p,a,b,c,d,e,f,g) (p)->Lock(a,b,c,d,e,f,g) +#define IDirectSoundCaptureBuffer_Start(p,a) (p)->Start(a) +#define IDirectSoundCaptureBuffer_Stop(p) (p)->Stop() +#define IDirectSoundCaptureBuffer_Unlock(p,a,b,c,d) (p)->Unlock(a,b,c,d) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + + +#if DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSoundCaptureBuffer8 +// + +DEFINE_GUID(IID_IDirectSoundCaptureBuffer8, 0x990df4, 0xdbb, 0x4872, 0x83, 0x3e, 0x6d, 0x30, 0x3e, 0x80, 0xae, 0xb6); + +#undef INTERFACE +#define INTERFACE IDirectSoundCaptureBuffer8 + +DECLARE_INTERFACE_(IDirectSoundCaptureBuffer8, IDirectSoundCaptureBuffer) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCaptureBuffer methods + STDMETHOD(GetCaps) (THIS_ LPDSCBCAPS pDSCBCaps) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD pdwCapturePosition, LPDWORD pdwReadPosition) PURE; + STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX pwfxFormat, DWORD dwSizeAllocated, LPDWORD pdwSizeWritten) PURE; + STDMETHOD(GetStatus) (THIS_ LPDWORD pdwStatus) PURE; + STDMETHOD(Initialize) (THIS_ LPDIRECTSOUNDCAPTURE pDirectSoundCapture, LPCDSCBUFFERDESC pcDSCBufferDesc) PURE; + STDMETHOD(Lock) (THIS_ DWORD dwOffset, DWORD dwBytes, LPVOID *ppvAudioPtr1, LPDWORD pdwAudioBytes1, + LPVOID *ppvAudioPtr2, LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE; + STDMETHOD(Start) (THIS_ DWORD dwFlags) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ LPVOID pvAudioPtr1, DWORD dwAudioBytes1, LPVOID pvAudioPtr2, DWORD dwAudioBytes2) PURE; + + // IDirectSoundCaptureBuffer8 methods + STDMETHOD(GetObjectInPath) (THIS_ REFGUID rguidObject, DWORD dwIndex, REFGUID rguidInterface, LPVOID *ppObject) PURE; + STDMETHOD(GetFXStatus) (DWORD dwFXCount, LPDWORD pdwFXStatus) PURE; +}; + +#define IDirectSoundCaptureBuffer8_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundCaptureBuffer8_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundCaptureBuffer8_Release(p) IUnknown_Release(p) + +#define IDirectSoundCaptureBuffer8_GetCaps(p,a) IDirectSoundCaptureBuffer_GetCaps(p,a) +#define IDirectSoundCaptureBuffer8_GetCurrentPosition(p,a,b) IDirectSoundCaptureBuffer_GetCurrentPosition(p,a,b) +#define IDirectSoundCaptureBuffer8_GetFormat(p,a,b,c) IDirectSoundCaptureBuffer_GetFormat(p,a,b,c) +#define IDirectSoundCaptureBuffer8_GetStatus(p,a) IDirectSoundCaptureBuffer_GetStatus(p,a) +#define IDirectSoundCaptureBuffer8_Initialize(p,a,b) IDirectSoundCaptureBuffer_Initialize(p,a,b) +#define IDirectSoundCaptureBuffer8_Lock(p,a,b,c,d,e,f,g) IDirectSoundCaptureBuffer_Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundCaptureBuffer8_Start(p,a) IDirectSoundCaptureBuffer_Start(p,a) +#define IDirectSoundCaptureBuffer8_Stop(p) IDirectSoundCaptureBuffer_Stop(p)) +#define IDirectSoundCaptureBuffer8_Unlock(p,a,b,c,d) IDirectSoundCaptureBuffer_Unlock(p,a,b,c,d) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureBuffer8_GetObjectInPath(p,a,b,c,d) (p)->lpVtbl->GetObjectInPath(p,a,b,c,d) +#define IDirectSoundCaptureBuffer8_GetFXStatus(p,a,b) (p)->lpVtbl->GetFXStatus(p,a,b) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureBuffer8_GetObjectInPath(p,a,b,c,d) (p)->GetObjectInPath(a,b,c,d) +#define IDirectSoundCaptureBuffer8_GetFXStatus(p,a,b) (p)->GetFXStatus(a,b) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSoundNotify +// + +DEFINE_GUID(IID_IDirectSoundNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +#undef INTERFACE +#define INTERFACE IDirectSoundNotify + +DECLARE_INTERFACE_(IDirectSoundNotify, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundNotify methods + STDMETHOD(SetNotificationPositions) (THIS_ DWORD dwPositionNotifies, LPCDSBPOSITIONNOTIFY pcPositionNotifies) PURE; +}; + +#define IDirectSoundNotify_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundNotify_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundNotify_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundNotify_SetNotificationPositions(p,a,b) (p)->lpVtbl->SetNotificationPositions(p,a,b) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundNotify_SetNotificationPositions(p,a,b) (p)->SetNotificationPositions(a,b) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IKsPropertySet +// + +#ifndef _IKsPropertySet_ +#define _IKsPropertySet_ + +#ifdef __cplusplus +// 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined +struct IKsPropertySet; +#endif // __cplusplus + +typedef struct IKsPropertySet *LPKSPROPERTYSET; + +#define KSPROPERTY_SUPPORT_GET 0x00000001 +#define KSPROPERTY_SUPPORT_SET 0x00000002 + +DEFINE_GUID(IID_IKsPropertySet, 0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93); + +#undef INTERFACE +#define INTERFACE IKsPropertySet + +DECLARE_INTERFACE_(IKsPropertySet, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IKsPropertySet methods + STDMETHOD(Get) (THIS_ REFGUID rguidPropSet, ULONG ulId, LPVOID pInstanceData, ULONG ulInstanceLength, + LPVOID pPropertyData, ULONG ulDataLength, PULONG pulBytesReturned) PURE; + STDMETHOD(Set) (THIS_ REFGUID rguidPropSet, ULONG ulId, LPVOID pInstanceData, ULONG ulInstanceLength, + LPVOID pPropertyData, ULONG ulDataLength) PURE; + STDMETHOD(QuerySupport) (THIS_ REFGUID rguidPropSet, ULONG ulId, PULONG pulTypeSupport) PURE; +}; + +#define IKsPropertySet_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IKsPropertySet_AddRef(p) IUnknown_AddRef(p) +#define IKsPropertySet_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IKsPropertySet_Get(p,a,b,c,d,e,f,g) (p)->lpVtbl->Get(p,a,b,c,d,e,f,g) +#define IKsPropertySet_Set(p,a,b,c,d,e,f) (p)->lpVtbl->Set(p,a,b,c,d,e,f) +#define IKsPropertySet_QuerySupport(p,a,b,c) (p)->lpVtbl->QuerySupport(p,a,b,c) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IKsPropertySet_Get(p,a,b,c,d,e,f,g) (p)->Get(a,b,c,d,e,f,g) +#define IKsPropertySet_Set(p,a,b,c,d,e,f) (p)->Set(a,b,c,d,e,f) +#define IKsPropertySet_QuerySupport(p,a,b,c) (p)->QuerySupport(a,b,c) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // _IKsPropertySet_ + +#if DIRECTSOUND_VERSION >= 0x0800 + +// +// IDirectSoundFXGargle +// + +DEFINE_GUID(IID_IDirectSoundFXGargle, 0xd616f352, 0xd622, 0x11ce, 0xaa, 0xc5, 0x00, 0x20, 0xaf, 0x0b, 0x99, 0xa3); + +typedef struct _DSFXGargle +{ + DWORD dwRateHz; // Rate of modulation in hz + DWORD dwWaveShape; // DSFXGARGLE_WAVE_xxx +} DSFXGargle, *LPDSFXGargle; + +#define DSFXGARGLE_WAVE_TRIANGLE 0 +#define DSFXGARGLE_WAVE_SQUARE 1 + +typedef const DSFXGargle *LPCDSFXGargle; + +#define DSFXGARGLE_RATEHZ_MIN 1 +#define DSFXGARGLE_RATEHZ_MAX 1000 + +#undef INTERFACE +#define INTERFACE IDirectSoundFXGargle + +DECLARE_INTERFACE_(IDirectSoundFXGargle, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXGargle methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSFXGargle pcDsFxGargle) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSFXGargle pDsFxGargle) PURE; +}; + +#define IDirectSoundFXGargle_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXGargle_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXGargle_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXGargle_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXGargle_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXGargle_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXGargle_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXChorus +// + +DEFINE_GUID(IID_IDirectSoundFXChorus, 0x880842e3, 0x145f, 0x43e6, 0xa9, 0x34, 0xa7, 0x18, 0x06, 0xe5, 0x05, 0x47); + +typedef struct _DSFXChorus +{ + FLOAT fWetDryMix; + FLOAT fDepth; + FLOAT fFeedback; + FLOAT fFrequency; + LONG lWaveform; // LFO shape; DSFXCHORUS_WAVE_xxx + FLOAT fDelay; + LONG lPhase; +} DSFXChorus, *LPDSFXChorus; + +typedef const DSFXChorus *LPCDSFXChorus; + +#define DSFXCHORUS_WAVE_TRIANGLE 0 +#define DSFXCHORUS_WAVE_SIN 1 + +#define DSFXCHORUS_WETDRYMIX_MIN 0.0f +#define DSFXCHORUS_WETDRYMIX_MAX 100.0f +#define DSFXCHORUS_DEPTH_MIN 0.0f +#define DSFXCHORUS_DEPTH_MAX 100.0f +#define DSFXCHORUS_FEEDBACK_MIN -99.0f +#define DSFXCHORUS_FEEDBACK_MAX 99.0f +#define DSFXCHORUS_FREQUENCY_MIN 0.0f +#define DSFXCHORUS_FREQUENCY_MAX 10.0f +#define DSFXCHORUS_DELAY_MIN 0.0f +#define DSFXCHORUS_DELAY_MAX 20.0f +#define DSFXCHORUS_PHASE_MIN 0 +#define DSFXCHORUS_PHASE_MAX 4 + +#define DSFXCHORUS_PHASE_NEG_180 0 +#define DSFXCHORUS_PHASE_NEG_90 1 +#define DSFXCHORUS_PHASE_ZERO 2 +#define DSFXCHORUS_PHASE_90 3 +#define DSFXCHORUS_PHASE_180 4 + +#undef INTERFACE +#define INTERFACE IDirectSoundFXChorus + +DECLARE_INTERFACE_(IDirectSoundFXChorus, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXChorus methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSFXChorus pcDsFxChorus) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSFXChorus pDsFxChorus) PURE; +}; + +#define IDirectSoundFXChorus_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXChorus_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXChorus_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXChorus_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXChorus_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXChorus_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXChorus_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXFlanger +// + +DEFINE_GUID(IID_IDirectSoundFXFlanger, 0x903e9878, 0x2c92, 0x4072, 0x9b, 0x2c, 0xea, 0x68, 0xf5, 0x39, 0x67, 0x83); + +typedef struct _DSFXFlanger +{ + FLOAT fWetDryMix; + FLOAT fDepth; + FLOAT fFeedback; + FLOAT fFrequency; + LONG lWaveform; + FLOAT fDelay; + LONG lPhase; +} DSFXFlanger, *LPDSFXFlanger; + +typedef const DSFXFlanger *LPCDSFXFlanger; + +#define DSFXFLANGER_WAVE_TRIANGLE 0 +#define DSFXFLANGER_WAVE_SIN 1 + +#define DSFXFLANGER_WETDRYMIX_MIN 0.0f +#define DSFXFLANGER_WETDRYMIX_MAX 100.0f +#define DSFXFLANGER_FREQUENCY_MIN 0.0f +#define DSFXFLANGER_FREQUENCY_MAX 10.0f +#define DSFXFLANGER_DEPTH_MIN 0.0f +#define DSFXFLANGER_DEPTH_MAX 100.0f +#define DSFXFLANGER_PHASE_MIN 0 +#define DSFXFLANGER_PHASE_MAX 4 +#define DSFXFLANGER_FEEDBACK_MIN -99.0f +#define DSFXFLANGER_FEEDBACK_MAX 99.0f +#define DSFXFLANGER_DELAY_MIN 0.0f +#define DSFXFLANGER_DELAY_MAX 4.0f + +#define DSFXFLANGER_PHASE_NEG_180 0 +#define DSFXFLANGER_PHASE_NEG_90 1 +#define DSFXFLANGER_PHASE_ZERO 2 +#define DSFXFLANGER_PHASE_90 3 +#define DSFXFLANGER_PHASE_180 4 + +#undef INTERFACE +#define INTERFACE IDirectSoundFXFlanger + +DECLARE_INTERFACE_(IDirectSoundFXFlanger, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXFlanger methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSFXFlanger pcDsFxFlanger) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSFXFlanger pDsFxFlanger) PURE; +}; + +#define IDirectSoundFXFlanger_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXFlanger_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXFlanger_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXFlanger_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXFlanger_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXFlanger_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXFlanger_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXEcho +// + +DEFINE_GUID(IID_IDirectSoundFXEcho, 0x8bd28edf, 0x50db, 0x4e92, 0xa2, 0xbd, 0x44, 0x54, 0x88, 0xd1, 0xed, 0x42); + +typedef struct _DSFXEcho +{ + FLOAT fWetDryMix; + FLOAT fFeedback; + FLOAT fLeftDelay; + FLOAT fRightDelay; + LONG lPanDelay; +} DSFXEcho, *LPDSFXEcho; + +typedef const DSFXEcho *LPCDSFXEcho; + +#define DSFXECHO_WETDRYMIX_MIN 0.0f +#define DSFXECHO_WETDRYMIX_MAX 100.0f +#define DSFXECHO_FEEDBACK_MIN 0.0f +#define DSFXECHO_FEEDBACK_MAX 100.0f +#define DSFXECHO_LEFTDELAY_MIN 1.0f +#define DSFXECHO_LEFTDELAY_MAX 2000.0f +#define DSFXECHO_RIGHTDELAY_MIN 1.0f +#define DSFXECHO_RIGHTDELAY_MAX 2000.0f +#define DSFXECHO_PANDELAY_MIN 0 +#define DSFXECHO_PANDELAY_MAX 1 + +#undef INTERFACE +#define INTERFACE IDirectSoundFXEcho + +DECLARE_INTERFACE_(IDirectSoundFXEcho, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXEcho methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSFXEcho pcDsFxEcho) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSFXEcho pDsFxEcho) PURE; +}; + +#define IDirectSoundFXEcho_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXEcho_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXEcho_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXEcho_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXEcho_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXEcho_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXEcho_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXDistortion +// + +DEFINE_GUID(IID_IDirectSoundFXDistortion, 0x8ecf4326, 0x455f, 0x4d8b, 0xbd, 0xa9, 0x8d, 0x5d, 0x3e, 0x9e, 0x3e, 0x0b); + +typedef struct _DSFXDistortion +{ + FLOAT fGain; + FLOAT fEdge; + FLOAT fPostEQCenterFrequency; + FLOAT fPostEQBandwidth; + FLOAT fPreLowpassCutoff; +} DSFXDistortion, *LPDSFXDistortion; + +typedef const DSFXDistortion *LPCDSFXDistortion; + +#define DSFXDISTORTION_GAIN_MIN -60.0f +#define DSFXDISTORTION_GAIN_MAX 0.0f +#define DSFXDISTORTION_EDGE_MIN 0.0f +#define DSFXDISTORTION_EDGE_MAX 100.0f +#define DSFXDISTORTION_POSTEQCENTERFREQUENCY_MIN 100.0f +#define DSFXDISTORTION_POSTEQCENTERFREQUENCY_MAX 8000.0f +#define DSFXDISTORTION_POSTEQBANDWIDTH_MIN 100.0f +#define DSFXDISTORTION_POSTEQBANDWIDTH_MAX 8000.0f +#define DSFXDISTORTION_PRELOWPASSCUTOFF_MIN 100.0f +#define DSFXDISTORTION_PRELOWPASSCUTOFF_MAX 8000.0f + +#undef INTERFACE +#define INTERFACE IDirectSoundFXDistortion + +DECLARE_INTERFACE_(IDirectSoundFXDistortion, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXDistortion methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSFXDistortion pcDsFxDistortion) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSFXDistortion pDsFxDistortion) PURE; +}; + +#define IDirectSoundFXDistortion_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXDistortion_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXDistortion_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXDistortion_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXDistortion_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXDistortion_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXDistortion_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXCompressor +// + +DEFINE_GUID(IID_IDirectSoundFXCompressor, 0x4bbd1154, 0x62f6, 0x4e2c, 0xa1, 0x5c, 0xd3, 0xb6, 0xc4, 0x17, 0xf7, 0xa0); + +typedef struct _DSFXCompressor +{ + FLOAT fGain; + FLOAT fAttack; + FLOAT fRelease; + FLOAT fThreshold; + FLOAT fRatio; + FLOAT fPredelay; +} DSFXCompressor, *LPDSFXCompressor; + +typedef const DSFXCompressor *LPCDSFXCompressor; + +#define DSFXCOMPRESSOR_GAIN_MIN -60.0f +#define DSFXCOMPRESSOR_GAIN_MAX 60.0f +#define DSFXCOMPRESSOR_ATTACK_MIN 0.01f +#define DSFXCOMPRESSOR_ATTACK_MAX 500.0f +#define DSFXCOMPRESSOR_RELEASE_MIN 50.0f +#define DSFXCOMPRESSOR_RELEASE_MAX 3000.0f +#define DSFXCOMPRESSOR_THRESHOLD_MIN -60.0f +#define DSFXCOMPRESSOR_THRESHOLD_MAX 0.0f +#define DSFXCOMPRESSOR_RATIO_MIN 1.0f +#define DSFXCOMPRESSOR_RATIO_MAX 100.0f +#define DSFXCOMPRESSOR_PREDELAY_MIN 0.0f +#define DSFXCOMPRESSOR_PREDELAY_MAX 4.0f + +#undef INTERFACE +#define INTERFACE IDirectSoundFXCompressor + +DECLARE_INTERFACE_(IDirectSoundFXCompressor, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXCompressor methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSFXCompressor pcDsFxCompressor) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSFXCompressor pDsFxCompressor) PURE; +}; + +#define IDirectSoundFXCompressor_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXCompressor_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXCompressor_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXCompressor_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXCompressor_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXCompressor_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXCompressor_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXParamEq +// + +DEFINE_GUID(IID_IDirectSoundFXParamEq, 0xc03ca9fe, 0xfe90, 0x4204, 0x80, 0x78, 0x82, 0x33, 0x4c, 0xd1, 0x77, 0xda); + +typedef struct _DSFXParamEq +{ + FLOAT fCenter; + FLOAT fBandwidth; + FLOAT fGain; +} DSFXParamEq, *LPDSFXParamEq; + +typedef const DSFXParamEq *LPCDSFXParamEq; + +#define DSFXPARAMEQ_CENTER_MIN 80.0f +#define DSFXPARAMEQ_CENTER_MAX 16000.0f +#define DSFXPARAMEQ_BANDWIDTH_MIN 1.0f +#define DSFXPARAMEQ_BANDWIDTH_MAX 36.0f +#define DSFXPARAMEQ_GAIN_MIN -15.0f +#define DSFXPARAMEQ_GAIN_MAX 15.0f + +#undef INTERFACE +#define INTERFACE IDirectSoundFXParamEq + +DECLARE_INTERFACE_(IDirectSoundFXParamEq, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXParamEq methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSFXParamEq pcDsFxParamEq) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSFXParamEq pDsFxParamEq) PURE; +}; + +#define IDirectSoundFXParamEq_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXParamEq_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXParamEq_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXParamEq_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXParamEq_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXParamEq_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXParamEq_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXI3DL2Reverb +// + +DEFINE_GUID(IID_IDirectSoundFXI3DL2Reverb, 0x4b166a6a, 0x0d66, 0x43f3, 0x80, 0xe3, 0xee, 0x62, 0x80, 0xde, 0xe1, 0xa4); + +typedef struct _DSFXI3DL2Reverb +{ + LONG lRoom; // [-10000, 0] default: -1000 mB + LONG lRoomHF; // [-10000, 0] default: 0 mB + FLOAT flRoomRolloffFactor; // [0.0, 10.0] default: 0.0 + FLOAT flDecayTime; // [0.1, 20.0] default: 1.49s + FLOAT flDecayHFRatio; // [0.1, 2.0] default: 0.83 + LONG lReflections; // [-10000, 1000] default: -2602 mB + FLOAT flReflectionsDelay; // [0.0, 0.3] default: 0.007 s + LONG lReverb; // [-10000, 2000] default: 200 mB + FLOAT flReverbDelay; // [0.0, 0.1] default: 0.011 s + FLOAT flDiffusion; // [0.0, 100.0] default: 100.0 % + FLOAT flDensity; // [0.0, 100.0] default: 100.0 % + FLOAT flHFReference; // [20.0, 20000.0] default: 5000.0 Hz +} DSFXI3DL2Reverb, *LPDSFXI3DL2Reverb; + +typedef const DSFXI3DL2Reverb *LPCDSFXI3DL2Reverb; + +#define DSFX_I3DL2REVERB_ROOM_MIN (-10000) +#define DSFX_I3DL2REVERB_ROOM_MAX 0 +#define DSFX_I3DL2REVERB_ROOM_DEFAULT (-1000) + +#define DSFX_I3DL2REVERB_ROOMHF_MIN (-10000) +#define DSFX_I3DL2REVERB_ROOMHF_MAX 0 +#define DSFX_I3DL2REVERB_ROOMHF_DEFAULT (-100) + +#define DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_MIN 0.0f +#define DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_MAX 10.0f +#define DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_DEFAULT 0.0f + +#define DSFX_I3DL2REVERB_DECAYTIME_MIN 0.1f +#define DSFX_I3DL2REVERB_DECAYTIME_MAX 20.0f +#define DSFX_I3DL2REVERB_DECAYTIME_DEFAULT 1.49f + +#define DSFX_I3DL2REVERB_DECAYHFRATIO_MIN 0.1f +#define DSFX_I3DL2REVERB_DECAYHFRATIO_MAX 2.0f +#define DSFX_I3DL2REVERB_DECAYHFRATIO_DEFAULT 0.83f + +#define DSFX_I3DL2REVERB_REFLECTIONS_MIN (-10000) +#define DSFX_I3DL2REVERB_REFLECTIONS_MAX 1000 +#define DSFX_I3DL2REVERB_REFLECTIONS_DEFAULT (-2602) + +#define DSFX_I3DL2REVERB_REFLECTIONSDELAY_MIN 0.0f +#define DSFX_I3DL2REVERB_REFLECTIONSDELAY_MAX 0.3f +#define DSFX_I3DL2REVERB_REFLECTIONSDELAY_DEFAULT 0.007f + +#define DSFX_I3DL2REVERB_REVERB_MIN (-10000) +#define DSFX_I3DL2REVERB_REVERB_MAX 2000 +#define DSFX_I3DL2REVERB_REVERB_DEFAULT (200) + +#define DSFX_I3DL2REVERB_REVERBDELAY_MIN 0.0f +#define DSFX_I3DL2REVERB_REVERBDELAY_MAX 0.1f +#define DSFX_I3DL2REVERB_REVERBDELAY_DEFAULT 0.011f + +#define DSFX_I3DL2REVERB_DIFFUSION_MIN 0.0f +#define DSFX_I3DL2REVERB_DIFFUSION_MAX 100.0f +#define DSFX_I3DL2REVERB_DIFFUSION_DEFAULT 100.0f + +#define DSFX_I3DL2REVERB_DENSITY_MIN 0.0f +#define DSFX_I3DL2REVERB_DENSITY_MAX 100.0f +#define DSFX_I3DL2REVERB_DENSITY_DEFAULT 100.0f + +#define DSFX_I3DL2REVERB_HFREFERENCE_MIN 20.0f +#define DSFX_I3DL2REVERB_HFREFERENCE_MAX 20000.0f +#define DSFX_I3DL2REVERB_HFREFERENCE_DEFAULT 5000.0f + +#define DSFX_I3DL2REVERB_QUALITY_MIN 0 +#define DSFX_I3DL2REVERB_QUALITY_MAX 3 +#define DSFX_I3DL2REVERB_QUALITY_DEFAULT 2 + +#undef INTERFACE +#define INTERFACE IDirectSoundFXI3DL2Reverb + +DECLARE_INTERFACE_(IDirectSoundFXI3DL2Reverb, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXI3DL2Reverb methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSFXI3DL2Reverb pcDsFxI3DL2Reverb) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSFXI3DL2Reverb pDsFxI3DL2Reverb) PURE; + STDMETHOD(SetPreset) (THIS_ DWORD dwPreset) PURE; + STDMETHOD(GetPreset) (THIS_ LPDWORD pdwPreset) PURE; + STDMETHOD(SetQuality) (THIS_ LONG lQuality) PURE; + STDMETHOD(GetQuality) (THIS_ LONG *plQuality) PURE; +}; + +#define IDirectSoundFXI3DL2Reverb_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXI3DL2Reverb_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXI3DL2Reverb_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXI3DL2Reverb_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXI3DL2Reverb_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#define IDirectSoundFXI3DL2Reverb_SetPreset(p,a) (p)->lpVtbl->SetPreset(p,a) +#define IDirectSoundFXI3DL2Reverb_GetPreset(p,a) (p)->lpVtbl->GetPreset(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXI3DL2Reverb_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXI3DL2Reverb_GetAllParameters(p,a) (p)->GetAllParameters(a) +#define IDirectSoundFXI3DL2Reverb_SetPreset(p,a) (p)->SetPreset(a) +#define IDirectSoundFXI3DL2Reverb_GetPreset(p,a) (p)->GetPreset(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundFXWavesReverb +// + +DEFINE_GUID(IID_IDirectSoundFXWavesReverb,0x46858c3a,0x0dc6,0x45e3,0xb7,0x60,0xd4,0xee,0xf1,0x6c,0xb3,0x25); + +typedef struct _DSFXWavesReverb +{ + FLOAT fInGain; // [-96.0,0.0] default: 0.0 dB + FLOAT fReverbMix; // [-96.0,0.0] default: 0.0 db + FLOAT fReverbTime; // [0.001,3000.0] default: 1000.0 ms + FLOAT fHighFreqRTRatio; // [0.001,0.999] default: 0.001 +} DSFXWavesReverb, *LPDSFXWavesReverb; + +typedef const DSFXWavesReverb *LPCDSFXWavesReverb; + +#define DSFX_WAVESREVERB_INGAIN_MIN -96.0f +#define DSFX_WAVESREVERB_INGAIN_MAX 0.0f +#define DSFX_WAVESREVERB_INGAIN_DEFAULT 0.0f +#define DSFX_WAVESREVERB_REVERBMIX_MIN -96.0f +#define DSFX_WAVESREVERB_REVERBMIX_MAX 0.0f +#define DSFX_WAVESREVERB_REVERBMIX_DEFAULT 0.0f +#define DSFX_WAVESREVERB_REVERBTIME_MIN 0.001f +#define DSFX_WAVESREVERB_REVERBTIME_MAX 3000.0f +#define DSFX_WAVESREVERB_REVERBTIME_DEFAULT 1000.0f +#define DSFX_WAVESREVERB_HIGHFREQRTRATIO_MIN 0.001f +#define DSFX_WAVESREVERB_HIGHFREQRTRATIO_MAX 0.999f +#define DSFX_WAVESREVERB_HIGHFREQRTRATIO_DEFAULT 0.001f + +#undef INTERFACE +#define INTERFACE IDirectSoundFXWavesReverb + +DECLARE_INTERFACE_(IDirectSoundFXWavesReverb, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFXWavesReverb methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSFXWavesReverb pcDsFxWavesReverb) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSFXWavesReverb pDsFxWavesReverb) PURE; +}; + +#define IDirectSoundFXWavesReverb_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFXWavesReverb_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFXWavesReverb_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXWavesReverb_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundFXWavesReverb_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFXWavesReverb_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundFXWavesReverb_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundCaptureFXAec +// + +DEFINE_GUID(IID_IDirectSoundCaptureFXAec, 0xad74143d, 0x903d, 0x4ab7, 0x80, 0x66, 0x28, 0xd3, 0x63, 0x03, 0x6d, 0x65); + +typedef struct _DSCFXAec +{ + BOOL fEnable; + BOOL fNoiseFill; + DWORD dwMode; +} DSCFXAec, *LPDSCFXAec; + +typedef const DSCFXAec *LPCDSCFXAec; + +// These match the AEC_MODE_* constants in the DDK's ksmedia.h file +#define DSCFX_AEC_MODE_PASS_THROUGH 0x0 +#define DSCFX_AEC_MODE_HALF_DUPLEX 0x1 +#define DSCFX_AEC_MODE_FULL_DUPLEX 0x2 + +// These match the AEC_STATUS_* constants in ksmedia.h +#define DSCFX_AEC_STATUS_HISTORY_UNINITIALIZED 0x0 +#define DSCFX_AEC_STATUS_HISTORY_CONTINUOUSLY_CONVERGED 0x1 +#define DSCFX_AEC_STATUS_HISTORY_PREVIOUSLY_DIVERGED 0x2 +#define DSCFX_AEC_STATUS_CURRENTLY_CONVERGED 0x8 + +#undef INTERFACE +#define INTERFACE IDirectSoundCaptureFXAec + +DECLARE_INTERFACE_(IDirectSoundCaptureFXAec, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCaptureFXAec methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSCFXAec pDscFxAec) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSCFXAec pDscFxAec) PURE; + STDMETHOD(GetStatus) (THIS_ PDWORD pdwStatus) PURE; + STDMETHOD(Reset) (THIS) PURE; +}; + +#define IDirectSoundCaptureFXAec_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundCaptureFXAec_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundCaptureFXAec_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureFXAec_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundCaptureFXAec_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureFXAec_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundCaptureFXAec_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + + +// +// IDirectSoundCaptureFXNoiseSuppress +// + +DEFINE_GUID(IID_IDirectSoundCaptureFXNoiseSuppress, 0xed311e41, 0xfbae, 0x4175, 0x96, 0x25, 0xcd, 0x8, 0x54, 0xf6, 0x93, 0xca); + +typedef struct _DSCFXNoiseSuppress +{ + BOOL fEnable; +} DSCFXNoiseSuppress, *LPDSCFXNoiseSuppress; + +typedef const DSCFXNoiseSuppress *LPCDSCFXNoiseSuppress; + +#undef INTERFACE +#define INTERFACE IDirectSoundCaptureFXNoiseSuppress + +DECLARE_INTERFACE_(IDirectSoundCaptureFXNoiseSuppress, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCaptureFXNoiseSuppress methods + STDMETHOD(SetAllParameters) (THIS_ LPCDSCFXNoiseSuppress pcDscFxNoiseSuppress) PURE; + STDMETHOD(GetAllParameters) (THIS_ LPDSCFXNoiseSuppress pDscFxNoiseSuppress) PURE; + STDMETHOD(Reset) (THIS) PURE; +}; + +#define IDirectSoundCaptureFXNoiseSuppress_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundCaptureFXNoiseSuppress_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundCaptureFXNoiseSuppress_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureFXNoiseSuppress_SetAllParameters(p,a) (p)->lpVtbl->SetAllParameters(p,a) +#define IDirectSoundCaptureFXNoiseSuppress_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureFXNoiseSuppress_SetAllParameters(p,a) (p)->SetAllParameters(a) +#define IDirectSoundCaptureFXNoiseSuppress_GetAllParameters(p,a) (p)->GetAllParameters(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + + +// +// IDirectSoundFullDuplex +// + +#ifndef _IDirectSoundFullDuplex_ +#define _IDirectSoundFullDuplex_ + +#ifdef __cplusplus +// 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined +struct IDirectSoundFullDuplex; +#endif // __cplusplus + +typedef struct IDirectSoundFullDuplex *LPDIRECTSOUNDFULLDUPLEX; + +DEFINE_GUID(IID_IDirectSoundFullDuplex, 0xedcb4c7a, 0xdaab, 0x4216, 0xa4, 0x2e, 0x6c, 0x50, 0x59, 0x6d, 0xdc, 0x1d); + +#undef INTERFACE +#define INTERFACE IDirectSoundFullDuplex + +DECLARE_INTERFACE_(IDirectSoundFullDuplex, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundFullDuplex methods + STDMETHOD(Initialize) (THIS_ LPCGUID pCaptureGuid, LPCGUID pRenderGuid, LPCDSCBUFFERDESC lpDscBufferDesc, LPCDSBUFFERDESC lpDsBufferDesc, HWND hWnd, DWORD dwLevel, LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8, LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8) PURE; +}; + +#define IDirectSoundFullDuplex_QueryInterface(p,a,b) IUnknown_QueryInterface(p,a,b) +#define IDirectSoundFullDuplex_AddRef(p) IUnknown_AddRef(p) +#define IDirectSoundFullDuplex_Release(p) IUnknown_Release(p) + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFullDuplex_Initialize(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->Initialize(p,a,b,c,d,e,f,g,h) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundFullDuplex_Initialize(p,a,b,c,d,e,f,g,h) (p)->Initialize(a,b,c,d,e,f,g,h) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // _IDirectSoundFullDuplex_ + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +// +// Return Codes +// + +// The function completed successfully +#define DS_OK S_OK + +// The call succeeded, but we had to substitute the 3D algorithm +#define DS_NO_VIRTUALIZATION MAKE_HRESULT(0, _FACDS, 10) + +// The call failed because resources (such as a priority level) +// were already being used by another caller +#define DSERR_ALLOCATED MAKE_DSHRESULT(10) + +// The control (vol, pan, etc.) requested by the caller is not available +#define DSERR_CONTROLUNAVAIL MAKE_DSHRESULT(30) + +// An invalid parameter was passed to the returning function +#define DSERR_INVALIDPARAM E_INVALIDARG + +// This call is not valid for the current state of this object +#define DSERR_INVALIDCALL MAKE_DSHRESULT(50) + +// An undetermined error occurred inside the DirectSound subsystem +#define DSERR_GENERIC E_FAIL + +// The caller does not have the priority level required for the function to +// succeed +#define DSERR_PRIOLEVELNEEDED MAKE_DSHRESULT(70) + +// Not enough free memory is available to complete the operation +#define DSERR_OUTOFMEMORY E_OUTOFMEMORY + +// The specified WAVE format is not supported +#define DSERR_BADFORMAT MAKE_DSHRESULT(100) + +// The function called is not supported at this time +#define DSERR_UNSUPPORTED E_NOTIMPL + +// No sound driver is available for use +#define DSERR_NODRIVER MAKE_DSHRESULT(120) +// This object is already initialized +#define DSERR_ALREADYINITIALIZED MAKE_DSHRESULT(130) + +// This object does not support aggregation +#define DSERR_NOAGGREGATION CLASS_E_NOAGGREGATION + +// The buffer memory has been lost, and must be restored +#define DSERR_BUFFERLOST MAKE_DSHRESULT(150) + +// Another app has a higher priority level, preventing this call from +// succeeding +#define DSERR_OTHERAPPHASPRIO MAKE_DSHRESULT(160) + +// This object has not been initialized +#define DSERR_UNINITIALIZED MAKE_DSHRESULT(170) + +// The requested COM interface is not available +#define DSERR_NOINTERFACE E_NOINTERFACE + +// Access is denied +#define DSERR_ACCESSDENIED E_ACCESSDENIED + +// Tried to create a DSBCAPS_CTRLFX buffer shorter than DSBSIZE_FX_MIN milliseconds +#define DSERR_BUFFERTOOSMALL MAKE_DSHRESULT(180) + +// Attempt to use DirectSound 8 functionality on an older DirectSound object +#define DSERR_DS8_REQUIRED MAKE_DSHRESULT(190) + +// A circular loop of send effects was detected +#define DSERR_SENDLOOP MAKE_DSHRESULT(200) + +// The GUID specified in an audiopath file does not match a valid MIXIN buffer +#define DSERR_BADSENDBUFFERGUID MAKE_DSHRESULT(210) + +// The object requested was not found (numerically equal to DMUS_E_NOT_FOUND) +#define DSERR_OBJECTNOTFOUND MAKE_DSHRESULT(4449) + +// The effects requested could not be found on the system, or they were found +// but in the wrong order, or in the wrong hardware/software locations. +#define DSERR_FXUNAVAILABLE MAKE_DSHRESULT(220) + +// +// Flags +// + +#define DSCAPS_PRIMARYMONO 0x00000001 +#define DSCAPS_PRIMARYSTEREO 0x00000002 +#define DSCAPS_PRIMARY8BIT 0x00000004 +#define DSCAPS_PRIMARY16BIT 0x00000008 +#define DSCAPS_CONTINUOUSRATE 0x00000010 +#define DSCAPS_EMULDRIVER 0x00000020 +#define DSCAPS_CERTIFIED 0x00000040 +#define DSCAPS_SECONDARYMONO 0x00000100 +#define DSCAPS_SECONDARYSTEREO 0x00000200 +#define DSCAPS_SECONDARY8BIT 0x00000400 +#define DSCAPS_SECONDARY16BIT 0x00000800 + +#define DSSCL_NORMAL 0x00000001 +#define DSSCL_PRIORITY 0x00000002 +#define DSSCL_EXCLUSIVE 0x00000003 +#define DSSCL_WRITEPRIMARY 0x00000004 + +#define DSSPEAKER_DIRECTOUT 0x00000000 +#define DSSPEAKER_HEADPHONE 0x00000001 +#define DSSPEAKER_MONO 0x00000002 +#define DSSPEAKER_QUAD 0x00000003 +#define DSSPEAKER_STEREO 0x00000004 +#define DSSPEAKER_SURROUND 0x00000005 +#define DSSPEAKER_5POINT1 0x00000006 // obsolete 5.1 setting +#define DSSPEAKER_7POINT1 0x00000007 // obsolete 7.1 setting +#define DSSPEAKER_7POINT1_SURROUND 0x00000008 // correct 7.1 Home Theater setting +#define DSSPEAKER_7POINT1_WIDE DSSPEAKER_7POINT1 +#if (DIRECTSOUND_VERSION >= 0x1000) + #define DSSPEAKER_5POINT1_SURROUND 0x00000009 // correct 5.1 setting + #define DSSPEAKER_5POINT1_BACK DSSPEAKER_5POINT1 +#endif + +#define DSSPEAKER_GEOMETRY_MIN 0x00000005 // 5 degrees +#define DSSPEAKER_GEOMETRY_NARROW 0x0000000A // 10 degrees +#define DSSPEAKER_GEOMETRY_WIDE 0x00000014 // 20 degrees +#define DSSPEAKER_GEOMETRY_MAX 0x000000B4 // 180 degrees + +#define DSSPEAKER_COMBINED(c, g) ((DWORD)(((BYTE)(c)) | ((DWORD)((BYTE)(g))) << 16)) +#define DSSPEAKER_CONFIG(a) ((BYTE)(a)) +#define DSSPEAKER_GEOMETRY(a) ((BYTE)(((DWORD)(a) >> 16) & 0x00FF)) + +#define DSBCAPS_PRIMARYBUFFER 0x00000001 +#define DSBCAPS_STATIC 0x00000002 +#define DSBCAPS_LOCHARDWARE 0x00000004 +#define DSBCAPS_LOCSOFTWARE 0x00000008 +#define DSBCAPS_CTRL3D 0x00000010 +#define DSBCAPS_CTRLFREQUENCY 0x00000020 +#define DSBCAPS_CTRLPAN 0x00000040 +#define DSBCAPS_CTRLVOLUME 0x00000080 +#define DSBCAPS_CTRLPOSITIONNOTIFY 0x00000100 +#define DSBCAPS_CTRLFX 0x00000200 +#define DSBCAPS_STICKYFOCUS 0x00004000 +#define DSBCAPS_GLOBALFOCUS 0x00008000 +#define DSBCAPS_GETCURRENTPOSITION2 0x00010000 +#define DSBCAPS_MUTE3DATMAXDISTANCE 0x00020000 +#define DSBCAPS_LOCDEFER 0x00040000 +#if (DIRECTSOUND_VERSION >= 0x1000) + // Force GetCurrentPosition() to return a buffer's true play position; + // unmodified by aids to enhance backward compatibility. + #define DSBCAPS_TRUEPLAYPOSITION 0x00080000 +#endif + +#define DSBPLAY_LOOPING 0x00000001 +#define DSBPLAY_LOCHARDWARE 0x00000002 +#define DSBPLAY_LOCSOFTWARE 0x00000004 +#define DSBPLAY_TERMINATEBY_TIME 0x00000008 +#define DSBPLAY_TERMINATEBY_DISTANCE 0x000000010 +#define DSBPLAY_TERMINATEBY_PRIORITY 0x000000020 + +#define DSBSTATUS_PLAYING 0x00000001 +#define DSBSTATUS_BUFFERLOST 0x00000002 +#define DSBSTATUS_LOOPING 0x00000004 +#define DSBSTATUS_LOCHARDWARE 0x00000008 +#define DSBSTATUS_LOCSOFTWARE 0x00000010 +#define DSBSTATUS_TERMINATED 0x00000020 + +#define DSBLOCK_FROMWRITECURSOR 0x00000001 +#define DSBLOCK_ENTIREBUFFER 0x00000002 + +#define DSBFREQUENCY_ORIGINAL 0 +#define DSBFREQUENCY_MIN 100 +#if DIRECTSOUND_VERSION >= 0x0900 +#define DSBFREQUENCY_MAX 200000 +#else +#define DSBFREQUENCY_MAX 100000 +#endif + +#define DSBPAN_LEFT -10000 +#define DSBPAN_CENTER 0 +#define DSBPAN_RIGHT 10000 + +#define DSBVOLUME_MIN -10000 +#define DSBVOLUME_MAX 0 + +#define DSBSIZE_MIN 4 +#define DSBSIZE_MAX 0x0FFFFFFF +#define DSBSIZE_FX_MIN 150 // NOTE: Milliseconds, not bytes + +#define DSBNOTIFICATIONS_MAX 100000UL + +#define DS3DMODE_NORMAL 0x00000000 +#define DS3DMODE_HEADRELATIVE 0x00000001 +#define DS3DMODE_DISABLE 0x00000002 + +#define DS3D_IMMEDIATE 0x00000000 +#define DS3D_DEFERRED 0x00000001 + +#define DS3D_MINDISTANCEFACTOR FLT_MIN +#define DS3D_MAXDISTANCEFACTOR FLT_MAX +#define DS3D_DEFAULTDISTANCEFACTOR 1.0f + +#define DS3D_MINROLLOFFFACTOR 0.0f +#define DS3D_MAXROLLOFFFACTOR 10.0f +#define DS3D_DEFAULTROLLOFFFACTOR 1.0f + +#define DS3D_MINDOPPLERFACTOR 0.0f +#define DS3D_MAXDOPPLERFACTOR 10.0f +#define DS3D_DEFAULTDOPPLERFACTOR 1.0f + +#define DS3D_DEFAULTMINDISTANCE 1.0f +#define DS3D_DEFAULTMAXDISTANCE 1000000000.0f + +#define DS3D_MINCONEANGLE 0 +#define DS3D_MAXCONEANGLE 360 +#define DS3D_DEFAULTCONEANGLE 360 + +#define DS3D_DEFAULTCONEOUTSIDEVOLUME DSBVOLUME_MAX + +// IDirectSoundCapture attributes + +#define DSCCAPS_EMULDRIVER DSCAPS_EMULDRIVER +#define DSCCAPS_CERTIFIED DSCAPS_CERTIFIED +#define DSCCAPS_MULTIPLECAPTURE 0x00000001 + +// IDirectSoundCaptureBuffer attributes + +#define DSCBCAPS_WAVEMAPPED 0x80000000 + +#if DIRECTSOUND_VERSION >= 0x0800 +#define DSCBCAPS_CTRLFX 0x00000200 +#endif + + +#define DSCBLOCK_ENTIREBUFFER 0x00000001 + +#define DSCBSTATUS_CAPTURING 0x00000001 +#define DSCBSTATUS_LOOPING 0x00000002 + +#define DSCBSTART_LOOPING 0x00000001 + +#define DSBPN_OFFSETSTOP 0xFFFFFFFF + +#define DS_CERTIFIED 0x00000000 +#define DS_UNCERTIFIED 0x00000001 + + +// +// Flags for the I3DL2 effects +// + +// +// I3DL2 Material Presets +// + +enum +{ + DSFX_I3DL2_MATERIAL_PRESET_SINGLEWINDOW, + DSFX_I3DL2_MATERIAL_PRESET_DOUBLEWINDOW, + DSFX_I3DL2_MATERIAL_PRESET_THINDOOR, + DSFX_I3DL2_MATERIAL_PRESET_THICKDOOR, + DSFX_I3DL2_MATERIAL_PRESET_WOODWALL, + DSFX_I3DL2_MATERIAL_PRESET_BRICKWALL, + DSFX_I3DL2_MATERIAL_PRESET_STONEWALL, + DSFX_I3DL2_MATERIAL_PRESET_CURTAIN +}; + +#define I3DL2_MATERIAL_PRESET_SINGLEWINDOW -2800,0.71f +#define I3DL2_MATERIAL_PRESET_DOUBLEWINDOW -5000,0.40f +#define I3DL2_MATERIAL_PRESET_THINDOOR -1800,0.66f +#define I3DL2_MATERIAL_PRESET_THICKDOOR -4400,0.64f +#define I3DL2_MATERIAL_PRESET_WOODWALL -4000,0.50f +#define I3DL2_MATERIAL_PRESET_BRICKWALL -5000,0.60f +#define I3DL2_MATERIAL_PRESET_STONEWALL -6000,0.68f +#define I3DL2_MATERIAL_PRESET_CURTAIN -1200,0.15f + +enum +{ + DSFX_I3DL2_ENVIRONMENT_PRESET_DEFAULT, + DSFX_I3DL2_ENVIRONMENT_PRESET_GENERIC, + DSFX_I3DL2_ENVIRONMENT_PRESET_PADDEDCELL, + DSFX_I3DL2_ENVIRONMENT_PRESET_ROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_BATHROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_LIVINGROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_STONEROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_AUDITORIUM, + DSFX_I3DL2_ENVIRONMENT_PRESET_CONCERTHALL, + DSFX_I3DL2_ENVIRONMENT_PRESET_CAVE, + DSFX_I3DL2_ENVIRONMENT_PRESET_ARENA, + DSFX_I3DL2_ENVIRONMENT_PRESET_HANGAR, + DSFX_I3DL2_ENVIRONMENT_PRESET_CARPETEDHALLWAY, + DSFX_I3DL2_ENVIRONMENT_PRESET_HALLWAY, + DSFX_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR, + DSFX_I3DL2_ENVIRONMENT_PRESET_ALLEY, + DSFX_I3DL2_ENVIRONMENT_PRESET_FOREST, + DSFX_I3DL2_ENVIRONMENT_PRESET_CITY, + DSFX_I3DL2_ENVIRONMENT_PRESET_MOUNTAINS, + DSFX_I3DL2_ENVIRONMENT_PRESET_QUARRY, + DSFX_I3DL2_ENVIRONMENT_PRESET_PLAIN, + DSFX_I3DL2_ENVIRONMENT_PRESET_PARKINGLOT, + DSFX_I3DL2_ENVIRONMENT_PRESET_SEWERPIPE, + DSFX_I3DL2_ENVIRONMENT_PRESET_UNDERWATER, + DSFX_I3DL2_ENVIRONMENT_PRESET_SMALLROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_MEDIUMROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_LARGEROOM, + DSFX_I3DL2_ENVIRONMENT_PRESET_MEDIUMHALL, + DSFX_I3DL2_ENVIRONMENT_PRESET_LARGEHALL, + DSFX_I3DL2_ENVIRONMENT_PRESET_PLATE +}; + +// +// I3DL2 Reverberation Presets Values +// + +#define I3DL2_ENVIRONMENT_PRESET_DEFAULT -1000, -100, 0.0f, 1.49f, 0.83f, -2602, 0.007f, 200, 0.011f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_GENERIC -1000, -100, 0.0f, 1.49f, 0.83f, -2602, 0.007f, 200, 0.011f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_PADDEDCELL -1000,-6000, 0.0f, 0.17f, 0.10f, -1204, 0.001f, 207, 0.002f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_ROOM -1000, -454, 0.0f, 0.40f, 0.83f, -1646, 0.002f, 53, 0.003f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_BATHROOM -1000,-1200, 0.0f, 1.49f, 0.54f, -370, 0.007f, 1030, 0.011f, 100.0f, 60.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_LIVINGROOM -1000,-6000, 0.0f, 0.50f, 0.10f, -1376, 0.003f, -1104, 0.004f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_STONEROOM -1000, -300, 0.0f, 2.31f, 0.64f, -711, 0.012f, 83, 0.017f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_AUDITORIUM -1000, -476, 0.0f, 4.32f, 0.59f, -789, 0.020f, -289, 0.030f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_CONCERTHALL -1000, -500, 0.0f, 3.92f, 0.70f, -1230, 0.020f, -2, 0.029f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_CAVE -1000, 0, 0.0f, 2.91f, 1.30f, -602, 0.015f, -302, 0.022f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_ARENA -1000, -698, 0.0f, 7.24f, 0.33f, -1166, 0.020f, 16, 0.030f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_HANGAR -1000,-1000, 0.0f,10.05f, 0.23f, -602, 0.020f, 198, 0.030f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_CARPETEDHALLWAY -1000,-4000, 0.0f, 0.30f, 0.10f, -1831, 0.002f, -1630, 0.030f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_HALLWAY -1000, -300, 0.0f, 1.49f, 0.59f, -1219, 0.007f, 441, 0.011f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR -1000, -237, 0.0f, 2.70f, 0.79f, -1214, 0.013f, 395, 0.020f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_ALLEY -1000, -270, 0.0f, 1.49f, 0.86f, -1204, 0.007f, -4, 0.011f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_FOREST -1000,-3300, 0.0f, 1.49f, 0.54f, -2560, 0.162f, -613, 0.088f, 79.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_CITY -1000, -800, 0.0f, 1.49f, 0.67f, -2273, 0.007f, -2217, 0.011f, 50.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_MOUNTAINS -1000,-2500, 0.0f, 1.49f, 0.21f, -2780, 0.300f, -2014, 0.100f, 27.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_QUARRY -1000,-1000, 0.0f, 1.49f, 0.83f,-10000, 0.061f, 500, 0.025f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_PLAIN -1000,-2000, 0.0f, 1.49f, 0.50f, -2466, 0.179f, -2514, 0.100f, 21.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_PARKINGLOT -1000, 0, 0.0f, 1.65f, 1.50f, -1363, 0.008f, -1153, 0.012f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_SEWERPIPE -1000,-1000, 0.0f, 2.81f, 0.14f, 429, 0.014f, 648, 0.021f, 80.0f, 60.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_UNDERWATER -1000,-4000, 0.0f, 1.49f, 0.10f, -449, 0.007f, 1700, 0.011f, 100.0f, 100.0f, 5000.0f + +// +// Examples simulating 'musical' reverb presets +// +// Name Decay time Description +// Small Room 1.1s A small size room with a length of 5m or so. +// Medium Room 1.3s A medium size room with a length of 10m or so. +// Large Room 1.5s A large size room suitable for live performances. +// Medium Hall 1.8s A medium size concert hall. +// Large Hall 1.8s A large size concert hall suitable for a full orchestra. +// Plate 1.3s A plate reverb simulation. +// + +#define I3DL2_ENVIRONMENT_PRESET_SMALLROOM -1000, -600, 0.0f, 1.10f, 0.83f, -400, 0.005f, 500, 0.010f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_MEDIUMROOM -1000, -600, 0.0f, 1.30f, 0.83f, -1000, 0.010f, -200, 0.020f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_LARGEROOM -1000, -600, 0.0f, 1.50f, 0.83f, -1600, 0.020f, -1000, 0.040f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_MEDIUMHALL -1000, -600, 0.0f, 1.80f, 0.70f, -1300, 0.015f, -800, 0.030f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_LARGEHALL -1000, -600, 0.0f, 1.80f, 0.70f, -2000, 0.030f, -1400, 0.060f, 100.0f, 100.0f, 5000.0f +#define I3DL2_ENVIRONMENT_PRESET_PLATE -1000, -200, 0.0f, 1.30f, 0.90f, 0, 0.002f, 0, 0.010f, 100.0f, 75.0f, 5000.0f + +// +// DirectSound3D Algorithms +// + +// Default DirectSound3D algorithm {00000000-0000-0000-0000-000000000000} +#define DS3DALG_DEFAULT GUID_NULL + +// No virtualization (Pan3D) {C241333F-1C1B-11d2-94F5-00C04FC28ACA} +DEFINE_GUID(DS3DALG_NO_VIRTUALIZATION, 0xc241333f, 0x1c1b, 0x11d2, 0x94, 0xf5, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); + +// High-quality HRTF algorithm {C2413340-1C1B-11d2-94F5-00C04FC28ACA} +DEFINE_GUID(DS3DALG_HRTF_FULL, 0xc2413340, 0x1c1b, 0x11d2, 0x94, 0xf5, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); + +// Lower-quality HRTF algorithm {C2413342-1C1B-11d2-94F5-00C04FC28ACA} +DEFINE_GUID(DS3DALG_HRTF_LIGHT, 0xc2413342, 0x1c1b, 0x11d2, 0x94, 0xf5, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); + + +#if DIRECTSOUND_VERSION >= 0x0800 + +// +// DirectSound Internal Effect Algorithms +// + + +// Gargle {DAFD8210-5711-4B91-9FE3-F75B7AE279BF} +DEFINE_GUID(GUID_DSFX_STANDARD_GARGLE, 0xdafd8210, 0x5711, 0x4b91, 0x9f, 0xe3, 0xf7, 0x5b, 0x7a, 0xe2, 0x79, 0xbf); + +// Chorus {EFE6629C-81F7-4281-BD91-C9D604A95AF6} +DEFINE_GUID(GUID_DSFX_STANDARD_CHORUS, 0xefe6629c, 0x81f7, 0x4281, 0xbd, 0x91, 0xc9, 0xd6, 0x04, 0xa9, 0x5a, 0xf6); + +// Flanger {EFCA3D92-DFD8-4672-A603-7420894BAD98} +DEFINE_GUID(GUID_DSFX_STANDARD_FLANGER, 0xefca3d92, 0xdfd8, 0x4672, 0xa6, 0x03, 0x74, 0x20, 0x89, 0x4b, 0xad, 0x98); + +// Echo/Delay {EF3E932C-D40B-4F51-8CCF-3F98F1B29D5D} +DEFINE_GUID(GUID_DSFX_STANDARD_ECHO, 0xef3e932c, 0xd40b, 0x4f51, 0x8c, 0xcf, 0x3f, 0x98, 0xf1, 0xb2, 0x9d, 0x5d); + +// Distortion {EF114C90-CD1D-484E-96E5-09CFAF912A21} +DEFINE_GUID(GUID_DSFX_STANDARD_DISTORTION, 0xef114c90, 0xcd1d, 0x484e, 0x96, 0xe5, 0x09, 0xcf, 0xaf, 0x91, 0x2a, 0x21); + +// Compressor/Limiter {EF011F79-4000-406D-87AF-BFFB3FC39D57} +DEFINE_GUID(GUID_DSFX_STANDARD_COMPRESSOR, 0xef011f79, 0x4000, 0x406d, 0x87, 0xaf, 0xbf, 0xfb, 0x3f, 0xc3, 0x9d, 0x57); + +// Parametric Equalization {120CED89-3BF4-4173-A132-3CB406CF3231} +DEFINE_GUID(GUID_DSFX_STANDARD_PARAMEQ, 0x120ced89, 0x3bf4, 0x4173, 0xa1, 0x32, 0x3c, 0xb4, 0x06, 0xcf, 0x32, 0x31); + +// I3DL2 Environmental Reverberation: Reverb (Listener) Effect {EF985E71-D5C7-42D4-BA4D-2D073E2E96F4} +DEFINE_GUID(GUID_DSFX_STANDARD_I3DL2REVERB, 0xef985e71, 0xd5c7, 0x42d4, 0xba, 0x4d, 0x2d, 0x07, 0x3e, 0x2e, 0x96, 0xf4); + +// Waves Reverberation {87FC0268-9A55-4360-95AA-004A1D9DE26C} +DEFINE_GUID(GUID_DSFX_WAVES_REVERB, 0x87fc0268, 0x9a55, 0x4360, 0x95, 0xaa, 0x00, 0x4a, 0x1d, 0x9d, 0xe2, 0x6c); + +// +// DirectSound Capture Effect Algorithms +// + + +// Acoustic Echo Canceller {BF963D80-C559-11D0-8A2B-00A0C9255AC1} +// Matches KSNODETYPE_ACOUSTIC_ECHO_CANCEL in ksmedia.h +DEFINE_GUID(GUID_DSCFX_CLASS_AEC, 0xBF963D80L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1); + +// Microsoft AEC {CDEBB919-379A-488a-8765-F53CFD36DE40} +DEFINE_GUID(GUID_DSCFX_MS_AEC, 0xcdebb919, 0x379a, 0x488a, 0x87, 0x65, 0xf5, 0x3c, 0xfd, 0x36, 0xde, 0x40); + +// System AEC {1C22C56D-9879-4f5b-A389-27996DDC2810} +DEFINE_GUID(GUID_DSCFX_SYSTEM_AEC, 0x1c22c56d, 0x9879, 0x4f5b, 0xa3, 0x89, 0x27, 0x99, 0x6d, 0xdc, 0x28, 0x10); + +// Noise Supression {E07F903F-62FD-4e60-8CDD-DEA7236665B5} +// Matches KSNODETYPE_NOISE_SUPPRESS in post Windows ME DDK's ksmedia.h +DEFINE_GUID(GUID_DSCFX_CLASS_NS, 0xe07f903f, 0x62fd, 0x4e60, 0x8c, 0xdd, 0xde, 0xa7, 0x23, 0x66, 0x65, 0xb5); + +// Microsoft Noise Suppresion {11C5C73B-66E9-4ba1-A0BA-E814C6EED92D} +DEFINE_GUID(GUID_DSCFX_MS_NS, 0x11c5c73b, 0x66e9, 0x4ba1, 0xa0, 0xba, 0xe8, 0x14, 0xc6, 0xee, 0xd9, 0x2d); + +// System Noise Suppresion {5AB0882E-7274-4516-877D-4EEE99BA4FD0} +DEFINE_GUID(GUID_DSCFX_SYSTEM_NS, 0x5ab0882e, 0x7274, 0x4516, 0x87, 0x7d, 0x4e, 0xee, 0x99, 0xba, 0x4f, 0xd0); + +#endif // DIRECTSOUND_VERSION >= 0x0800 + +#endif // __DSOUND_INCLUDED__ + + + +#ifdef __cplusplus +}; +#endif // __cplusplus + diff --git a/include/ginclude.h b/include/ginclude.h new file mode 100644 index 0000000..b627dc2 --- /dev/null +++ b/include/ginclude.h @@ -0,0 +1,38 @@ +#ifndef __gInclude__ +#define __gInclude__ + +#if SGI + #undef BEOS + #undef MAC + #undef WINDOWS + // + #define ASIO_BIG_ENDIAN 1 + #define ASIO_CPU_MIPS 1 +#elif defined WIN32 + #undef BEOS + #undef MAC + #undef SGI + #define WINDOWS 1 + #define ASIO_LITTLE_ENDIAN 1 + #define ASIO_CPU_X86 1 +#elif BEOS + #undef MAC + #undef SGI + #undef WINDOWS + #define ASIO_LITTLE_ENDIAN 1 + #define ASIO_CPU_X86 1 + // +#else + #define MAC 1 + #undef BEOS + #undef WINDOWS + #undef SGI + #define ASIO_BIG_ENDIAN 1 + #define ASIO_CPU_PPC 1 +#endif + +// always +#define NATIVE_INT64 0 +#define IEEE754_64FLOAT 1 + +#endif // __gInclude__ diff --git a/include/iasiodrv.h b/include/iasiodrv.h new file mode 100644 index 0000000..64d2dbb --- /dev/null +++ b/include/iasiodrv.h @@ -0,0 +1,37 @@ +#include "asiosys.h" +#include "asio.h" + +/* Forward Declarations */ + +#ifndef __ASIODRIVER_FWD_DEFINED__ +#define __ASIODRIVER_FWD_DEFINED__ +typedef interface IASIO IASIO; +#endif /* __ASIODRIVER_FWD_DEFINED__ */ + +interface IASIO : public IUnknown +{ + + virtual ASIOBool init(void *sysHandle) = 0; + virtual void getDriverName(char *name) = 0; + virtual long getDriverVersion() = 0; + virtual void getErrorMessage(char *string) = 0; + virtual ASIOError start() = 0; + virtual ASIOError stop() = 0; + virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0; + virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0; + virtual ASIOError getBufferSize(long *minSize, long *maxSize, + long *preferredSize, long *granularity) = 0; + virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0; + virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0; + virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0; + virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0; + virtual ASIOError setClockSource(long reference) = 0; + virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0; + virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0; + virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, + long bufferSize, ASIOCallbacks *callbacks) = 0; + virtual ASIOError disposeBuffers() = 0; + virtual ASIOError controlPanel() = 0; + virtual ASIOError future(long selector,void *opt) = 0; + virtual ASIOError outputReady() = 0; +}; diff --git a/include/iasiothiscallresolver.cpp b/include/iasiothiscallresolver.cpp new file mode 100644 index 0000000..38c39d2 --- /dev/null +++ b/include/iasiothiscallresolver.cpp @@ -0,0 +1,563 @@ +/* + IASIOThiscallResolver.cpp see the comments in iasiothiscallresolver.h for + the top level description - this comment describes the technical details of + the implementation. + + The latest version of this file is available from: + http://www.audiomulch.com/~rossb/code/calliasio + + please email comments to Ross Bencina + + BACKGROUND + + The IASIO interface declared in the Steinberg ASIO 2 SDK declares + functions with no explicit calling convention. This causes MSVC++ to default + to using the thiscall convention, which is a proprietary convention not + implemented by some non-microsoft compilers - notably borland BCC, + C++Builder, and gcc. MSVC++ is the defacto standard compiler used by + Steinberg. As a result of this situation, the ASIO sdk will compile with + any compiler, however attempting to execute the compiled code will cause a + crash due to different default calling conventions on non-Microsoft + compilers. + + IASIOThiscallResolver solves the problem by providing an adapter class that + delegates to the IASIO interface using the correct calling convention + (thiscall). Due to the lack of support for thiscall in the Borland and GCC + compilers, the calls have been implemented in assembly language. + + A number of macros are defined for thiscall function calls with different + numbers of parameters, with and without return values - it may be possible + to modify the format of these macros to make them work with other inline + assemblers. + + + THISCALL DEFINITION + + A number of definitions of the thiscall calling convention are floating + around the internet. The following definition has been validated against + output from the MSVC++ compiler: + + For non-vararg functions, thiscall works as follows: the object (this) + pointer is passed in ECX. All arguments are passed on the stack in + right to left order. The return value is placed in EAX. The callee + clears the passed arguments from the stack. + + + FINDING FUNCTION POINTERS FROM AN IASIO POINTER + + The first field of a COM object is a pointer to its vtble. Thus a pointer + to an object implementing the IASIO interface also points to a pointer to + that object's vtbl. The vtble is a table of function pointers for all of + the virtual functions exposed by the implemented interfaces. + + If we consider a variable declared as a pointer to IASO: + + IASIO *theAsioDriver + + theAsioDriver points to: + + object implementing IASIO + { + IASIOvtbl *vtbl + other data + } + + in other words, theAsioDriver points to a pointer to an IASIOvtbl + + vtbl points to a table of function pointers: + + IASIOvtbl ( interface IASIO : public IUnknown ) + { + (IUnknown functions) + 0 virtual HRESULT STDMETHODCALLTYPE (*QueryInterface)(REFIID riid, void **ppv) = 0; + 4 virtual ULONG STDMETHODCALLTYPE (*AddRef)() = 0; + 8 virtual ULONG STDMETHODCALLTYPE (*Release)() = 0; + + (IASIO functions) + 12 virtual ASIOBool (*init)(void *sysHandle) = 0; + 16 virtual void (*getDriverName)(char *name) = 0; + 20 virtual long (*getDriverVersion)() = 0; + 24 virtual void (*getErrorMessage)(char *string) = 0; + 28 virtual ASIOError (*start)() = 0; + 32 virtual ASIOError (*stop)() = 0; + 36 virtual ASIOError (*getChannels)(long *numInputChannels, long *numOutputChannels) = 0; + 40 virtual ASIOError (*getLatencies)(long *inputLatency, long *outputLatency) = 0; + 44 virtual ASIOError (*getBufferSize)(long *minSize, long *maxSize, + long *preferredSize, long *granularity) = 0; + 48 virtual ASIOError (*canSampleRate)(ASIOSampleRate sampleRate) = 0; + 52 virtual ASIOError (*getSampleRate)(ASIOSampleRate *sampleRate) = 0; + 56 virtual ASIOError (*setSampleRate)(ASIOSampleRate sampleRate) = 0; + 60 virtual ASIOError (*getClockSources)(ASIOClockSource *clocks, long *numSources) = 0; + 64 virtual ASIOError (*setClockSource)(long reference) = 0; + 68 virtual ASIOError (*getSamplePosition)(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0; + 72 virtual ASIOError (*getChannelInfo)(ASIOChannelInfo *info) = 0; + 76 virtual ASIOError (*createBuffers)(ASIOBufferInfo *bufferInfos, long numChannels, + long bufferSize, ASIOCallbacks *callbacks) = 0; + 80 virtual ASIOError (*disposeBuffers)() = 0; + 84 virtual ASIOError (*controlPanel)() = 0; + 88 virtual ASIOError (*future)(long selector,void *opt) = 0; + 92 virtual ASIOError (*outputReady)() = 0; + }; + + The numbers in the left column show the byte offset of each function ptr + from the beginning of the vtbl. These numbers are used in the code below + to select different functions. + + In order to find the address of a particular function, theAsioDriver + must first be dereferenced to find the value of the vtbl pointer: + + mov eax, theAsioDriver + mov edx, [theAsioDriver] // edx now points to vtbl[0] + + Then an offset must be added to the vtbl pointer to select a + particular function, for example vtbl+44 points to the slot containing + a pointer to the getBufferSize function. + + Finally vtbl+x must be dereferenced to obtain the value of the function + pointer stored in that address: + + call [edx+44] // call the function pointed to by + // the value in the getBufferSize field of the vtbl + + + SEE ALSO + + Martin Fay's OpenASIO DLL at http://www.martinfay.com solves the same + problem by providing a new COM interface which wraps IASIO with an + interface that uses portable calling conventions. OpenASIO must be compiled + with MSVC, and requires that you ship the OpenASIO DLL with your + application. + + + ACKNOWLEDGEMENTS + + Ross Bencina: worked out the thiscall details above, wrote the original + Borland asm macros, and a patch for asio.cpp (which is no longer needed). + Thanks to Martin Fay for introducing me to the issues discussed here, + and to Rene G. Ceballos for assisting with asm dumps from MSVC++. + + Antti Silvast: converted the original calliasio to work with gcc and NASM + by implementing the asm code in a separate file. + + Fraser Adams: modified the original calliasio containing the Borland inline + asm to add inline asm for gcc i.e. Intel syntax for Borland and AT&T syntax + for gcc. This seems a neater approach for gcc than to have a separate .asm + file and it means that we only need one version of the thiscall patch. + + Fraser Adams: rewrote the original calliasio patch in the form of the + IASIOThiscallResolver class in order to avoid modifications to files from + the Steinberg SDK, which may have had potential licence issues. + + Andrew Baldwin: contributed fixes for compatibility problems with more + recent versions of the gcc assembler. +*/ + + +// We only need IASIOThiscallResolver at all if we are on Win32. For other +// platforms we simply bypass the IASIOThiscallResolver definition to allow us +// to be safely #include'd whatever the platform to keep client code portable +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + + +// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver +// is not used. +#if !defined(_MSC_VER) + + +#include +#include + +// We have a mechanism in iasiothiscallresolver.h to ensure that asio.h is +// #include'd before it in client code, we do NOT want to do this test here. +#define iasiothiscallresolver_sourcefile 1 +#include "iasiothiscallresolver.h" +#undef iasiothiscallresolver_sourcefile + +// iasiothiscallresolver.h redefines ASIOInit for clients, but we don't want +// this macro defined in this translation unit. +#undef ASIOInit + + +// theAsioDriver is a global pointer to the current IASIO instance which the +// ASIO SDK uses to perform all actions on the IASIO interface. We substitute +// our own forwarding interface into this pointer. +extern IASIO* theAsioDriver; + + +// The following macros define the inline assembler for BORLAND first then gcc + +#if defined(__BCPLUSPLUS__) || defined(__BORLANDC__) + + +#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )\ + void *this_ = (thisPtr); \ + __asm { \ + mov ecx, this_ ; \ + mov eax, [ecx] ; \ + call [eax+funcOffset] ; \ + mov resultName, eax ; \ + } + + +#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )\ + void *this_ = (thisPtr); \ + __asm { \ + mov eax, param1 ; \ + push eax ; \ + mov ecx, this_ ; \ + mov eax, [ecx] ; \ + call [eax+funcOffset] ; \ + } + + +#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )\ + void *this_ = (thisPtr); \ + __asm { \ + mov eax, param1 ; \ + push eax ; \ + mov ecx, this_ ; \ + mov eax, [ecx] ; \ + call [eax+funcOffset] ; \ + mov resultName, eax ; \ + } + + +#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )\ + void *this_ = (thisPtr); \ + void *doubleParamPtr_ (¶m1); \ + __asm { \ + mov eax, doubleParamPtr_ ; \ + push [eax+4] ; \ + push [eax] ; \ + mov ecx, this_ ; \ + mov eax, [ecx] ; \ + call [eax+funcOffset] ; \ + mov resultName, eax ; \ + } + + +#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )\ + void *this_ = (thisPtr); \ + __asm { \ + mov eax, param2 ; \ + push eax ; \ + mov eax, param1 ; \ + push eax ; \ + mov ecx, this_ ; \ + mov eax, [ecx] ; \ + call [eax+funcOffset] ; \ + mov resultName, eax ; \ + } + + +#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\ + void *this_ = (thisPtr); \ + __asm { \ + mov eax, param4 ; \ + push eax ; \ + mov eax, param3 ; \ + push eax ; \ + mov eax, param2 ; \ + push eax ; \ + mov eax, param1 ; \ + push eax ; \ + mov ecx, this_ ; \ + mov eax, [ecx] ; \ + call [eax+funcOffset] ; \ + mov resultName, eax ; \ + } + + +#elif defined(__GNUC__) + + +#define CALL_THISCALL_0( resultName, thisPtr, funcOffset ) \ + __asm__ __volatile__ ("movl (%1), %%edx\n\t" \ + "call *"#funcOffset"(%%edx)\n\t" \ + :"=a"(resultName) /* Output Operands */ \ + :"c"(thisPtr) /* Input Operands */ \ + ); \ + + +#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 ) \ + __asm__ __volatile__ ("pushl %0\n\t" \ + "movl (%1), %%edx\n\t" \ + "call *"#funcOffset"(%%edx)\n\t" \ + : /* Output Operands */ \ + :"r"(param1), /* Input Operands */ \ + "c"(thisPtr) \ + ); \ + + +#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 ) \ + __asm__ __volatile__ ("pushl %1\n\t" \ + "movl (%2), %%edx\n\t" \ + "call *"#funcOffset"(%%edx)\n\t" \ + :"=a"(resultName) /* Output Operands */ \ + :"r"(param1), /* Input Operands */ \ + "c"(thisPtr) \ + ); \ + + +#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 ) \ + __asm__ __volatile__ ("pushl 4(%1)\n\t" \ + "pushl (%1)\n\t" \ + "movl (%2), %%edx\n\t" \ + "call *"#funcOffset"(%%edx);\n\t" \ + :"=a"(resultName) /* Output Operands */ \ + :"a"(¶m1), /* Input Operands */ \ + /* Note: Using "r" above instead of "a" fails */ \ + /* when using GCC 3.3.3, and maybe later versions*/\ + "c"(thisPtr) \ + ); \ + + +#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 ) \ + __asm__ __volatile__ ("pushl %1\n\t" \ + "pushl %2\n\t" \ + "movl (%3), %%edx\n\t" \ + "call *"#funcOffset"(%%edx)\n\t" \ + :"=a"(resultName) /* Output Operands */ \ + :"r"(param2), /* Input Operands */ \ + "r"(param1), \ + "c"(thisPtr) \ + ); \ + + +#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\ + __asm__ __volatile__ ("pushl %1\n\t" \ + "pushl %2\n\t" \ + "pushl %3\n\t" \ + "pushl %4\n\t" \ + "movl (%5), %%edx\n\t" \ + "call *"#funcOffset"(%%edx)\n\t" \ + :"=a"(resultName) /* Output Operands */ \ + :"r"(param4), /* Input Operands */ \ + "r"(param3), \ + "r"(param2), \ + "r"(param1), \ + "c"(thisPtr) \ + ); \ + +#endif + + + +// Our static singleton instance. +IASIOThiscallResolver IASIOThiscallResolver::instance; + +// Constructor called to initialize static Singleton instance above. Note that +// it is important not to clear that_ incase it has already been set by the call +// to placement new in ASIOInit(). +IASIOThiscallResolver::IASIOThiscallResolver() +{ +} + +// Constructor called from ASIOInit() below +IASIOThiscallResolver::IASIOThiscallResolver(IASIO* that) +: that_( that ) +{ +} + +// Implement IUnknown methods as assert(false). IASIOThiscallResolver is not +// really a COM object, just a wrapper which will work with the ASIO SDK. +// If you wanted to use ASIO without the SDK you might want to implement COM +// aggregation in these methods. +HRESULT STDMETHODCALLTYPE IASIOThiscallResolver::QueryInterface(REFIID riid, void **ppv) +{ + (void)riid; // suppress unused variable warning + + assert( false ); // this function should never be called by the ASIO SDK. + + *ppv = NULL; + return E_NOINTERFACE; +} + +ULONG STDMETHODCALLTYPE IASIOThiscallResolver::AddRef() +{ + assert( false ); // this function should never be called by the ASIO SDK. + + return 1; +} + +ULONG STDMETHODCALLTYPE IASIOThiscallResolver::Release() +{ + assert( false ); // this function should never be called by the ASIO SDK. + + return 1; +} + + +// Implement the IASIO interface methods by performing the vptr manipulation +// described above then delegating to the real implementation. +ASIOBool IASIOThiscallResolver::init(void *sysHandle) +{ + ASIOBool result; + CALL_THISCALL_1( result, that_, 12, sysHandle ); + return result; +} + +void IASIOThiscallResolver::getDriverName(char *name) +{ + CALL_VOID_THISCALL_1( that_, 16, name ); +} + +long IASIOThiscallResolver::getDriverVersion() +{ + ASIOBool result; + CALL_THISCALL_0( result, that_, 20 ); + return result; +} + +void IASIOThiscallResolver::getErrorMessage(char *string) +{ + CALL_VOID_THISCALL_1( that_, 24, string ); +} + +ASIOError IASIOThiscallResolver::start() +{ + ASIOBool result; + CALL_THISCALL_0( result, that_, 28 ); + return result; +} + +ASIOError IASIOThiscallResolver::stop() +{ + ASIOBool result; + CALL_THISCALL_0( result, that_, 32 ); + return result; +} + +ASIOError IASIOThiscallResolver::getChannels(long *numInputChannels, long *numOutputChannels) +{ + ASIOBool result; + CALL_THISCALL_2( result, that_, 36, numInputChannels, numOutputChannels ); + return result; +} + +ASIOError IASIOThiscallResolver::getLatencies(long *inputLatency, long *outputLatency) +{ + ASIOBool result; + CALL_THISCALL_2( result, that_, 40, inputLatency, outputLatency ); + return result; +} + +ASIOError IASIOThiscallResolver::getBufferSize(long *minSize, long *maxSize, + long *preferredSize, long *granularity) +{ + ASIOBool result; + CALL_THISCALL_4( result, that_, 44, minSize, maxSize, preferredSize, granularity ); + return result; +} + +ASIOError IASIOThiscallResolver::canSampleRate(ASIOSampleRate sampleRate) +{ + ASIOBool result; + CALL_THISCALL_1_DOUBLE( result, that_, 48, sampleRate ); + return result; +} + +ASIOError IASIOThiscallResolver::getSampleRate(ASIOSampleRate *sampleRate) +{ + ASIOBool result; + CALL_THISCALL_1( result, that_, 52, sampleRate ); + return result; +} + +ASIOError IASIOThiscallResolver::setSampleRate(ASIOSampleRate sampleRate) +{ + ASIOBool result; + CALL_THISCALL_1_DOUBLE( result, that_, 56, sampleRate ); + return result; +} + +ASIOError IASIOThiscallResolver::getClockSources(ASIOClockSource *clocks, long *numSources) +{ + ASIOBool result; + CALL_THISCALL_2( result, that_, 60, clocks, numSources ); + return result; +} + +ASIOError IASIOThiscallResolver::setClockSource(long reference) +{ + ASIOBool result; + CALL_THISCALL_1( result, that_, 64, reference ); + return result; +} + +ASIOError IASIOThiscallResolver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) +{ + ASIOBool result; + CALL_THISCALL_2( result, that_, 68, sPos, tStamp ); + return result; +} + +ASIOError IASIOThiscallResolver::getChannelInfo(ASIOChannelInfo *info) +{ + ASIOBool result; + CALL_THISCALL_1( result, that_, 72, info ); + return result; +} + +ASIOError IASIOThiscallResolver::createBuffers(ASIOBufferInfo *bufferInfos, + long numChannels, long bufferSize, ASIOCallbacks *callbacks) +{ + ASIOBool result; + CALL_THISCALL_4( result, that_, 76, bufferInfos, numChannels, bufferSize, callbacks ); + return result; +} + +ASIOError IASIOThiscallResolver::disposeBuffers() +{ + ASIOBool result; + CALL_THISCALL_0( result, that_, 80 ); + return result; +} + +ASIOError IASIOThiscallResolver::controlPanel() +{ + ASIOBool result; + CALL_THISCALL_0( result, that_, 84 ); + return result; +} + +ASIOError IASIOThiscallResolver::future(long selector,void *opt) +{ + ASIOBool result; + CALL_THISCALL_2( result, that_, 88, selector, opt ); + return result; +} + +ASIOError IASIOThiscallResolver::outputReady() +{ + ASIOBool result; + CALL_THISCALL_0( result, that_, 92 ); + return result; +} + + +// Implement our substitute ASIOInit() method +ASIOError IASIOThiscallResolver::ASIOInit(ASIODriverInfo *info) +{ + // To ensure that our instance's vptr is correctly constructed, even if + // ASIOInit is called prior to main(), we explicitly call its constructor + // (potentially over the top of an existing instance). Note that this is + // pretty ugly, and is only safe because IASIOThiscallResolver has no + // destructor and contains no objects with destructors. + new((void*)&instance) IASIOThiscallResolver( theAsioDriver ); + + // Interpose between ASIO client code and the real driver. + theAsioDriver = &instance; + + // Note that we never need to switch theAsioDriver back to point to the + // real driver because theAsioDriver is reset to zero in ASIOExit(). + + // Delegate to the real ASIOInit + return ::ASIOInit(info); +} + + +#endif /* !defined(_MSC_VER) */ + +#endif /* Win32 */ + diff --git a/include/iasiothiscallresolver.h b/include/iasiothiscallresolver.h new file mode 100644 index 0000000..b59d910 --- /dev/null +++ b/include/iasiothiscallresolver.h @@ -0,0 +1,201 @@ +// **************************************************************************** +// +// Changed: I have modified this file slightly (includes) to work with +// RtAudio. RtAudio.cpp must include this file after asio.h. +// +// File: IASIOThiscallResolver.h +// Description: The IASIOThiscallResolver class implements the IASIO +// interface and acts as a proxy to the real IASIO interface by +// calling through its vptr table using the thiscall calling +// convention. To put it another way, we interpose +// IASIOThiscallResolver between ASIO SDK code and the driver. +// This is necessary because most non-Microsoft compilers don't +// implement the thiscall calling convention used by IASIO. +// +// iasiothiscallresolver.cpp contains the background of this +// problem plus a technical description of the vptr +// manipulations. +// +// In order to use this mechanism one simply has to add +// iasiothiscallresolver.cpp to the list of files to compile +// and #include +// +// Note that this #include must come after the other ASIO SDK +// #includes, for example: +// +// #include +// #include +// #include +// #include +// #include +// +// Actually the important thing is to #include +// after . We have +// incorporated a test to enforce this ordering. +// +// The code transparently takes care of the interposition by +// using macro substitution to intercept calls to ASIOInit() +// and ASIOExit(). We save the original ASIO global +// "theAsioDriver" in our "that" variable, and then set +// "theAsioDriver" to equal our IASIOThiscallResolver instance. +// +// Whilst this method of resolving the thiscall problem requires +// the addition of #include to client +// code it has the advantage that it does not break the terms +// of the ASIO licence by publishing it. We are NOT modifying +// any Steinberg code here, we are merely implementing the IASIO +// interface in the same way that we would need to do if we +// wished to provide an open source ASIO driver. +// +// For compilation with MinGW -lole32 needs to be added to the +// linker options. For BORLAND, linking with Import32.lib is +// sufficient. +// +// The dependencies are with: CoInitialize, CoUninitialize, +// CoCreateInstance, CLSIDFromString - used by asiolist.cpp +// and are required on Windows whether ThiscallResolver is used +// or not. +// +// Searching for the above strings in the root library path +// of your compiler should enable the correct libraries to be +// identified if they aren't immediately obvious. +// +// Note that the current implementation of IASIOThiscallResolver +// is not COM compliant - it does not correctly implement the +// IUnknown interface. Implementing it is not necessary because +// it is not called by parts of the ASIO SDK which call through +// theAsioDriver ptr. The IUnknown methods are implemented as +// assert(false) to ensure that the code fails if they are +// ever called. +// Restrictions: None. Public Domain & Open Source distribute freely +// You may use IASIOThiscallResolver commercially as well as +// privately. +// You the user assume the responsibility for the use of the +// files, binary or text, and there is no guarantee or warranty, +// expressed or implied, including but not limited to the +// implied warranties of merchantability and fitness for a +// particular purpose. You assume all responsibility and agree +// to hold no entity, copyright holder or distributors liable +// for any loss of data or inaccurate representations of data +// as a result of using IASIOThiscallResolver. +// Version: 1.4 Added separate macro CALL_THISCALL_1_DOUBLE from +// Andrew Baldwin, and volatile for whole gcc asm blocks, +// both for compatibility with newer gcc versions. Cleaned up +// Borland asm to use one less register. +// 1.3 Switched to including assert.h for better compatibility. +// Wrapped entire .h and .cpp contents with a check for +// _MSC_VER to provide better compatibility with MS compilers. +// Changed Singleton implementation to use static instance +// instead of freestore allocated instance. Removed ASIOExit +// macro as it is no longer needed. +// 1.2 Removed semicolons from ASIOInit and ASIOExit macros to +// allow them to be embedded in expressions (if statements). +// Cleaned up some comments. Removed combase.c dependency (it +// doesn't compile with BCB anyway) by stubbing IUnknown. +// 1.1 Incorporated comments from Ross Bencina including things +// such as changing name from ThiscallResolver to +// IASIOThiscallResolver, tidying up the constructor, fixing +// a bug in IASIOThiscallResolver::ASIOExit() and improving +// portability through the use of conditional compilation +// 1.0 Initial working version. +// Created: 6/09/2003 +// Authors: Fraser Adams +// Ross Bencina +// Rene G. Ceballos +// Martin Fay +// Antti Silvast +// Andrew Baldwin +// +// **************************************************************************** + + +#ifndef included_iasiothiscallresolver_h +#define included_iasiothiscallresolver_h + +// We only need IASIOThiscallResolver at all if we are on Win32. For other +// platforms we simply bypass the IASIOThiscallResolver definition to allow us +// to be safely #include'd whatever the platform to keep client code portable +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + + +// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver +// is not used. +#if !defined(_MSC_VER) + + +// The following is in order to ensure that this header is only included after +// the other ASIO headers (except for the case of iasiothiscallresolver.cpp). +// We need to do this because IASIOThiscallResolver works by eclipsing the +// original definition of ASIOInit() with a macro (see below). +#if !defined(iasiothiscallresolver_sourcefile) + #if !defined(__ASIO_H) + #error iasiothiscallresolver.h must be included AFTER asio.h + #endif +#endif + +#include +#include "iasiodrv.h" /* From ASIO SDK */ + + +class IASIOThiscallResolver : public IASIO { +private: + IASIO* that_; // Points to the real IASIO + + static IASIOThiscallResolver instance; // Singleton instance + + // Constructors - declared private so construction is limited to + // our Singleton instance + IASIOThiscallResolver(); + IASIOThiscallResolver(IASIO* that); +public: + + // Methods from the IUnknown interface. We don't fully implement IUnknown + // because the ASIO SDK never calls these methods through theAsioDriver ptr. + // These methods are implemented as assert(false). + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + + // Methods from the IASIO interface, implemented as forwarning calls to that. + virtual ASIOBool init(void *sysHandle); + virtual void getDriverName(char *name); + virtual long getDriverVersion(); + virtual void getErrorMessage(char *string); + virtual ASIOError start(); + virtual ASIOError stop(); + virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels); + virtual ASIOError getLatencies(long *inputLatency, long *outputLatency); + virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); + virtual ASIOError canSampleRate(ASIOSampleRate sampleRate); + virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate); + virtual ASIOError setSampleRate(ASIOSampleRate sampleRate); + virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); + virtual ASIOError setClockSource(long reference); + virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); + virtual ASIOError getChannelInfo(ASIOChannelInfo *info); + virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks); + virtual ASIOError disposeBuffers(); + virtual ASIOError controlPanel(); + virtual ASIOError future(long selector,void *opt); + virtual ASIOError outputReady(); + + // Class method, see ASIOInit() macro below. + static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit +}; + + +// Replace calls to ASIOInit with our interposing version. +// This macro enables us to perform thiscall resolution simply by #including +// after the asio #includes (this file _must_ be +// included _after_ the asio #includes) + +#define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name)) + + +#endif /* !defined(_MSC_VER) */ + +#endif /* Win32 */ + +#endif /* included_iasiothiscallresolver_h */ + + diff --git a/include/soundcard.h b/include/soundcard.h new file mode 100644 index 0000000..e8fc9f6 --- /dev/null +++ b/include/soundcard.h @@ -0,0 +1,2061 @@ +#ifndef SOUNDCARD_H +#define SOUNDCARD_H +/* + **************************************************************************** + * Copyright by 4Front Technologies 1993-2006 + * + ****************************************************************************** + * Modifications to this file are NOT allowed. This header file controls the + * OSS API. For compatibility reasons only 4Front Technologies can make changes + * to the definitions. If you have any questions, please contact + * hannu@opensound.com. + ****************************************************************************** + * + * Redistribution and use in source and binary forms, without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + **************************************************************************** + */ +/* + * Purpose: The C/C++ header file that defines the OSS API. + * Description: + * This header file contains all the declarations required to compile OSS + * programs. The latest version is always installed together with OSS + * use of the latest version is strongly recommended. + * + * {!notice This header file contains many obsolete definitions + * (for compatibility with older applications that still ned them). + * Do not use this file as a reference manual of OSS. + * Please check the OSS Programmer's guide for descriptions + * of the supported API details (http://www.opensound.com/pguide).} + */ + +#if defined(__cplusplus) +#define EXTERNC extern "C" +#else +#define EXTERNC extern +#endif /* EXTERN_C_WRAPPERS */ + +#define OSS_VERSION 0x040002 + +#define SOUND_VERSION OSS_VERSION +#define OPEN_SOUND_SYSTEM + +#if defined(__hpux) && !defined(_HPUX_SOURCE) +# error "-D_HPUX_SOURCE must be used when compiling OSS applications" +#endif + +#ifdef __hpux +#include +#endif + +#ifdef linux +/* In Linux we need to be prepared for cross compiling */ +#include +#else +# ifdef __FreeBSD__ +# include +# else +# include +# endif +#endif + +#ifndef __SIOWR +#if defined(__hpux) || (defined(_IOWR) && (defined(_AIX) || (!defined(sun) && !defined(sparc) && !defined(__INCioctlh) && !defined(__Lynx__)))) + +/* + * Make sure the ioctl macros are compatible with the ones already used + * by this operating system. + */ +#define SIOCPARM_MASK IOCPARM_MASK +#define SIOC_VOID IOC_VOID +#define SIOC_OUT IOC_OUT +#define SIOC_IN IOC_IN +#define SIOC_INOUT IOC_INOUT +#define __SIOC_SIZE _IOC_SIZE +#define __SIOC_DIR _IOC_DIR +#define __SIOC_NONE _IOC_NONE +#define __SIOC_READ _IOC_READ +#define __SIOC_WRITE _IOC_WRITE +#define __SIO _IO +#define __SIOR _IOR +#define __SIOW _IOW +#define __SIOWR _IOWR +#else + +/* #define SIOCTYPE (0xff<<8) */ +#define SIOCPARM_MASK 0x1fff /* parameters must be < 8192 bytes */ +#define SIOC_VOID 0x00000000 /* no parameters */ +#define SIOC_OUT 0x20000000 /* copy out parameters */ +#define SIOC_IN 0x40000000 /* copy in parameters */ +#define SIOC_INOUT (SIOC_IN|SIOC_OUT) + +#define __SIO(x,y) ((int)(SIOC_VOID|(x<<8)|y)) +#define __SIOR(x,y,t) ((int)(SIOC_OUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) +#define __SIOW(x,y,t) ((int)(SIOC_IN|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) +#define __SIOWR(x,y,t) ((int)(SIOC_INOUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) +#define __SIOC_SIZE(x) ((x>>16)&SIOCPARM_MASK) +#define __SIOC_DIR(x) (x & 0xf0000000) +#define __SIOC_NONE SIOC_VOID +#define __SIOC_READ SIOC_OUT +#define __SIOC_WRITE SIOC_IN +# endif /* _IOWR */ +#endif /* !__SIOWR */ + +#define OSS_LONGNAME_SIZE 64 +#define OSS_LABEL_SIZE 16 +#define OSS_DEVNODE_SIZE 32 +typedef char oss_longname_t[OSS_LONGNAME_SIZE]; +typedef char oss_label_t[OSS_LABEL_SIZE]; +typedef char oss_devnode_t[OSS_DEVNODE_SIZE]; + +#ifndef DISABLE_SEQUENCER +/* + **************************************************************************** + * IOCTL Commands for /dev/sequencer and /dev/music (AKA /dev/sequencer2) + * + * Note that this interface is obsolete and no longer developed. New + * applications should use /dev/midi instead. + ****************************************************************************/ +#define SNDCTL_SEQ_RESET __SIO ('Q', 0) +#define SNDCTL_SEQ_SYNC __SIO ('Q', 1) +#define SNDCTL_SYNTH_INFO __SIOWR('Q', 2, struct synth_info) +#define SNDCTL_SEQ_CTRLRATE __SIOWR('Q', 3, int) /* Set/get timer resolution (HZ) */ +#define SNDCTL_SEQ_GETOUTCOUNT __SIOR ('Q', 4, int) +#define SNDCTL_SEQ_GETINCOUNT __SIOR ('Q', 5, int) +#define SNDCTL_SEQ_PERCMODE __SIOW ('Q', 6, int) +#define SNDCTL_FM_LOAD_INSTR __SIOW ('Q', 7, struct sbi_instrument) /* Obsolete. Don't use!!!!!! */ +#define SNDCTL_SEQ_TESTMIDI __SIOW ('Q', 8, int) +#define SNDCTL_SEQ_RESETSAMPLES __SIOW ('Q', 9, int) +#define SNDCTL_SEQ_NRSYNTHS __SIOR ('Q',10, int) +#define SNDCTL_SEQ_NRMIDIS __SIOR ('Q',11, int) +#define SNDCTL_MIDI_INFO __SIOWR('Q',12, struct midi_info) /* OBSOLETE - use SNDCTL_MIDIINFO instead */ +#define SNDCTL_SEQ_THRESHOLD __SIOW ('Q',13, int) +#define SNDCTL_SYNTH_MEMAVL __SIOWR('Q',14, int) /* in=dev#, out=memsize */ +#define SNDCTL_FM_4OP_ENABLE __SIOW ('Q',15, int) /* in=dev# */ +#define SNDCTL_SEQ_PANIC __SIO ('Q',17) +#define SNDCTL_SEQ_OUTOFBAND __SIOW ('Q',18, struct seq_event_rec) +#define SNDCTL_SEQ_GETTIME __SIOR ('Q',19, int) +#define SNDCTL_SYNTH_ID __SIOWR('Q',20, struct synth_info) +#define SNDCTL_SYNTH_CONTROL __SIOWR('Q',21, struct synth_control) +#define SNDCTL_SYNTH_REMOVESAMPLE __SIOWR('Q',22, struct remove_sample) /* Reserved for future use */ +#define SNDCTL_SEQ_TIMING_ENABLE __SIO ('Q', 23) /* Enable incoming MIDI timing messages */ +#define SNDCTL_SEQ_ACTSENSE_ENABLE __SIO ('Q', 24) /* Enable incoming active sensing messages */ +#define SNDCTL_SEQ_RT_ENABLE __SIO ('Q', 25) /* Enable other incoming realtime messages */ + +typedef struct synth_control +{ + int devno; /* Synthesizer # */ + char data[4000]; /* Device spesific command/data record */ +} synth_control; + +typedef struct remove_sample +{ + int devno; /* Synthesizer # */ + int bankno; /* MIDI bank # (0=General MIDI) */ + int instrno; /* MIDI instrument number */ +} remove_sample; + +typedef struct seq_event_rec +{ + unsigned char arr[8]; +} seq_event_rec; + +#define SNDCTL_TMR_TIMEBASE __SIOWR('T', 1, int) +#define SNDCTL_TMR_START __SIO ('T', 2) +#define SNDCTL_TMR_STOP __SIO ('T', 3) +#define SNDCTL_TMR_CONTINUE __SIO ('T', 4) +#define SNDCTL_TMR_TEMPO __SIOWR('T', 5, int) +#define SNDCTL_TMR_SOURCE __SIOWR('T', 6, int) +# define TMR_INTERNAL 0x00000001 +# define TMR_EXTERNAL 0x00000002 +# define TMR_MODE_MIDI 0x00000010 +# define TMR_MODE_FSK 0x00000020 +# define TMR_MODE_CLS 0x00000040 +# define TMR_MODE_SMPTE 0x00000080 +#define SNDCTL_TMR_METRONOME __SIOW ('T', 7, int) +#define SNDCTL_TMR_SELECT __SIOW ('T', 8, int) + +/* + * Sample loading mechanism for internal synthesizers (/dev/sequencer) + * (for the .PAT format). + */ + +struct patch_info +{ + unsigned short key; /* Use WAVE_PATCH here */ +#define WAVE_PATCH _PATCHKEY(0x04) +#define GUS_PATCH WAVE_PATCH +#define WAVEFRONT_PATCH _PATCHKEY(0x06) + + short device_no; /* Synthesizer number */ + short instr_no; /* Midi pgm# */ + + unsigned int mode; +/* + * The least significant byte has the same format than the GUS .PAT + * files + */ +#define WAVE_16_BITS 0x01 /* bit 0 = 8 or 16 bit wave data. */ +#define WAVE_UNSIGNED 0x02 /* bit 1 = Signed - Unsigned data. */ +#define WAVE_LOOPING 0x04 /* bit 2 = looping enabled-1. */ +#define WAVE_BIDIR_LOOP 0x08 /* bit 3 = Set is bidirectional looping. */ +#define WAVE_LOOP_BACK 0x10 /* bit 4 = Set is looping backward. */ +#define WAVE_SUSTAIN_ON 0x20 /* bit 5 = Turn sustaining on. (Env. pts. 3) */ +#define WAVE_ENVELOPES 0x40 /* bit 6 = Enable envelopes - 1 */ +#define WAVE_FAST_RELEASE 0x80 /* bit 7 = Shut off immediately after note off */ + /* (use the env_rate/env_offs fields). */ +/* Linux specific bits */ +#define WAVE_VIBRATO 0x00010000 /* The vibrato info is valid */ +#define WAVE_TREMOLO 0x00020000 /* The tremolo info is valid */ +#define WAVE_SCALE 0x00040000 /* The scaling info is valid */ +#define WAVE_FRACTIONS 0x00080000 /* Fraction information is valid */ +/* Reserved bits */ +#define WAVE_ROM 0x40000000 /* For future use */ +#define WAVE_MULAW 0x20000000 /* For future use */ +/* Other bits must be zeroed */ + + int len; /* Size of the wave data in bytes */ + int loop_start, loop_end; /* Byte offsets from the beginning */ + +/* + * The base_freq and base_note fields are used when computing the + * playback speed for a note. The base_note defines the tone frequency + * which is heard if the sample is played using the base_freq as the + * playback speed. + * + * The low_note and high_note fields define the minimum and maximum note + * frequencies for which this sample is valid. It is possible to define + * more than one samples for an instrument number at the same time. The + * low_note and high_note fields are used to select the most suitable one. + * + * The fields base_note, high_note and low_note should contain + * the note frequency multiplied by 1000. For example value for the + * middle A is 440*1000. + */ + + unsigned int base_freq; + unsigned int base_note; + unsigned int high_note; + unsigned int low_note; + int panning; /* -128=left, 127=right */ + int detuning; + + /* Envelope. Enabled by mode bit WAVE_ENVELOPES */ + unsigned char env_rate[6]; /* GUS HW ramping rate */ + unsigned char env_offset[6]; /* 255 == 100% */ + + /* + * The tremolo, vibrato and scale info are not supported yet. + * Enable by setting the mode bits WAVE_TREMOLO, WAVE_VIBRATO or + * WAVE_SCALE + */ + + unsigned char tremolo_sweep; + unsigned char tremolo_rate; + unsigned char tremolo_depth; + + unsigned char vibrato_sweep; + unsigned char vibrato_rate; + unsigned char vibrato_depth; + + int scale_frequency; + unsigned int scale_factor; /* from 0 to 2048 or 0 to 2 */ + + int volume; + int fractions; + int reserved1; + int spare[2]; + char data[1]; /* The waveform data starts here */ +}; + +struct sysex_info +{ + short key; /* Use SYSEX_PATCH or MAUI_PATCH here */ +#define SYSEX_PATCH _PATCHKEY(0x05) +#define MAUI_PATCH _PATCHKEY(0x06) + short device_no; /* Synthesizer number */ + int len; /* Size of the sysex data in bytes */ + unsigned char data[1]; /* Sysex data starts here */ +}; + +/* + * /dev/sequencer input events. + * + * The data written to the /dev/sequencer is a stream of events. Events + * are records of 4 or 8 bytes. The first byte defines the size. + * Any number of events can be written with a write call. There + * is a set of macros for sending these events. Use these macros if you + * want to maximize portability of your program. + * + * Events SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO. Are also input events. + * (All input events are currently 4 bytes long. Be prepared to support + * 8 byte events also. If you receive any event having first byte >= 128, + * it's a 8 byte event. + * + * The events are documented at the end of this file. + * + * Normal events (4 bytes) + * There is also a 8 byte version of most of the 4 byte events. The + * 8 byte one is recommended. + * + * NOTE! All 4 byte events are now obsolete. Applications should not write + * them. However 4 byte events are still used as inputs from + * /dev/sequencer (/dev/music uses only 8 byte ones). + */ +#define SEQ_NOTEOFF 0 +#define SEQ_FMNOTEOFF SEQ_NOTEOFF /* Just old name */ +#define SEQ_NOTEON 1 +#define SEQ_FMNOTEON SEQ_NOTEON +#define SEQ_WAIT TMR_WAIT_ABS +#define SEQ_PGMCHANGE 3 +#define SEQ_FMPGMCHANGE SEQ_PGMCHANGE +#define SEQ_SYNCTIMER TMR_START +#define SEQ_MIDIPUTC 5 +#define SEQ_DRUMON 6 /*** OBSOLETE ***/ +#define SEQ_DRUMOFF 7 /*** OBSOLETE ***/ +#define SEQ_ECHO TMR_ECHO /* For synching programs with output */ +#define SEQ_AFTERTOUCH 9 +#define SEQ_CONTROLLER 10 +#define SEQ_BALANCE 11 +#define SEQ_VOLMODE 12 + +/************************************ + * Midi controller numbers * + ************************************/ +/* + * Controllers 0 to 31 (0x00 to 0x1f) and + * 32 to 63 (0x20 to 0x3f) are continuous + * controllers. + * In the MIDI 1.0 these controllers are sent using + * two messages. Controller numbers 0 to 31 are used + * to send the MSB and the controller numbers 32 to 63 + * are for the LSB. Note that just 7 bits are used in MIDI bytes. + */ + +#define CTL_BANK_SELECT 0x00 +#define CTL_MODWHEEL 0x01 +#define CTL_BREATH 0x02 +/* undefined 0x03 */ +#define CTL_FOOT 0x04 +#define CTL_PORTAMENTO_TIME 0x05 +#define CTL_DATA_ENTRY 0x06 +#define CTL_MAIN_VOLUME 0x07 +#define CTL_BALANCE 0x08 +/* undefined 0x09 */ +#define CTL_PAN 0x0a +#define CTL_EXPRESSION 0x0b +/* undefined 0x0c */ +/* undefined 0x0d */ +/* undefined 0x0e */ +/* undefined 0x0f */ +#define CTL_GENERAL_PURPOSE1 0x10 +#define CTL_GENERAL_PURPOSE2 0x11 +#define CTL_GENERAL_PURPOSE3 0x12 +#define CTL_GENERAL_PURPOSE4 0x13 +/* undefined 0x14 - 0x1f */ + +/* undefined 0x20 */ +/* The controller numbers 0x21 to 0x3f are reserved for the */ +/* least significant bytes of the controllers 0x00 to 0x1f. */ +/* These controllers are not recognised by the driver. */ + +/* Controllers 64 to 69 (0x40 to 0x45) are on/off switches. */ +/* 0=OFF and 127=ON (intermediate values are possible) */ +#define CTL_DAMPER_PEDAL 0x40 +#define CTL_SUSTAIN 0x40 /* Alias */ +#define CTL_HOLD 0x40 /* Alias */ +#define CTL_PORTAMENTO 0x41 +#define CTL_SOSTENUTO 0x42 +#define CTL_SOFT_PEDAL 0x43 +/* undefined 0x44 */ +#define CTL_HOLD2 0x45 +/* undefined 0x46 - 0x4f */ + +#define CTL_GENERAL_PURPOSE5 0x50 +#define CTL_GENERAL_PURPOSE6 0x51 +#define CTL_GENERAL_PURPOSE7 0x52 +#define CTL_GENERAL_PURPOSE8 0x53 +/* undefined 0x54 - 0x5a */ +#define CTL_EXT_EFF_DEPTH 0x5b +#define CTL_TREMOLO_DEPTH 0x5c +#define CTL_CHORUS_DEPTH 0x5d +#define CTL_DETUNE_DEPTH 0x5e +#define CTL_CELESTE_DEPTH 0x5e /* Alias for the above one */ +#define CTL_PHASER_DEPTH 0x5f +#define CTL_DATA_INCREMENT 0x60 +#define CTL_DATA_DECREMENT 0x61 +#define CTL_NONREG_PARM_NUM_LSB 0x62 +#define CTL_NONREG_PARM_NUM_MSB 0x63 +#define CTL_REGIST_PARM_NUM_LSB 0x64 +#define CTL_REGIST_PARM_NUM_MSB 0x65 +/* undefined 0x66 - 0x78 */ +/* reserved 0x79 - 0x7f */ + +/* Pseudo controllers (not midi compatible) */ +#define CTRL_PITCH_BENDER 255 +#define CTRL_PITCH_BENDER_RANGE 254 +#define CTRL_EXPRESSION 253 /* Obsolete */ +#define CTRL_MAIN_VOLUME 252 /* Obsolete */ + +/* + * Volume mode defines how volumes are used + */ + +#define VOL_METHOD_ADAGIO 1 +#define VOL_METHOD_LINEAR 2 + +/* + * Note! SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO are used also as + * input events. + */ + +/* + * Event codes 0xf0 to 0xfc are reserved for future extensions. + */ + +#define SEQ_FULLSIZE 0xfd /* Long events */ +/* + * SEQ_FULLSIZE events are used for loading patches/samples to the + * synthesizer devices. These events are passed directly to the driver + * of the associated synthesizer device. There is no limit to the size + * of the extended events. These events are not queued but executed + * immediately when the write() is called (execution can take several + * seconds of time). + * + * When a SEQ_FULLSIZE message is written to the device, it must + * be written using exactly one write() call. Other events cannot + * be mixed to the same write. + * + * For FM synths (YM3812/OPL3) use struct sbi_instrument and write it to the + * /dev/sequencer. Don't write other data together with the instrument structure + * Set the key field of the structure to FM_PATCH. The device field is used to + * route the patch to the corresponding device. + * + * For wave table use struct patch_info. Initialize the key field + * to WAVE_PATCH. + */ +#define SEQ_PRIVATE 0xfe /* Low level HW dependent events (8 bytes) */ +#define SEQ_EXTENDED 0xff /* Extended events (8 bytes) OBSOLETE */ + +/* + * Record for FM patches + */ + +typedef unsigned char sbi_instr_data[32]; + +struct sbi_instrument +{ + unsigned short key; /* FM_PATCH or OPL3_PATCH */ +#define FM_PATCH _PATCHKEY(0x01) +#define OPL3_PATCH _PATCHKEY(0x03) + short device; /* Synth# (0-4) */ + int channel; /* Program# to be initialized */ + sbi_instr_data operators; /* Register settings for operator cells (.SBI format) */ +}; + +struct synth_info +{ /* Read only */ + char name[30]; + int device; /* 0-N. INITIALIZE BEFORE CALLING */ + int synth_type; +#define SYNTH_TYPE_FM 0 +#define SYNTH_TYPE_SAMPLE 1 +#define SYNTH_TYPE_MIDI 2 /* Midi interface */ + + int synth_subtype; +#define FM_TYPE_ADLIB 0x00 +#define FM_TYPE_OPL3 0x01 +#define MIDI_TYPE_MPU401 0x401 + +#define SAMPLE_TYPE_BASIC 0x10 +#define SAMPLE_TYPE_GUS SAMPLE_TYPE_BASIC +#define SAMPLE_TYPE_WAVEFRONT 0x11 + + int perc_mode; /* No longer supported */ + int nr_voices; + int nr_drums; /* Obsolete field */ + int instr_bank_size; + unsigned int capabilities; +#define SYNTH_CAP_PERCMODE 0x00000001 /* No longer used */ +#define SYNTH_CAP_OPL3 0x00000002 /* Set if OPL3 supported */ +#define SYNTH_CAP_INPUT 0x00000004 /* Input (MIDI) device */ + int dummies[19]; /* Reserve space */ +}; + +struct sound_timer_info +{ + char name[32]; + int caps; +}; + +struct midi_info /* OBSOLETE */ +{ + char name[30]; + int device; /* 0-N. INITIALIZE BEFORE CALLING */ + unsigned int capabilities; /* To be defined later */ + int dev_type; + int dummies[18]; /* Reserve space */ +}; + +/* + * Level 2 event types for /dev/sequencer + */ + +/* + * The 4 most significant bits of byte 0 specify the class of + * the event: + * + * 0x8X = system level events, + * 0x9X = device/port specific events, event[1] = device/port, + * The last 4 bits give the subtype: + * 0x02 = Channel event (event[3] = chn). + * 0x01 = note event (event[4] = note). + * (0x01 is not used alone but always with bit 0x02). + * event[2] = MIDI message code (0x80=note off etc.) + * + */ + +#define EV_SEQ_LOCAL 0x80 +#define EV_TIMING 0x81 +#define EV_CHN_COMMON 0x92 +#define EV_CHN_VOICE 0x93 +#define EV_SYSEX 0x94 +#define EV_SYSTEM 0x95 /* MIDI system and real time messages (input only) */ +/* + * Event types 200 to 220 are reserved for application use. + * These numbers will not be used by the driver. + */ + +/* + * Events for event type EV_CHN_VOICE + */ + +#define MIDI_NOTEOFF 0x80 +#define MIDI_NOTEON 0x90 +#define MIDI_KEY_PRESSURE 0xA0 + +/* + * Events for event type EV_CHN_COMMON + */ + +#define MIDI_CTL_CHANGE 0xB0 +#define MIDI_PGM_CHANGE 0xC0 +#define MIDI_CHN_PRESSURE 0xD0 +#define MIDI_PITCH_BEND 0xE0 + +#define MIDI_SYSTEM_PREFIX 0xF0 + +/* + * Timer event types + */ +#define TMR_WAIT_REL 1 /* Time relative to the prev time */ +#define TMR_WAIT_ABS 2 /* Absolute time since TMR_START */ +#define TMR_STOP 3 +#define TMR_START 4 +#define TMR_CONTINUE 5 +#define TMR_TEMPO 6 +#define TMR_ECHO 8 +#define TMR_CLOCK 9 /* MIDI clock */ +#define TMR_SPP 10 /* Song position pointer */ +#define TMR_TIMESIG 11 /* Time signature */ + +/* + * Local event types + */ +#define LOCL_STARTAUDIO 1 +#define LOCL_STARTAUDIO2 2 +#define LOCL_STARTAUDIO3 3 +#define LOCL_STARTAUDIO4 4 + +#if (!defined(__KERNEL__) && !defined(KERNEL) && !defined(INKERNEL) && !defined(_KERNEL)) || defined(USE_SEQ_MACROS) +/* + * Some convenience macros to simplify programming of the + * /dev/sequencer interface + * + * These macros define the API which should be used when possible. + */ +#define SEQ_DECLAREBUF() SEQ_USE_EXTBUF() + +void seqbuf_dump (void); /* This function must be provided by programs */ + +EXTERNC int OSS_init (int seqfd, int buflen); +EXTERNC void OSS_seqbuf_dump (int fd, unsigned char *buf, int buflen); +EXTERNC void OSS_seq_advbuf (int len, int fd, unsigned char *buf, int buflen); +EXTERNC void OSS_seq_needbuf (int len, int fd, unsigned char *buf, + int buflen); +EXTERNC void OSS_patch_caching (int dev, int chn, int patch, int fd, + unsigned char *buf, int buflen); +EXTERNC void OSS_drum_caching (int dev, int chn, int patch, int fd, + unsigned char *buf, int buflen); +EXTERNC void OSS_write_patch (int fd, unsigned char *buf, int len); +EXTERNC int OSS_write_patch2 (int fd, unsigned char *buf, int len); + +#define SEQ_PM_DEFINES int __foo_bar___ +#ifdef OSSLIB +# define SEQ_USE_EXTBUF() \ + EXTERNC unsigned char *_seqbuf; \ + EXTERNC int _seqbuflen;EXTERNC int _seqbufptr +# define SEQ_DEFINEBUF(len) SEQ_USE_EXTBUF();static int _requested_seqbuflen=len +# define _SEQ_ADVBUF(len) OSS_seq_advbuf(len, seqfd, _seqbuf, _seqbuflen) +# define _SEQ_NEEDBUF(len) OSS_seq_needbuf(len, seqfd, _seqbuf, _seqbuflen) +# define SEQ_DUMPBUF() OSS_seqbuf_dump(seqfd, _seqbuf, _seqbuflen) + +# define SEQ_LOAD_GMINSTR(dev, instr) \ + OSS_patch_caching(dev, -1, instr, seqfd, _seqbuf, _seqbuflen) +# define SEQ_LOAD_GMDRUM(dev, drum) \ + OSS_drum_caching(dev, -1, drum, seqfd, _seqbuf, _seqbuflen) +#else /* !OSSLIB */ + +# define SEQ_LOAD_GMINSTR(dev, instr) +# define SEQ_LOAD_GMDRUM(dev, drum) + +# define SEQ_USE_EXTBUF() \ + EXTERNC unsigned char _seqbuf[]; \ + EXTERNC int _seqbuflen;EXTERNC int _seqbufptr + +#ifndef USE_SIMPLE_MACROS +/* Sample seqbuf_dump() implementation: + * + * SEQ_DEFINEBUF (2048); -- Defines a buffer for 2048 bytes + * + * int seqfd; -- The file descriptor for /dev/sequencer. + * + * void + * seqbuf_dump () + * { + * if (_seqbufptr) + * if (write (seqfd, _seqbuf, _seqbufptr) == -1) + * { + * perror ("write /dev/sequencer"); + * exit (-1); + * } + * _seqbufptr = 0; + * } + */ + +#define SEQ_DEFINEBUF(len) \ + unsigned char _seqbuf[len]; int _seqbuflen = len;int _seqbufptr = 0 +#define _SEQ_NEEDBUF(len) \ + if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump() +#define _SEQ_ADVBUF(len) _seqbufptr += len +#define SEQ_DUMPBUF seqbuf_dump +#else +/* + * This variation of the sequencer macros is used just to format one event + * using fixed buffer. + * + * The program using the macro library must define the following macros before + * using this library. + * + * #define _seqbuf name of the buffer (unsigned char[]) + * #define _SEQ_ADVBUF(len) If the applic needs to know the exact + * size of the event, this macro can be used. + * Otherwise this must be defined as empty. + * #define _seqbufptr Define the name of index variable or 0 if + * not required. + */ +#define _SEQ_NEEDBUF(len) /* empty */ +#endif +#endif /* !OSSLIB */ + +#define SEQ_VOLUME_MODE(dev, mode) \ + {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ + _seqbuf[_seqbufptr+1] = SEQ_VOLMODE;\ + _seqbuf[_seqbufptr+2] = (dev);\ + _seqbuf[_seqbufptr+3] = (mode);\ + _seqbuf[_seqbufptr+4] = 0;\ + _seqbuf[_seqbufptr+5] = 0;\ + _seqbuf[_seqbufptr+6] = 0;\ + _seqbuf[_seqbufptr+7] = 0;\ + _SEQ_ADVBUF(8);} + +/* + * Midi voice messages + */ + +#define _CHN_VOICE(dev, event, chn, note, parm) \ + {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr] = EV_CHN_VOICE;\ + _seqbuf[_seqbufptr+1] = (dev);\ + _seqbuf[_seqbufptr+2] = (event);\ + _seqbuf[_seqbufptr+3] = (chn);\ + _seqbuf[_seqbufptr+4] = (note);\ + _seqbuf[_seqbufptr+5] = (parm);\ + _seqbuf[_seqbufptr+6] = (0);\ + _seqbuf[_seqbufptr+7] = 0;\ + _SEQ_ADVBUF(8);} + +#define SEQ_START_NOTE(dev, chn, note, vol) \ + _CHN_VOICE(dev, MIDI_NOTEON, chn, note, vol) + +#define SEQ_STOP_NOTE(dev, chn, note, vol) \ + _CHN_VOICE(dev, MIDI_NOTEOFF, chn, note, vol) + +#define SEQ_KEY_PRESSURE(dev, chn, note, pressure) \ + _CHN_VOICE(dev, MIDI_KEY_PRESSURE, chn, note, pressure) + +/* + * Midi channel messages + */ + +#define _CHN_COMMON(dev, event, chn, p1, p2, w14) \ + {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr] = EV_CHN_COMMON;\ + _seqbuf[_seqbufptr+1] = (dev);\ + _seqbuf[_seqbufptr+2] = (event);\ + _seqbuf[_seqbufptr+3] = (chn);\ + _seqbuf[_seqbufptr+4] = (p1);\ + _seqbuf[_seqbufptr+5] = (p2);\ + *(short *)&_seqbuf[_seqbufptr+6] = (w14);\ + _SEQ_ADVBUF(8);} +/* + * SEQ_SYSEX permits sending of sysex messages. (It may look that it permits + * sending any MIDI bytes but it's absolutely not possible. Trying to do + * so _will_ cause problems with MPU401 intelligent mode). + * + * Sysex messages are sent in blocks of 1 to 6 bytes. Longer messages must be + * sent by calling SEQ_SYSEX() several times (there must be no other events + * between them). First sysex fragment must have 0xf0 in the first byte + * and the last byte (buf[len-1] of the last fragment must be 0xf7. No byte + * between these sysex start and end markers cannot be larger than 0x7f. Also + * lengths of each fragments (except the last one) must be 6. + * + * Breaking the above rules may work with some MIDI ports but is likely to + * cause fatal problems with some other devices (such as MPU401). + */ +#define SEQ_SYSEX(dev, buf, len) \ + {int ii, ll=(len); \ + unsigned char *bufp=buf;\ + if (ll>6)ll=6;\ + _SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr] = EV_SYSEX;\ + _seqbuf[_seqbufptr+1] = (dev);\ + for(ii=0;ii>8)&0xff);\ + _seqbuf[_seqbufptr+7] = 0;\ + _SEQ_ADVBUF(8);} +/* + * The following 5 macros are incorrectly implemented and obsolete. + * Use SEQ_BENDER and SEQ_CONTROL (with proper controller) instead. + */ +#define SEQ_PITCHBEND(dev, voice, value) \ + SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER, value) +#define SEQ_BENDER_RANGE(dev, voice, value) \ + SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER_RANGE, value) +#define SEQ_EXPRESSION(dev, voice, value) \ + SEQ_CONTROL(dev, voice, CTL_EXPRESSION, value*128) +#define SEQ_MAIN_VOLUME(dev, voice, value) \ + SEQ_CONTROL(dev, voice, CTL_MAIN_VOLUME, (value*16383)/100) +#define SEQ_PANNING(dev, voice, pos) \ + SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2) + +/* + * Timing and syncronization macros + */ + +#define _TIMER_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr+0] = EV_TIMING; \ + _seqbuf[_seqbufptr+1] = (ev); \ + _seqbuf[_seqbufptr+2] = 0;\ + _seqbuf[_seqbufptr+3] = 0;\ + *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ + _SEQ_ADVBUF(8);} + +#define SEQ_START_TIMER() _TIMER_EVENT(TMR_START, 0) +#define SEQ_STOP_TIMER() _TIMER_EVENT(TMR_STOP, 0) +#define SEQ_CONTINUE_TIMER() _TIMER_EVENT(TMR_CONTINUE, 0) +#define SEQ_WAIT_TIME(ticks) _TIMER_EVENT(TMR_WAIT_ABS, ticks) +#define SEQ_DELTA_TIME(ticks) _TIMER_EVENT(TMR_WAIT_REL, ticks) +#define SEQ_ECHO_BACK(key) _TIMER_EVENT(TMR_ECHO, key) +#define SEQ_SET_TEMPO(value) _TIMER_EVENT(TMR_TEMPO, value) +#define SEQ_SONGPOS(pos) _TIMER_EVENT(TMR_SPP, pos) +#define SEQ_TIME_SIGNATURE(sig) _TIMER_EVENT(TMR_TIMESIG, sig) + +/* + * Local control events + */ + +#define _LOCAL_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr+0] = EV_SEQ_LOCAL; \ + _seqbuf[_seqbufptr+1] = (ev); \ + _seqbuf[_seqbufptr+2] = 0;\ + _seqbuf[_seqbufptr+3] = 0;\ + *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ + _SEQ_ADVBUF(8);} + +#define SEQ_PLAYAUDIO(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO, devmask) +#define SEQ_PLAYAUDIO2(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO2, devmask) +#define SEQ_PLAYAUDIO3(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO3, devmask) +#define SEQ_PLAYAUDIO4(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO4, devmask) +/* + * Events for the level 1 interface only + */ + +#define SEQ_MIDIOUT(device, byte) {_SEQ_NEEDBUF(4);\ + _seqbuf[_seqbufptr] = SEQ_MIDIPUTC;\ + _seqbuf[_seqbufptr+1] = (byte);\ + _seqbuf[_seqbufptr+2] = (device);\ + _seqbuf[_seqbufptr+3] = 0;\ + _SEQ_ADVBUF(4);} + +/* + * Patch loading. + */ +#ifdef OSSLIB +# define SEQ_WRPATCH(patchx, len) \ + OSS_write_patch(seqfd, (char*)(patchx), len) +# define SEQ_WRPATCH2(patchx, len) \ + OSS_write_patch2(seqfd, (char*)(patchx), len) +#else +# define SEQ_WRPATCH(patchx, len) \ + {if (_seqbufptr) SEQ_DUMPBUF();\ + if (write(seqfd, (char*)(patchx), len)==-1) \ + perror("Write patch: /dev/sequencer");} +# define SEQ_WRPATCH2(patchx, len) \ + (SEQ_DUMPBUF(), write(seqfd, (char*)(patchx), len)) +#endif + +#endif +#endif /* ifndef DISABLE_SEQUENCER */ + +/* + **************************************************************************** + * ioctl commands for the /dev/midi## + ****************************************************************************/ +#define SNDCTL_MIDI_PRETIME __SIOWR('m', 0, int) + +#if 0 +/* + * The SNDCTL_MIDI_MPUMODE and SNDCTL_MIDI_MPUCMD calls + * are completely obsolete. The hardware device (MPU-401 "intelligent mode" + * and compatibles) has disappeared from the market 10 years ago so there + * is no need for this stuff. The MPU-401 "UART" mode devices don't support + * this stuff. + */ +typedef struct +{ + unsigned char cmd; + char nr_args, nr_returns; + unsigned char data[30]; +} mpu_command_rec; + +#define SNDCTL_MIDI_MPUMODE __SIOWR('m', 1, int) +#define SNDCTL_MIDI_MPUCMD __SIOWR('m', 2, mpu_command_rec) +#endif + +/* + * SNDCTL_MIDI_MTCINPUT turns on a mode where OSS automatically inserts + * MTC quarter frame messages (F1 xx) to the input. + * The argument is the MTC mode: + * + * -1 = Turn MTC messages OFF (default) + * 24 = 24 FPS + * 25 = 25 FPS + * 29 = 30 FPS drop frame + * 30 = 30 FPS + * + * Note that 25 FPS mode is probably the only mode that is supported. Other + * modes may be supported in the future versions of OSS, 25 FPS is handy + * because it generates 25*4=100 quarter frame messages per second which + * matches the usual 100 HZ system timer rate). + * + * The quarter frame timer will be reset to 0:00:00:00.0 at the moment this + * ioctl is made. + */ +#define SNDCTL_MIDI_MTCINPUT __SIOWR('m', 3, int) + +/* + * MTC/SMPTE time code record (for future use) + */ +typedef struct +{ + unsigned char hours, minutes, seconds, frames, qframes; + char direction; +#define MTC_DIR_STOPPED 0 +#define MTC_DIR_FORWARD 1 +#define MTC_DIR_BACKWARD -1 + unsigned char time_code_type; + unsigned int flags; +} oss_mtc_data_t; + +#define SNDCTL_MIDI_SETMODE __SIOWR('m', 6, int) +# define MIDI_MODE_TRADITIONAL 0 +# define MIDI_MODE_TIMED 1 /* Input times are in MIDI ticks */ +# define MIDI_MODE_TIMED_ABS 2 /* Input times are absolute (usecs) */ + +/* + * Packet header for MIDI_MODE_TIMED and MIDI_MODE_TIMED_ABS + */ +typedef unsigned long long oss_midi_time_t; /* Variable type for MIDI time (clock ticks) */ + +typedef struct +{ + int magic; /* Initialize to MIDI_HDR_MAGIC */ +#define MIDI_HDR_MAGIC -1 + unsigned short event_type; +#define MIDI_EV_WRITE 0 /* Write or read (with payload) */ +#define MIDI_EV_TEMPO 1 +#define MIDI_EV_ECHO 2 +#define MIDI_EV_START 3 +#define MIDI_EV_STOP 4 +#define MIDI_EV_CONTINUE 5 +#define MIDI_EV_XPRESSWRITE 6 +#define MIDI_EV_TIMEBASE 7 +#define MIDI_EV_DEVCTL 8 /* Device control read/write */ + unsigned short options; +#define MIDI_OPT_NONE 0x0000 +#define MIDI_OPT_TIMED 0x0001 +#define MIDI_OPT_CONTINUATION 0x0002 +#define MIDI_OPT_USECTIME 0x0004 /* Time is absolute (in usecs) */ +#define MIDI_OPT_BUSY 0x0008 /* Reserved for internal use */ + oss_midi_time_t time; + int parm; + int filler[3]; /* Fur future expansion - init to zeros */ +} midi_packet_header_t; +/* + * MIDI_PAYLOAD_SIZE is the maximum size of one MIDI input chunk. It must be + * less (or equal) than 1024 which is the read size recommended in the + * documentation. TODO: Explain this better. + */ +#define MIDI_PAYLOAD_SIZE 1000 + +typedef struct +{ + midi_packet_header_t hdr; + unsigned char payload[MIDI_PAYLOAD_SIZE]; +} midi_packet_t; + +#define SNDCTL_MIDI_TIMEBASE __SIOWR('m', 7, int) +#define SNDCTL_MIDI_TEMPO __SIOWR('m', 8, int) +/* + * User land MIDI servers (synths) can use SNDCTL_MIDI_SET_LATENCY + * to request MIDI events to be sent to them in advance. The parameter + * (in microseconds) tells how much before the events are submitted. + * + * This feature is only valid for loopback devices and possibly some other + * types of virtual devices. + */ +#define SNDCTL_MIDI_SET_LATENCY __SIOW ('m', 9, int) +/* + **************************************************************************** + * IOCTL commands for /dev/dsp + ****************************************************************************/ + +#define SNDCTL_DSP_HALT __SIO ('P', 0) +#define SNDCTL_DSP_RESET SNDCTL_DSP_HALT /* Old name */ +#define SNDCTL_DSP_SYNC __SIO ('P', 1) +#define SNDCTL_DSP_SPEED __SIOWR('P', 2, int) + +/* SNDCTL_DSP_STEREO is obsolete - use SNDCTL_DSP_CHANNELS instead */ +#define SNDCTL_DSP_STEREO __SIOWR('P', 3, int) +/* SNDCTL_DSP_STEREO is obsolete - use SNDCTL_DSP_CHANNELS instead */ + +#define SNDCTL_DSP_GETBLKSIZE __SIOWR('P', 4, int) +#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT +#define SNDCTL_DSP_CHANNELS __SIOWR('P', 6, int) +#define SNDCTL_DSP_POST __SIO ('P', 8) +#define SNDCTL_DSP_SUBDIVIDE __SIOWR('P', 9, int) +#define SNDCTL_DSP_SETFRAGMENT __SIOWR('P',10, int) + +/* Audio data formats (Note! U8=8 and S16_LE=16 for compatibility) */ +#define SNDCTL_DSP_GETFMTS __SIOR ('P',11, int) /* Returns a mask */ +#define SNDCTL_DSP_SETFMT __SIOWR('P',5, int) /* Selects ONE fmt */ +# define AFMT_QUERY 0x00000000 /* Return current fmt */ +# define AFMT_MU_LAW 0x00000001 +# define AFMT_A_LAW 0x00000002 +# define AFMT_IMA_ADPCM 0x00000004 +# define AFMT_U8 0x00000008 +# define AFMT_S16_LE 0x00000010 /* Little endian signed 16 */ +# define AFMT_S16_BE 0x00000020 /* Big endian signed 16 */ +# define AFMT_S8 0x00000040 +# define AFMT_U16_LE 0x00000080 /* Little endian U16 */ +# define AFMT_U16_BE 0x00000100 /* Big endian U16 */ +# define AFMT_MPEG 0x00000200 /* MPEG (2) audio */ + +/* AC3 _compressed_ bitstreams (See Programmer's Guide for details). */ +# define AFMT_AC3 0x00000400 +/* Ogg Vorbis _compressed_ bit streams */ +# define AFMT_VORBIS 0x00000800 + +/* 32 bit formats (MSB aligned) formats */ +# define AFMT_S32_LE 0x00001000 +# define AFMT_S32_BE 0x00002000 + +/* Reserved for _native_ endian double precision IEEE floating point */ +# define AFMT_FLOAT 0x00004000 + +/* 24 bit formats (LSB aligned in 32 bit word) formats */ +# define AFMT_S24_LE 0x00008000 +# define AFMT_S24_BE 0x00010000 + +/* + * S/PDIF raw format. In this format the S/PDIF frames (including all + * control and user bits) are included in the data stream. Each sample + * is stored in a 32 bit frame (see IEC-958 for more info). This format + * is supported by very few devices and it's only usable for purposes + * where full access to the control/user bits is required (real time control). + */ +# define AFMT_SPDIF_RAW 0x00020000 + +/* 24 bit packed (3 byte) little endian format (USB compatibility) */ +# define AFMT_S24_PACKED 0x00040000 + + +/* + * Some big endian/little endian handling macros (native endian and opposite + * endian formats). The usage of these macros is described in the OSS + * Programmer's Manual. + */ + +#if defined(_AIX) || defined(AIX) || defined(sparc) || defined(__hppa) || defined(PPC) || defined(__powerpc__) && !defined(i386) && !defined(__i386) && !defined(__i386__) + +/* Big endian machines */ +# define _PATCHKEY(id) (0xfd00|id) +# define AFMT_S16_NE AFMT_S16_BE +# define AFMT_U16_NE AFMT_U16_BE +# define AFMT_S32_NE AFMT_S32_BE +# define AFMT_S24_NE AFMT_S24_BE +# define AFMT_S16_OE AFMT_S16_LE +# define AFMT_S32_OE AFMT_S32_LE +# define AFMT_S24_OE AFMT_S24_LE +#else +# define _PATCHKEY(id) ((id<<8)|0xfd) +# define AFMT_S16_NE AFMT_S16_LE +# define AFMT_U16_NE AFMT_U16_LE +# define AFMT_S32_NE AFMT_S32_LE +# define AFMT_S24_NE AFMT_S24_LE +# define AFMT_S16_OE AFMT_S16_BE +# define AFMT_S32_OE AFMT_S32_BE +# define AFMT_S24_OE AFMT_S24_BE +#endif +/* + * Buffer status queries. + */ +typedef struct audio_buf_info +{ + int fragments; /* # of available fragments (partially usend ones not counted) */ + int fragstotal; /* Total # of fragments allocated */ + int fragsize; /* Size of a fragment in bytes */ + int bytes; /* Available space in bytes (includes partially used fragments) */ + /* Note! 'bytes' could be more than fragments*fragsize */ +} audio_buf_info; + +#define SNDCTL_DSP_GETOSPACE __SIOR ('P',12, audio_buf_info) +#define SNDCTL_DSP_GETISPACE __SIOR ('P',13, audio_buf_info) +#define SNDCTL_DSP_GETCAPS __SIOR ('P',15, int) +# define PCM_CAP_REVISION 0x000000ff /* Bits for revision level (0 to 255) */ +# define PCM_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */ +# define PCM_CAP_REALTIME 0x00000200 /* Not in use */ +# define PCM_CAP_BATCH 0x00000400 /* Device has some kind of */ + /* internal buffers which may */ + /* cause some delays and */ + /* decrease precision of timing */ +# define PCM_CAP_COPROC 0x00000800 /* Has a coprocessor */ + /* Sometimes it's a DSP */ + /* but usually not */ +# define PCM_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */ +# define PCM_CAP_MMAP 0x00002000 /* Supports mmap() */ +# define PCM_CAP_MULTI 0x00004000 /* Supports multiple open */ +# define PCM_CAP_BIND 0x00008000 /* Supports binding to front/rear/center/lfe */ +# define PCM_CAP_INPUT 0x00010000 /* Supports recording */ +# define PCM_CAP_OUTPUT 0x00020000 /* Supports playback */ +# define PCM_CAP_VIRTUAL 0x00040000 /* Virtuial device */ +/* 0x00040000 and 0x00080000 reserved for future use */ + +/* Analog/digital control capabilities */ +# define PCM_CAP_ANALOGOUT 0x00100000 +# define PCM_CAP_ANALOGIN 0x00200000 +# define PCM_CAP_DIGITALOUT 0x00400000 +# define PCM_CAP_DIGITALIN 0x00800000 +# define PCM_CAP_ADMASK 0x00f00000 +/* + * NOTE! (capabilities & PCM_CAP_ADMASK)==0 means just that the + * digital/analog interface control features are not supported by the + * device/driver. However the device still supports analog, digital or + * both inputs/outputs (depending on the device). See the OSS Programmer's + * Guide for full details. + */ +# define PCM_CAP_SHADOW 0x01000000 /* "Shadow" device */ + +/* + * Preferred channel usage. These bits can be used to + * give recommendations to the application. Used by few drivers. + * For example if ((caps & DSP_CH_MASK) == DSP_CH_MONO) means that + * the device works best in mono mode. However it doesn't necessarily mean + * that the device cannot be used in stereo. These bits should only be used + * special applications such as multi track hard disk recorders to find out + * the initial setup. However the user should be able to override this + * selection. + * + * To find out which modes are actually supported the application should + * try to select them using SNDCTL_DSP_CHANNELS. + */ +# define DSP_CH_MASK 0x06000000 /* Mask */ +# define DSP_CH_ANY 0x00000000 /* No preferred mode */ +# define DSP_CH_MONO 0x02000000 +# define DSP_CH_STEREO 0x04000000 +# define DSP_CH_MULTI 0x06000000 /* More than two channels */ + +# define PCM_CAP_HIDDEN 0x08000000 /* Hidden device */ +# define PCM_CAP_FREERATE 0x10000000 +# define PCM_CAP_MODEM 0x20000000 /* Modem device */ +# define PCM_CAP_DEFAULT 0x40000000 /* "Default" device */ + +/* + * The PCM_CAP_* capability names were known as DSP_CAP_* prior OSS 4.0 + * so it's necessary to define the older names too. + */ +#define DSP_CAP_ADMASK PCM_CAP_ADMASK +#define DSP_CAP_ANALOGIN PCM_CAP_ANALOGIN +#define DSP_CAP_ANALOGOUT PCM_CAP_ANALOGOUT +#define DSP_CAP_BATCH PCM_CAP_BATCH +#define DSP_CAP_BIND PCM_CAP_BIND +#define DSP_CAP_COPROC PCM_CAP_COPROC +#define DSP_CAP_DEFAULT PCM_CAP_DEFAULT +#define DSP_CAP_DIGITALIN PCM_CAP_DIGITALIN +#define DSP_CAP_DIGITALOUT PCM_CAP_DIGITALOUT +#define DSP_CAP_DUPLEX PCM_CAP_DUPLEX +#define DSP_CAP_FREERATE PCM_CAP_FREERATE +#define DSP_CAP_HIDDEN PCM_CAP_HIDDEN +#define DSP_CAP_INPUT PCM_CAP_INPUT +#define DSP_CAP_MMAP PCM_CAP_MMAP +#define DSP_CAP_MODEM PCM_CAP_MODEM +#define DSP_CAP_MULTI PCM_CAP_MULTI +#define DSP_CAP_OUTPUT PCM_CAP_OUTPUT +#define DSP_CAP_REALTIME PCM_CAP_REALTIME +#define DSP_CAP_REVISION PCM_CAP_REVISION +#define DSP_CAP_SHADOW PCM_CAP_SHADOW +#define DSP_CAP_TRIGGER PCM_CAP_TRIGGER +#define DSP_CAP_VIRTUAL PCM_CAP_VIRTUAL + +#define SNDCTL_DSP_GETTRIGGER __SIOR ('P',16, int) +#define SNDCTL_DSP_SETTRIGGER __SIOW ('P',16, int) +# define PCM_ENABLE_INPUT 0x00000001 +# define PCM_ENABLE_OUTPUT 0x00000002 + +typedef struct count_info +{ + unsigned int bytes; /* Total # of bytes processed */ + int blocks; /* # of fragment transitions since last time */ + int ptr; /* Current DMA pointer value */ +} count_info; + +#define SNDCTL_DSP_GETIPTR __SIOR ('P',17, count_info) +#define SNDCTL_DSP_GETOPTR __SIOR ('P',18, count_info) + +typedef struct buffmem_desc +{ + unsigned *buffer; + int size; +} buffmem_desc; +#define SNDCTL_DSP_SETSYNCRO __SIO ('P', 21) +#define SNDCTL_DSP_SETDUPLEX __SIO ('P', 22) + +#define SNDCTL_DSP_PROFILE __SIOW ('P', 23, int) /* OBSOLETE */ +#define APF_NORMAL 0 /* Normal applications */ +#define APF_NETWORK 1 /* Underruns probably caused by an "external" delay */ +#define APF_CPUINTENS 2 /* Underruns probably caused by "overheating" the CPU */ + +#define SNDCTL_DSP_GETODELAY __SIOR ('P', 23, int) + +typedef struct audio_errinfo +{ + int play_underruns; + int rec_overruns; + unsigned int play_ptradjust; + unsigned int rec_ptradjust; + int play_errorcount; + int rec_errorcount; + int play_lasterror; + int rec_lasterror; + int play_errorparm; + int rec_errorparm; + int filler[16]; +} audio_errinfo; + +#define SNDCTL_DSP_GETPLAYVOL __SIOR ('P', 24, int) +#define SNDCTL_DSP_SETPLAYVOL __SIOWR('P', 24, int) +#define SNDCTL_DSP_GETERROR __SIOR ('P', 25, audio_errinfo) +/* + **************************************************************************** + * Digital interface (S/PDIF) control interface + */ + +typedef struct oss_digital_control +{ + unsigned int caps; +#define DIG_CBITIN_NONE 0x00000000 +#define DIG_CBITIN_LIMITED 0x00000001 +#define DIG_CBITIN_DATA 0x00000002 +#define DIG_CBITIN_BYTE0 0x00000004 +#define DIG_CBITIN_FULL 0x00000008 +#define DIG_CBITIN_MASK 0x0000000f +#define DIG_CBITOUT_NONE 0x00000000 +#define DIG_CBITOUT_LIMITED 0x00000010 +#define DIG_CBITOUT_BYTE0 0x00000020 +#define DIG_CBITOUT_FULL 0x00000040 +#define DIG_CBITOUT_DATA 0x00000080 +#define DIG_CBITOUT_MASK 0x000000f0 +#define DIG_UBITIN 0x00000100 +#define DIG_UBITOUT 0x00000200 +#define DIG_VBITOUT 0x00000400 +#define DIG_OUTRATE 0x00000800 +#define DIG_INRATE 0x00001000 +#define DIG_INBITS 0x00002000 +#define DIG_OUTBITS 0x00004000 +#define DIG_EXACT 0x00010000 +#define DIG_PRO 0x00020000 +#define DIG_CONSUMER 0x00040000 +#define DIG_PASSTHROUGH 0x00080000 +#define DIG_OUTSEL 0x00100000 + + unsigned int valid; +#define VAL_CBITIN 0x00000001 +#define VAL_UBITIN 0x00000002 +#define VAL_CBITOUT 0x00000004 +#define VAL_UBITOUT 0x00000008 +#define VAL_ISTATUS 0x00000010 +#define VAL_IRATE 0x00000020 +#define VAL_ORATE 0x00000040 +#define VAL_INBITS 0x00000080 +#define VAL_OUTBITS 0x00000100 +#define VAL_REQUEST 0x00000200 +#define VAL_OUTSEL 0x00000400 + +#define VAL_OUTMASK (VAL_CBITOUT|VAL_UBITOUT|VAL_ORATE|VAL_OUTBITS|VAL_OUTSEL) + + unsigned int request, param; +#define SPD_RQ_PASSTHROUGH 1 + + unsigned char cbitin[24]; + unsigned char ubitin[24]; + unsigned char cbitout[24]; + unsigned char ubitout[24]; + + unsigned int outsel; +#define OUTSEL_DIGITAL 1 +#define OUTSEL_ANALOG 2 +#define OUTSEL_BOTH (OUTSEL_DIGITAL|OUTSEL_ANALOG) + + int in_data; /* Audio/data if autodetectable by the receiver */ +#define IND_UNKNOWN 0 +#define IND_AUDIO 1 +#define IND_DATA 2 + + int in_locked; /* Receiver locked */ +#define LOCK_NOT_INDICATED 0 +#define LOCK_UNLOCKED 1 +#define LOCK_LOCKED 2 + + int in_quality; /* Input signal quality */ +#define IN_QUAL_NOT_INDICATED 0 +#define IN_QUAL_POOR 1 +#define IN_QUAL_GOOD 2 + + int in_vbit, out_vbit; /* V bits */ +#define VBIT_NOT_INDICATED 0 +#define VBIT_OFF 1 +#define VBIT_ON 2 + + unsigned int in_errors; /* Various input errro conditions */ +#define INERR_CRC 0x0001 +#define INERR_QCODE_CRC 0x0002 +#define INERR_PARITY 0x0004 +#define INERR_BIPHASE 0x0008 + + int srate_in, srate_out; + int bits_in, bits_out; + + int filler[32]; +} oss_digital_control; + +#define SNDCTL_DSP_READCTL __SIOWR('P', 26, oss_digital_control) +#define SNDCTL_DSP_WRITECTL __SIOWR('P', 27, oss_digital_control) + +/* + **************************************************************************** + * Sync groups for audio devices + */ +typedef struct oss_syncgroup +{ + int id; + int mode; + int filler[16]; +} oss_syncgroup; + +#define SNDCTL_DSP_SYNCGROUP __SIOWR('P', 28, oss_syncgroup) +#define SNDCTL_DSP_SYNCSTART __SIOW ('P', 29, int) + +/* + ************************************************************************** + * "cooked" mode enables software based conversions for sample rate, sample + * format (bits) and number of channels (mono/stereo). These conversions are + * required with some devices that support only one sample rate or just stereo + * to let the applications to use other formats. The cooked mode is enabled by + * default. However it's necessary to disable this mode when mmap() is used or + * when very deterministic timing is required. SNDCTL_DSP_COOKEDMODE is an + * optional call introduced in OSS 3.9.6f. It's _error return must be ignored_ + * since normally this call will return erno=EINVAL. + * + * SNDCTL_DSP_COOKEDMODE must be called immediately after open before doing + * anything else. Otherwise the call will not have any effect. + */ +#define SNDCTL_DSP_COOKEDMODE __SIOW ('P', 30, int) + +/* + ************************************************************************** + * SNDCTL_DSP_SILENCE and SNDCTL_DSP_SKIP are new calls in OSS 3.99.0 + * that can be used to implement pause/continue during playback (no effect + * on recording). + */ +#define SNDCTL_DSP_SILENCE __SIO ('P', 31) +#define SNDCTL_DSP_SKIP __SIO ('P', 32) +/* + **************************************************************************** + * Abort transfer (reset) functions for input and output + */ +#define SNDCTL_DSP_HALT_INPUT __SIO ('P', 33) +#define SNDCTL_DSP_RESET_INPUT SNDCTL_DSP_HALT_INPUT /* Old name */ +#define SNDCTL_DSP_HALT_OUTPUT __SIO ('P', 34) +#define SNDCTL_DSP_RESET_OUTPUT SNDCTL_DSP_HALT_OUTPUT /* Old name */ +/* + **************************************************************************** + * Low water level control + */ +#define SNDCTL_DSP_LOW_WATER __SIOW ('P', 34, int) + +/* + **************************************************************************** + * 64 bit pointer support. Only available in environments that support + * the 64 bit (long long) integer type. + */ +#ifndef OSS_NO_LONG_LONG +typedef struct +{ + long long samples; + int fifo_samples; + int filler[32]; /* For future use */ +} oss_count_t; + +#define SNDCTL_DSP_CURRENT_IPTR __SIOR ('P', 35, oss_count_t) +#define SNDCTL_DSP_CURRENT_OPTR __SIOR ('P', 36, oss_count_t) +#endif + +/* + **************************************************************************** + * Interface for selecting recording sources and playback output routings. + */ +#define SNDCTL_DSP_GET_RECSRC_NAMES __SIOR ('P', 37, oss_mixer_enuminfo) +#define SNDCTL_DSP_GET_RECSRC __SIOR ('P', 38, int) +#define SNDCTL_DSP_SET_RECSRC __SIOWR('P', 38, int) + +#define SNDCTL_DSP_GET_PLAYTGT_NAMES __SIOR ('P', 39, oss_mixer_enuminfo) +#define SNDCTL_DSP_GET_PLAYTGT __SIOR ('P', 40, int) +#define SNDCTL_DSP_SET_PLAYTGT __SIOWR('P', 40, int) +#define SNDCTL_DSP_GETRECVOL __SIOR ('P', 41, int) +#define SNDCTL_DSP_SETRECVOL __SIOWR('P', 41, int) + +/* + *************************************************************************** + * Some calls for setting the channel assignment with multi channel devices + * (see the manual for details). + */ +#ifndef OSS_NO_LONG_LONG +#define SNDCTL_DSP_GET_CHNORDER __SIOR ('P', 42, unsigned long long) +#define SNDCTL_DSP_SET_CHNORDER __SIOWR('P', 42, unsigned long long) +# define CHID_UNDEF 0 +# define CHID_L 1 +# define CHID_R 2 +# define CHID_C 3 +# define CHID_LFE 4 +# define CHID_LS 5 +# define CHID_RS 6 +# define CHID_LR 7 +# define CHID_RR 8 +#define CHNORDER_UNDEF 0x0000000000000000ULL +#define CHNORDER_NORMAL 0x0000000087654321ULL +#endif + +#define MAX_PEAK_CHANNELS 128 +typedef unsigned short oss_peaks_t[MAX_PEAK_CHANNELS]; +#define SNDCTL_DSP_GETIPEAKS __SIOR('P', 43, oss_peaks_t) +#define SNDCTL_DSP_GETOPEAKS __SIOR('P', 44, oss_peaks_t) + +#define SNDCTL_DSP_POLICY __SIOW('P', 45, int) /* See the manual */ + +/* + **************************************************************************** + * Few ioctl calls that are not official parts of OSS. They have been used + * by few freeware implementations of OSS. + */ +#define SNDCTL_DSP_GETCHANNELMASK __SIOWR('P', 64, int) +#define SNDCTL_DSP_BIND_CHANNEL __SIOWR('P', 65, int) +# define DSP_BIND_QUERY 0x00000000 +# define DSP_BIND_FRONT 0x00000001 +# define DSP_BIND_SURR 0x00000002 +# define DSP_BIND_CENTER_LFE 0x00000004 +# define DSP_BIND_HANDSET 0x00000008 +# define DSP_BIND_MIC 0x00000010 +# define DSP_BIND_MODEM1 0x00000020 +# define DSP_BIND_MODEM2 0x00000040 +# define DSP_BIND_I2S 0x00000080 +# define DSP_BIND_SPDIF 0x00000100 +# define DSP_BIND_REAR 0x00000200 + +#ifndef NO_LEGACY_MIXER +/* + **************************************************************************** + * IOCTL commands for the "legacy " /dev/mixer API (obsolete) + * + * Mixer controls + * + * There can be up to 20 different analog mixer channels. The + * SOUND_MIXER_NRDEVICES gives the currently supported maximum. + * The SOUND_MIXER_READ_DEVMASK returns a bitmask which tells + * the devices supported by the particular mixer. + * + * {!notice This "legacy" mixer API is obsolete. It has been superceded + * by a new one (see below). + */ + +#define SOUND_MIXER_NRDEVICES 28 +#define SOUND_MIXER_VOLUME 0 +#define SOUND_MIXER_BASS 1 +#define SOUND_MIXER_TREBLE 2 +#define SOUND_MIXER_SYNTH 3 +#define SOUND_MIXER_PCM 4 +#define SOUND_MIXER_SPEAKER 5 +#define SOUND_MIXER_LINE 6 +#define SOUND_MIXER_MIC 7 +#define SOUND_MIXER_CD 8 +#define SOUND_MIXER_IMIX 9 /* Recording monitor */ +#define SOUND_MIXER_ALTPCM 10 +#define SOUND_MIXER_RECLEV 11 /* Recording level */ +#define SOUND_MIXER_IGAIN 12 /* Input gain */ +#define SOUND_MIXER_OGAIN 13 /* Output gain */ +/* + * Some soundcards have three line level inputs (line, aux1 and aux2). + * Since each card manufacturer has assigned different meanings to + * these inputs, it's impractical to assign specific meanings + * (eg line, cd, synth etc.) to them. + */ +#define SOUND_MIXER_LINE1 14 /* Input source 1 (aux1) */ +#define SOUND_MIXER_LINE2 15 /* Input source 2 (aux2) */ +#define SOUND_MIXER_LINE3 16 /* Input source 3 (line) */ +#define SOUND_MIXER_DIGITAL1 17 /* Digital I/O 1 */ +#define SOUND_MIXER_DIGITAL2 18 /* Digital I/O 2 */ +#define SOUND_MIXER_DIGITAL3 19 /* Digital I/O 3 */ +#define SOUND_MIXER_PHONE 20 /* Phone */ +#define SOUND_MIXER_MONO 21 /* Mono Output */ +#define SOUND_MIXER_VIDEO 22 /* Video/TV (audio) in */ +#define SOUND_MIXER_RADIO 23 /* Radio in */ +#define SOUND_MIXER_DEPTH 24 /* Surround depth */ +#define SOUND_MIXER_REARVOL 25 /* Rear/Surround speaker vol */ +#define SOUND_MIXER_CENTERVOL 26 /* Center/LFE speaker vol */ +#define SOUND_MIXER_SIDEVOL 27 /* Side-Surround (8speaker) vol */ + +/* + * Warning: SOUND_MIXER_SURRVOL is an old name of SOUND_MIXER_SIDEVOL. + * They are both assigned to the same mixer control. Don't + * use both control names in the same program/driver. + */ +#define SOUND_MIXER_SURRVOL SOUND_MIXER_SIDEVOL + +/* Some on/off settings (SOUND_SPECIAL_MIN - SOUND_SPECIAL_MAX) */ +/* Not counted to SOUND_MIXER_NRDEVICES, but use the same number space */ +#define SOUND_ONOFF_MIN 28 +#define SOUND_ONOFF_MAX 30 + +/* Note! Number 31 cannot be used since the sign bit is reserved */ +#define SOUND_MIXER_NONE 31 + +/* + * The following unsupported macros are no longer functional. + * Use SOUND_MIXER_PRIVATE# macros in future. + */ +#define SOUND_MIXER_ENHANCE SOUND_MIXER_NONE +#define SOUND_MIXER_MUTE SOUND_MIXER_NONE +#define SOUND_MIXER_LOUD SOUND_MIXER_NONE + +#define SOUND_DEVICE_LABELS \ + {"Vol ", "Bass ", "Treble", "Synth", "Pcm ", "Speaker ", "Line ", \ + "Mic ", "CD ", "Mix ", "Pcm2 ", "Rec ", "IGain", "OGain", \ + "Aux1", "Aux2", "Aux3", "Digital1", "Digital2", "Digital3", \ + "Phone", "Mono", "Video", "Radio", "Depth", \ + "Rear", "Center", "Side"} + +#define SOUND_DEVICE_NAMES \ + {"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \ + "mic", "cd", "mix", "pcm2", "rec", "igain", "ogain", \ + "aux1", "aux2", "aux3", "dig1", "dig2", "dig3", \ + "phone", "mono", "video", "radio", "depth", \ + "rear", "center", "side"} + +/* Device bitmask identifiers */ + +#define SOUND_MIXER_RECSRC 0xff /* Arg contains a bit for each recording source */ +#define SOUND_MIXER_DEVMASK 0xfe /* Arg contains a bit for each supported device */ +#define SOUND_MIXER_RECMASK 0xfd /* Arg contains a bit for each supported recording source */ +#define SOUND_MIXER_CAPS 0xfc +# define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */ +# define SOUND_CAP_NOLEGACY 0x00000004 /* For internal use only */ +# define SOUND_CAP_NORECSRC 0x00000008 +#define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */ + +/* OSS/Free ONLY */ +#define SOUND_MIXER_OUTSRC 0xfa /* Arg contains a bit for each input source to output */ +#define SOUND_MIXER_OUTMASK 0xf9 /* Arg contains a bit for each supported input source to output */ +/* OSS/Free ONLY */ + +/* Device mask bits */ + +#define SOUND_MASK_VOLUME (1 << SOUND_MIXER_VOLUME) +#define SOUND_MASK_BASS (1 << SOUND_MIXER_BASS) +#define SOUND_MASK_TREBLE (1 << SOUND_MIXER_TREBLE) +#define SOUND_MASK_SYNTH (1 << SOUND_MIXER_SYNTH) +#define SOUND_MASK_PCM (1 << SOUND_MIXER_PCM) +#define SOUND_MASK_SPEAKER (1 << SOUND_MIXER_SPEAKER) +#define SOUND_MASK_LINE (1 << SOUND_MIXER_LINE) +#define SOUND_MASK_MIC (1 << SOUND_MIXER_MIC) +#define SOUND_MASK_CD (1 << SOUND_MIXER_CD) +#define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX) +#define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM) +#define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV) +#define SOUND_MASK_IGAIN (1 << SOUND_MIXER_IGAIN) +#define SOUND_MASK_OGAIN (1 << SOUND_MIXER_OGAIN) +#define SOUND_MASK_LINE1 (1 << SOUND_MIXER_LINE1) +#define SOUND_MASK_LINE2 (1 << SOUND_MIXER_LINE2) +#define SOUND_MASK_LINE3 (1 << SOUND_MIXER_LINE3) +#define SOUND_MASK_DIGITAL1 (1 << SOUND_MIXER_DIGITAL1) +#define SOUND_MASK_DIGITAL2 (1 << SOUND_MIXER_DIGITAL2) +#define SOUND_MASK_DIGITAL3 (1 << SOUND_MIXER_DIGITAL3) +#define SOUND_MASK_MONO (1 << SOUND_MIXER_MONO) +#define SOUND_MASK_PHONE (1 << SOUND_MIXER_PHONE) +#define SOUND_MASK_RADIO (1 << SOUND_MIXER_RADIO) +#define SOUND_MASK_VIDEO (1 << SOUND_MIXER_VIDEO) +#define SOUND_MASK_DEPTH (1 << SOUND_MIXER_DEPTH) +#define SOUND_MASK_REARVOL (1 << SOUND_MIXER_REARVOL) +#define SOUND_MASK_CENTERVOL (1 << SOUND_MIXER_CENTERVOL) +#define SOUND_MASK_SIDEVOL (1 << SOUND_MIXER_SIDEVOL) + +/* Note! SOUND_MASK_SURRVOL is alias of SOUND_MASK_SIDEVOL */ +#define SOUND_MASK_SURRVOL (1 << SOUND_MIXER_SIDEVOL) + +/* Obsolete macros */ +#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE) +#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE) +#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD) + +#define MIXER_READ(dev) __SIOR('M', dev, int) +#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME) +#define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS) +#define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE) +#define SOUND_MIXER_READ_SYNTH MIXER_READ(SOUND_MIXER_SYNTH) +#define SOUND_MIXER_READ_PCM MIXER_READ(SOUND_MIXER_PCM) +#define SOUND_MIXER_READ_SPEAKER MIXER_READ(SOUND_MIXER_SPEAKER) +#define SOUND_MIXER_READ_LINE MIXER_READ(SOUND_MIXER_LINE) +#define SOUND_MIXER_READ_MIC MIXER_READ(SOUND_MIXER_MIC) +#define SOUND_MIXER_READ_CD MIXER_READ(SOUND_MIXER_CD) +#define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX) +#define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM) +#define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV) +#define SOUND_MIXER_READ_IGAIN MIXER_READ(SOUND_MIXER_IGAIN) +#define SOUND_MIXER_READ_OGAIN MIXER_READ(SOUND_MIXER_OGAIN) +#define SOUND_MIXER_READ_LINE1 MIXER_READ(SOUND_MIXER_LINE1) +#define SOUND_MIXER_READ_LINE2 MIXER_READ(SOUND_MIXER_LINE2) +#define SOUND_MIXER_READ_LINE3 MIXER_READ(SOUND_MIXER_LINE3) + +/* Obsolete macros */ +#define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE) +#define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE) +#define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD) + +#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC) +#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK) +#define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK) +#define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS) +#define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS) + +#define MIXER_WRITE(dev) __SIOWR('M', dev, int) +#define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME) +#define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS) +#define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE) +#define SOUND_MIXER_WRITE_SYNTH MIXER_WRITE(SOUND_MIXER_SYNTH) +#define SOUND_MIXER_WRITE_PCM MIXER_WRITE(SOUND_MIXER_PCM) +#define SOUND_MIXER_WRITE_SPEAKER MIXER_WRITE(SOUND_MIXER_SPEAKER) +#define SOUND_MIXER_WRITE_LINE MIXER_WRITE(SOUND_MIXER_LINE) +#define SOUND_MIXER_WRITE_MIC MIXER_WRITE(SOUND_MIXER_MIC) +#define SOUND_MIXER_WRITE_CD MIXER_WRITE(SOUND_MIXER_CD) +#define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX) +#define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM) +#define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV) +#define SOUND_MIXER_WRITE_IGAIN MIXER_WRITE(SOUND_MIXER_IGAIN) +#define SOUND_MIXER_WRITE_OGAIN MIXER_WRITE(SOUND_MIXER_OGAIN) +#define SOUND_MIXER_WRITE_LINE1 MIXER_WRITE(SOUND_MIXER_LINE1) +#define SOUND_MIXER_WRITE_LINE2 MIXER_WRITE(SOUND_MIXER_LINE2) +#define SOUND_MIXER_WRITE_LINE3 MIXER_WRITE(SOUND_MIXER_LINE3) + +/* Obsolete macros */ +#define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE) +#define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE) +#define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD) + +#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC) + +typedef struct mixer_info /* OBSOLETE */ +{ + char id[16]; + char name[32]; + int modify_counter; + int card_number; + int port_number; + char handle[32]; +} mixer_info; + +/* SOUND_MIXER_INFO is obsolete - use SNDCTL_MIXERINFO instead */ +#define SOUND_MIXER_INFO __SIOR ('M', 101, mixer_info) + +/* + * Two ioctls for special souncard function (OSS/Free only) + */ +#define SOUND_MIXER_AGC _SIOWR('M', 103, int) +#define SOUND_MIXER_3DSE _SIOWR('M', 104, int) +/* + * The SOUND_MIXER_PRIVATE# commands can be redefined by low level drivers. + * These features can be used when accessing device specific features. + */ +#define SOUND_MIXER_PRIVATE1 __SIOWR('M', 111, int) +#define SOUND_MIXER_PRIVATE2 __SIOWR('M', 112, int) +#define SOUND_MIXER_PRIVATE3 __SIOWR('M', 113, int) +#define SOUND_MIXER_PRIVATE4 __SIOWR('M', 114, int) +#define SOUND_MIXER_PRIVATE5 __SIOWR('M', 115, int) + +/* The following two controls were never implemented and they should not be used. */ +#define SOUND_MIXER_READ_MAINVOL __SIOR ('M', 116, int) +#define SOUND_MIXER_WRITE_MAINVOL __SIOWR('M', 116, int) + +/* + * SOUND_MIXER_GETLEVELS and SOUND_MIXER_SETLEVELS calls can be used + * for querying current mixer settings from the driver and for loading + * default volume settings _prior_ activating the mixer (loading + * doesn't affect current state of the mixer hardware). These calls + * are for internal use by the driver software only. + */ + +typedef struct mixer_vol_table +{ + int num; /* Index to volume table */ + char name[32]; + int levels[32]; +} mixer_vol_table; + +#define SOUND_MIXER_GETLEVELS __SIOWR('M', 116, mixer_vol_table) +#define SOUND_MIXER_SETLEVELS __SIOWR('M', 117, mixer_vol_table) + +#define OSS_GETVERSION __SIOR ('M', 118, int) + +/* + * Calls to set/get the recording gain for the currently active + * recording source. These calls automatically map to the right control. + * Note that these calls are not supported by all drivers. In this case + * the call will return -1 with errno set to EINVAL + * + * The _MONGAIN work in similar way but set/get the monitoring gain for + * the currently selected recording source. + */ +#define SOUND_MIXER_READ_RECGAIN __SIOR ('M', 119, int) +#define SOUND_MIXER_WRITE_RECGAIN __SIOWR('M', 119, int) +#define SOUND_MIXER_READ_MONGAIN __SIOR ('M', 120, int) +#define SOUND_MIXER_WRITE_MONGAIN __SIOWR('M', 120, int) + +/* The following call is for driver development time purposes. It's not + * present in any released drivers. + */ +typedef unsigned char oss_reserved_t[512]; +#define SOUND_MIXER_RESERVED __SIOWR('M', 121, oss_reserved_t) +#endif /* ifndef NO_LEGACY_MIXER */ + +/* + ************************************************************************* + * The "new" mixer API of OSS 4.0 and later. + * + * This improved mixer API makes it possible to access every possible feature + * of every possible device. However you should read the mixer programming + * section of the OSS API Developer's Manual. There is no chance that you + * could use this interface correctly just by examining this header. + */ + +typedef struct oss_sysinfo +{ + char product[32]; /* For example OSS/Free, OSS/Linux or OSS/Solaris */ + char version[32]; /* For example 4.0a */ + int versionnum; /* See OSS_GETVERSION */ + char options[128]; /* Reserved */ + + int numaudios; /* # of audio/dsp devices */ + int openedaudio[8]; /* Bit mask telling which audio devices are busy */ + + int numsynths; /* # of availavle synth devices */ + int nummidis; /* # of available MIDI ports */ + int numtimers; /* # of available timer devices */ + int nummixers; /* # of mixer devices */ + + int openedmidi[8]; /* Bit mask telling which midi devices are busy */ + int numcards; /* Number of sound cards in the system */ + int numaudioengines; /* Number of audio engines in the system */ + int filler[240]; /* For future expansion (set to -1) */ +} oss_sysinfo; + +typedef struct oss_mixext +{ + int dev; /* Mixer device number */ + int ctrl; /* Controller number */ + int type; /* Entry type */ +# define MIXT_DEVROOT 0 /* Device root entry */ +# define MIXT_GROUP 1 /* Controller group */ +# define MIXT_ONOFF 2 /* OFF (0) or ON (1) */ +# define MIXT_ENUM 3 /* Enumerated (0 to maxvalue) */ +# define MIXT_MONOSLIDER 4 /* Mono slider (0 to 255) */ +# define MIXT_STEREOSLIDER 5 /* Stereo slider (dual 0 to 255) */ +# define MIXT_MESSAGE 6 /* (Readable) textual message */ +# define MIXT_MONOVU 7 /* VU meter value (mono) */ +# define MIXT_STEREOVU 8 /* VU meter value (stereo) */ +# define MIXT_MONOPEAK 9 /* VU meter peak value (mono) */ +# define MIXT_STEREOPEAK 10 /* VU meter peak value (stereo) */ +# define MIXT_RADIOGROUP 11 /* Radio button group */ +# define MIXT_MARKER 12 /* Separator between normal and extension entries */ +# define MIXT_VALUE 13 /* Decimal value entry */ +# define MIXT_HEXVALUE 14 /* Hexadecimal value entry */ +# define MIXT_MONODB 15 /* OBSOLETE */ +# define MIXT_STEREODB 16 /* OBSOLETE */ +# define MIXT_SLIDER 17 /* Slider (mono) with full (31 bit) postitive integer range */ +# define MIXT_3D 18 + +/* + * Sliders with range expanded to 15 bits per channel (0-32767) + */ +# define MIXT_MONOSLIDER16 19 +# define MIXT_STEREOSLIDER16 20 + + /* Possible value range (minvalue to maxvalue) */ + /* Note that maxvalue may also be smaller than minvalue */ + int maxvalue; + int minvalue; + + int flags; +# define MIXF_READABLE 0x00000001 /* Has readable value */ +# define MIXF_WRITEABLE 0x00000002 /* Has writeable value */ +# define MIXF_POLL 0x00000004 /* May change itself */ +# define MIXF_HZ 0x00000008 /* Herz scale */ +# define MIXF_STRING 0x00000010 /* Use dynamic extensions for value */ +# define MIXF_DYNAMIC 0x00000010 /* Supports dynamic extensions */ +# define MIXF_OKFAIL 0x00000020 /* Interpret value as 1=OK, 0=FAIL */ +# define MIXF_FLAT 0x00000040 /* Flat vertical space requirements */ +# define MIXF_LEGACY 0x00000080 /* Legacy mixer control group */ +# define MIXF_CENTIBEL 0x00000100 /* Centibel (0.1 dB) step size */ +# define MIXF_DECIBEL 0x00000200 /* Step size of 1 dB */ +# define MIXF_MAINVOL 0x00000400 /* Main volume control */ +# define MIXF_PCMVOL 0x00000800 /* PCM output volume control */ +# define MIXF_RECVOL 0x00001000 /* PCM recording volume control */ + char id[16]; /* Mnemonic ID (mainly for internal use) */ + int parent; /* Entry# of parent (group) node (-1 if root) */ + + int dummy; /* Internal use */ + + int timestamp; + + char data[64]; /* Misc data (entry type dependent) */ + unsigned char enum_present[32]; /* Mask of allowed enum values */ + int control_no; /* SOUND_MIXER_VOLUME..SOUND_MIXER_MIDI */ + /* (-1 means not indicated) */ + +/* + * The desc field is reserved for internal purposes of OSS. It should not be + * used by applications. + */ + unsigned int desc; +#define MIXEXT_SCOPE_MASK 0x0000003f +#define MIXEXT_SCOPE_OTHER 0x00000000 +#define MIXEXT_SCOPE_INPUT 0x00000001 +#define MIXEXT_SCOPE_OUTPUT 0x00000002 +#define MIXEXT_SCOPE_MONITOR 0x00000003 +#define MIXEXT_SCOPE_RECSWITCH 0x00000004 + + char extname[32]; + int update_counter; + int filler[7]; +} oss_mixext; + +typedef struct oss_mixext_root +{ + char id[16]; + char name[48]; +} oss_mixext_root; + +typedef struct oss_mixer_value +{ + int dev; + int ctrl; + int value; + int flags; /* Reserved for future use. Initialize to 0 */ + int timestamp; /* Must be set to oss_mixext.timestamp */ + int filler[8]; /* Reserved for future use. Initialize to 0 */ +} oss_mixer_value; + +#define OSS_ENUM_MAXVALUE 255 +typedef struct oss_mixer_enuminfo +{ + int dev; + int ctrl; + int nvalues; + int version; /* Read the manual */ + short strindex[OSS_ENUM_MAXVALUE]; + char strings[3000]; +} oss_mixer_enuminfo; + +#define OPEN_READ PCM_ENABLE_INPUT +#define OPEN_WRITE PCM_ENABLE_OUTPUT +#define OPEN_READWRITE (OPEN_READ|OPEN_WRITE) + +typedef struct oss_audioinfo +{ + int dev; /* Audio device number */ + char name[64]; + int busy; /* 0, OPEN_READ, OPEN_WRITE or OPEN_READWRITE */ + int pid; + int caps; /* PCM_CAP_INPUT, PCM_CAP_OUTPUT */ + int iformats, oformats; + int magic; /* Reserved for internal use */ + char cmd[64]; /* Command using the device (if known) */ + int card_number; + int port_number; + int mixer_dev; + int legacy_device; /* Obsolete field. Replaced by devnode */ + int enabled; /* 1=enabled, 0=device not ready at this moment */ + int flags; /* For internal use only - no practical meaning */ + int min_rate, max_rate; /* Sample rate limits */ + int min_channels, max_channels; /* Number of channels supported */ + int binding; /* DSP_BIND_FRONT, etc. 0 means undefined */ + int rate_source; + char handle[32]; +#define OSS_MAX_SAMPLE_RATES 20 /* Cannot be changed */ + unsigned int nrates, rates[OSS_MAX_SAMPLE_RATES]; /* Please read the manual before using these */ + oss_longname_t song_name; /* Song name (if given) */ + oss_label_t label; /* Device label (if given) */ + int latency; /* In usecs, -1=unknown */ + oss_devnode_t devnode; /* Device special file name (absolute path) */ + int next_play_engine; /* Read the documentation for more info */ + int next_rec_engine; /* Read the documentation for more info */ + int filler[184]; +} oss_audioinfo; + +typedef struct oss_mixerinfo +{ + int dev; + char id[16]; + char name[32]; + int modify_counter; + int card_number; + int port_number; + char handle[32]; + int magic; /* Reserved */ + int enabled; /* Reserved */ + int caps; +#define MIXER_CAP_VIRTUAL 0x00000001 +#define MIXER_CAP_LAYOUT_B 0x00000002 /* For internal use only */ +#define MIXER_CAP_NARROW 0x00000004 /* Conserve horiz space */ + int flags; /* Reserved */ + int nrext; + /* + * The priority field can be used to select the default (motherboard) + * mixer device. The mixer with the highest priority is the + * most preferred one. -2 or less means that this device cannot be used + * as the default mixer. + */ + int priority; + oss_devnode_t devnode; /* Device special file name (absolute path) */ + int legacy_device; + int filler[245]; /* Reserved */ +} oss_mixerinfo; + +typedef struct oss_midi_info +{ + int dev; /* Midi device number */ + char name[64]; + int busy; /* 0, OPEN_READ, OPEN_WRITE or OPEN_READWRITE */ + int pid; + char cmd[64]; /* Command using the device (if known) */ + int caps; +#define MIDI_CAP_MPU401 0x00000001 /**** OBSOLETE ****/ +#define MIDI_CAP_INPUT 0x00000002 +#define MIDI_CAP_OUTPUT 0x00000004 +#define MIDI_CAP_INOUT (MIDI_CAP_INPUT|MIDI_CAP_OUTPUT) +#define MIDI_CAP_VIRTUAL 0x00000008 /* Pseudo device */ +#define MIDI_CAP_MTCINPUT 0x00000010 /* Supports SNDCTL_MIDI_MTCINPUT */ +#define MIDI_CAP_CLIENT 0x00000020 /* Virtual client side device */ +#define MIDI_CAP_SERVER 0x00000040 /* Virtual server side device */ +#define MIDI_CAP_INTERNAL 0x00000080 /* Internal (synth) device */ +#define MIDI_CAP_EXTERNAL 0x00000100 /* external (MIDI port) device */ +#define MIDI_CAP_PTOP 0x00000200 /* Point to point link to one device */ +#define MIDI_CAP_MTC 0x00000400 /* MTC/SMPTE (control) device */ + int magic; /* Reserved for internal use */ + int card_number; + int port_number; + int enabled; /* 1=enabled, 0=device not ready at this moment */ + int flags; /* For internal use only - no practical meaning */ + char handle[32]; + oss_longname_t song_name; /* Song name (if known) */ + oss_label_t label; /* Device label (if given) */ + int latency; /* In usecs, -1=unknown */ + oss_devnode_t devnode; /* Device special file name (absolute path) */ + int legacy_device; /* Legacy device mapping */ + int filler[235]; +} oss_midi_info; + +typedef struct oss_card_info +{ + int card; + char shortname[16]; + char longname[128]; + int flags; + int filler[256]; +} oss_card_info; + +#define SNDCTL_SYSINFO __SIOR ('X', 1, oss_sysinfo) +#define OSS_SYSINFO SNDCTL_SYSINFO /* Old name */ + +#define SNDCTL_MIX_NRMIX __SIOR ('X', 2, int) +#define SNDCTL_MIX_NREXT __SIOWR('X', 3, int) +#define SNDCTL_MIX_EXTINFO __SIOWR('X', 4, oss_mixext) +#define SNDCTL_MIX_READ __SIOWR('X', 5, oss_mixer_value) +#define SNDCTL_MIX_WRITE __SIOWR('X', 6, oss_mixer_value) + +#define SNDCTL_AUDIOINFO __SIOWR('X', 7, oss_audioinfo) +#define SNDCTL_MIX_ENUMINFO __SIOWR('X', 8, oss_mixer_enuminfo) +#define SNDCTL_MIDIINFO __SIOWR('X', 9, oss_midi_info) +#define SNDCTL_MIXERINFO __SIOWR('X',10, oss_mixerinfo) +#define SNDCTL_CARDINFO __SIOWR('X',11, oss_card_info) +#define SNDCTL_ENGINEINFO __SIOWR('X',12, oss_audioinfo) +#define SNDCTL_AUDIOINFO_EX __SIOWR('X',13, oss_audioinfo) + +/* ioctl codes 'X', 200-255 are reserved for internal use */ + +/* + * Few more "globally" available ioctl calls. + */ +#define SNDCTL_SETSONG __SIOW ('Y', 2, oss_longname_t) +#define SNDCTL_GETSONG __SIOR ('Y', 2, oss_longname_t) +#define SNDCTL_SETNAME __SIOW ('Y', 3, oss_longname_t) +#define SNDCTL_SETLABEL __SIOW ('Y', 4, oss_label_t) +#define SNDCTL_GETLABEL __SIOR ('Y', 4, oss_label_t) +/* + * The "new" mixer API definitions end here. + *************************************** + */ + +/* + ********************************************************* + * Few routines that are included in -lOSSlib + * + * At this moment this interface is not used. OSSlib contains just + * stubs that call the related system calls directly. + */ +#ifdef OSSLIB +extern int osslib_open (const char *path, int flags, int dummy); +extern void osslib_close (int fd); +extern int osslib_write (int fd, const void *buf, int count); +extern int osslib_read (int fd, void *buf, int count); +extern int osslib_ioctl (int fd, unsigned int request, void *arg); +#else +# define osslib_open open +# define osslib_close close +# define osslib_write write +# define osslib_read read +# define osslib_ioctl ioctl +#endif + +#if 1 +#define SNDCTL_DSP_NONBLOCK __SIO ('P',14) /* Obsolete. Not supported any more */ +#endif + +#if 1 +/* + * Some obsolete macros that are not part of Open Sound System API. + */ +#define SOUND_PCM_READ_RATE SOUND_PCM_READ_RATE_is_obsolete +#define SOUND_PCM_READ_BITS SOUND_PCM_READ_BITS_is_obsolete +#define SOUND_PCM_READ_CHANNELS SOUND_PCM_READ_CHANNELS_is_obsolete +#define SOUND_PCM_WRITE_RATE SOUND_PCM_WRITE_RATE_is_obsolet_use_SNDCTL_DSP_SPEED_instead +#define SOUND_PCM_WRITE_CHANNELS SOUND_PCM_WRITE_CHANNELS_is_obsolete_use_SNDCTL_DSP_CHANNELS_instead +#define SOUND_PCM_WRITE_BITS SOUND_PCM_WRITE_BITS_is_obsolete_use_SNDCTL_DSP_SETFMT_instead +#define SOUND_PCM_POST SOUND_PCM_POST_is_obsolete_use_SNDCTL_DSP_POST_instead +#define SOUND_PCM_RESET SOUND_PCM_RESET_is_obsolete_use_SNDCTL_DSP_HALT_instead +#define SOUND_PCM_SYNC SOUND_PCM_SYNC_is_obsolete_use_SNDCTL_DSP_SYNC_instead +#define SOUND_PCM_SUBDIVIDE SOUND_PCM_SUBDIVIDE_is_obsolete_use_SNDCTL_DSP_SUBDIVIDE_instead +#define SOUND_PCM_SETFRAGMENT SOUND_PCM_SETFRAGMENT_is_obsolete_use_SNDCTL_DSP_SETFRAGMENT_instead +#define SOUND_PCM_GETFMTS SOUND_PCM_GETFMTS_is_obsolete_use_SNDCTL_DSP_GETFMTS_instead +#define SOUND_PCM_SETFMT SOUND_PCM_SETFMT_is_obsolete_use_SNDCTL_DSP_SETFMT_instead +#define SOUND_PCM_GETOSPACE SOUND_PCM_GETOSPACE_is_obsolete_use_SNDCTL_DSP_GETOSPACE_instead +#define SOUND_PCM_GETISPACE SOUND_PCM_GETISPACE_is_obsolete_use_SNDCTL_DSP_GETISPACE_instead +#define SOUND_PCM_NONBLOCK SOUND_PCM_NONBLOCK_is_obsolete_use_SNDCTL_DSP_NONBLOCK_instead +#define SOUND_PCM_GETCAPS SOUND_PCM_GETCAPS_is_obsolete_use_SNDCTL_DSP_GETCAPS_instead +#define SOUND_PCM_GETTRIGGER SOUND_PCM_GETTRIGGER_is_obsolete_use_SNDCTL_DSP_GETTRIGGER_instead +#define SOUND_PCM_SETTRIGGER SOUND_PCM_SETTRIGGER_is_obsolete_use_SNDCTL_DSP_SETTRIGGER_instead +#define SOUND_PCM_SETSYNCRO SOUND_PCM_SETSYNCRO_is_obsolete_use_SNDCTL_DSP_SETSYNCRO_instead +#define SOUND_PCM_GETIPTR SOUND_PCM_GETIPTR_is_obsolete_use_SNDCTL_DSP_GETIPTR_instead +#define SOUND_PCM_GETOPTR SOUND_PCM_GETOPTR_is_obsolete_use_SNDCTL_DSP_GETOPTR_instead +#define SOUND_PCM_MAPINBUF SOUND_PCM_MAPINBUF_is_obsolete_use_SNDCTL_DSP_MAPINBUF_instead +#define SOUND_PCM_MAPOUTBUF SOUND_PCM_MAPOUTBUF_is_obsolete_use_SNDCTL_DSP_MAPOUTBUF_instead +#endif + +#endif diff --git a/oss/soundcard.h b/oss/soundcard.h deleted file mode 100644 index e8fc9f6..0000000 --- a/oss/soundcard.h +++ /dev/null @@ -1,2061 +0,0 @@ -#ifndef SOUNDCARD_H -#define SOUNDCARD_H -/* - **************************************************************************** - * Copyright by 4Front Technologies 1993-2006 - * - ****************************************************************************** - * Modifications to this file are NOT allowed. This header file controls the - * OSS API. For compatibility reasons only 4Front Technologies can make changes - * to the definitions. If you have any questions, please contact - * hannu@opensound.com. - ****************************************************************************** - * - * Redistribution and use in source and binary forms, without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - **************************************************************************** - */ -/* - * Purpose: The C/C++ header file that defines the OSS API. - * Description: - * This header file contains all the declarations required to compile OSS - * programs. The latest version is always installed together with OSS - * use of the latest version is strongly recommended. - * - * {!notice This header file contains many obsolete definitions - * (for compatibility with older applications that still ned them). - * Do not use this file as a reference manual of OSS. - * Please check the OSS Programmer's guide for descriptions - * of the supported API details (http://www.opensound.com/pguide).} - */ - -#if defined(__cplusplus) -#define EXTERNC extern "C" -#else -#define EXTERNC extern -#endif /* EXTERN_C_WRAPPERS */ - -#define OSS_VERSION 0x040002 - -#define SOUND_VERSION OSS_VERSION -#define OPEN_SOUND_SYSTEM - -#if defined(__hpux) && !defined(_HPUX_SOURCE) -# error "-D_HPUX_SOURCE must be used when compiling OSS applications" -#endif - -#ifdef __hpux -#include -#endif - -#ifdef linux -/* In Linux we need to be prepared for cross compiling */ -#include -#else -# ifdef __FreeBSD__ -# include -# else -# include -# endif -#endif - -#ifndef __SIOWR -#if defined(__hpux) || (defined(_IOWR) && (defined(_AIX) || (!defined(sun) && !defined(sparc) && !defined(__INCioctlh) && !defined(__Lynx__)))) - -/* - * Make sure the ioctl macros are compatible with the ones already used - * by this operating system. - */ -#define SIOCPARM_MASK IOCPARM_MASK -#define SIOC_VOID IOC_VOID -#define SIOC_OUT IOC_OUT -#define SIOC_IN IOC_IN -#define SIOC_INOUT IOC_INOUT -#define __SIOC_SIZE _IOC_SIZE -#define __SIOC_DIR _IOC_DIR -#define __SIOC_NONE _IOC_NONE -#define __SIOC_READ _IOC_READ -#define __SIOC_WRITE _IOC_WRITE -#define __SIO _IO -#define __SIOR _IOR -#define __SIOW _IOW -#define __SIOWR _IOWR -#else - -/* #define SIOCTYPE (0xff<<8) */ -#define SIOCPARM_MASK 0x1fff /* parameters must be < 8192 bytes */ -#define SIOC_VOID 0x00000000 /* no parameters */ -#define SIOC_OUT 0x20000000 /* copy out parameters */ -#define SIOC_IN 0x40000000 /* copy in parameters */ -#define SIOC_INOUT (SIOC_IN|SIOC_OUT) - -#define __SIO(x,y) ((int)(SIOC_VOID|(x<<8)|y)) -#define __SIOR(x,y,t) ((int)(SIOC_OUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) -#define __SIOW(x,y,t) ((int)(SIOC_IN|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) -#define __SIOWR(x,y,t) ((int)(SIOC_INOUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y)) -#define __SIOC_SIZE(x) ((x>>16)&SIOCPARM_MASK) -#define __SIOC_DIR(x) (x & 0xf0000000) -#define __SIOC_NONE SIOC_VOID -#define __SIOC_READ SIOC_OUT -#define __SIOC_WRITE SIOC_IN -# endif /* _IOWR */ -#endif /* !__SIOWR */ - -#define OSS_LONGNAME_SIZE 64 -#define OSS_LABEL_SIZE 16 -#define OSS_DEVNODE_SIZE 32 -typedef char oss_longname_t[OSS_LONGNAME_SIZE]; -typedef char oss_label_t[OSS_LABEL_SIZE]; -typedef char oss_devnode_t[OSS_DEVNODE_SIZE]; - -#ifndef DISABLE_SEQUENCER -/* - **************************************************************************** - * IOCTL Commands for /dev/sequencer and /dev/music (AKA /dev/sequencer2) - * - * Note that this interface is obsolete and no longer developed. New - * applications should use /dev/midi instead. - ****************************************************************************/ -#define SNDCTL_SEQ_RESET __SIO ('Q', 0) -#define SNDCTL_SEQ_SYNC __SIO ('Q', 1) -#define SNDCTL_SYNTH_INFO __SIOWR('Q', 2, struct synth_info) -#define SNDCTL_SEQ_CTRLRATE __SIOWR('Q', 3, int) /* Set/get timer resolution (HZ) */ -#define SNDCTL_SEQ_GETOUTCOUNT __SIOR ('Q', 4, int) -#define SNDCTL_SEQ_GETINCOUNT __SIOR ('Q', 5, int) -#define SNDCTL_SEQ_PERCMODE __SIOW ('Q', 6, int) -#define SNDCTL_FM_LOAD_INSTR __SIOW ('Q', 7, struct sbi_instrument) /* Obsolete. Don't use!!!!!! */ -#define SNDCTL_SEQ_TESTMIDI __SIOW ('Q', 8, int) -#define SNDCTL_SEQ_RESETSAMPLES __SIOW ('Q', 9, int) -#define SNDCTL_SEQ_NRSYNTHS __SIOR ('Q',10, int) -#define SNDCTL_SEQ_NRMIDIS __SIOR ('Q',11, int) -#define SNDCTL_MIDI_INFO __SIOWR('Q',12, struct midi_info) /* OBSOLETE - use SNDCTL_MIDIINFO instead */ -#define SNDCTL_SEQ_THRESHOLD __SIOW ('Q',13, int) -#define SNDCTL_SYNTH_MEMAVL __SIOWR('Q',14, int) /* in=dev#, out=memsize */ -#define SNDCTL_FM_4OP_ENABLE __SIOW ('Q',15, int) /* in=dev# */ -#define SNDCTL_SEQ_PANIC __SIO ('Q',17) -#define SNDCTL_SEQ_OUTOFBAND __SIOW ('Q',18, struct seq_event_rec) -#define SNDCTL_SEQ_GETTIME __SIOR ('Q',19, int) -#define SNDCTL_SYNTH_ID __SIOWR('Q',20, struct synth_info) -#define SNDCTL_SYNTH_CONTROL __SIOWR('Q',21, struct synth_control) -#define SNDCTL_SYNTH_REMOVESAMPLE __SIOWR('Q',22, struct remove_sample) /* Reserved for future use */ -#define SNDCTL_SEQ_TIMING_ENABLE __SIO ('Q', 23) /* Enable incoming MIDI timing messages */ -#define SNDCTL_SEQ_ACTSENSE_ENABLE __SIO ('Q', 24) /* Enable incoming active sensing messages */ -#define SNDCTL_SEQ_RT_ENABLE __SIO ('Q', 25) /* Enable other incoming realtime messages */ - -typedef struct synth_control -{ - int devno; /* Synthesizer # */ - char data[4000]; /* Device spesific command/data record */ -} synth_control; - -typedef struct remove_sample -{ - int devno; /* Synthesizer # */ - int bankno; /* MIDI bank # (0=General MIDI) */ - int instrno; /* MIDI instrument number */ -} remove_sample; - -typedef struct seq_event_rec -{ - unsigned char arr[8]; -} seq_event_rec; - -#define SNDCTL_TMR_TIMEBASE __SIOWR('T', 1, int) -#define SNDCTL_TMR_START __SIO ('T', 2) -#define SNDCTL_TMR_STOP __SIO ('T', 3) -#define SNDCTL_TMR_CONTINUE __SIO ('T', 4) -#define SNDCTL_TMR_TEMPO __SIOWR('T', 5, int) -#define SNDCTL_TMR_SOURCE __SIOWR('T', 6, int) -# define TMR_INTERNAL 0x00000001 -# define TMR_EXTERNAL 0x00000002 -# define TMR_MODE_MIDI 0x00000010 -# define TMR_MODE_FSK 0x00000020 -# define TMR_MODE_CLS 0x00000040 -# define TMR_MODE_SMPTE 0x00000080 -#define SNDCTL_TMR_METRONOME __SIOW ('T', 7, int) -#define SNDCTL_TMR_SELECT __SIOW ('T', 8, int) - -/* - * Sample loading mechanism for internal synthesizers (/dev/sequencer) - * (for the .PAT format). - */ - -struct patch_info -{ - unsigned short key; /* Use WAVE_PATCH here */ -#define WAVE_PATCH _PATCHKEY(0x04) -#define GUS_PATCH WAVE_PATCH -#define WAVEFRONT_PATCH _PATCHKEY(0x06) - - short device_no; /* Synthesizer number */ - short instr_no; /* Midi pgm# */ - - unsigned int mode; -/* - * The least significant byte has the same format than the GUS .PAT - * files - */ -#define WAVE_16_BITS 0x01 /* bit 0 = 8 or 16 bit wave data. */ -#define WAVE_UNSIGNED 0x02 /* bit 1 = Signed - Unsigned data. */ -#define WAVE_LOOPING 0x04 /* bit 2 = looping enabled-1. */ -#define WAVE_BIDIR_LOOP 0x08 /* bit 3 = Set is bidirectional looping. */ -#define WAVE_LOOP_BACK 0x10 /* bit 4 = Set is looping backward. */ -#define WAVE_SUSTAIN_ON 0x20 /* bit 5 = Turn sustaining on. (Env. pts. 3) */ -#define WAVE_ENVELOPES 0x40 /* bit 6 = Enable envelopes - 1 */ -#define WAVE_FAST_RELEASE 0x80 /* bit 7 = Shut off immediately after note off */ - /* (use the env_rate/env_offs fields). */ -/* Linux specific bits */ -#define WAVE_VIBRATO 0x00010000 /* The vibrato info is valid */ -#define WAVE_TREMOLO 0x00020000 /* The tremolo info is valid */ -#define WAVE_SCALE 0x00040000 /* The scaling info is valid */ -#define WAVE_FRACTIONS 0x00080000 /* Fraction information is valid */ -/* Reserved bits */ -#define WAVE_ROM 0x40000000 /* For future use */ -#define WAVE_MULAW 0x20000000 /* For future use */ -/* Other bits must be zeroed */ - - int len; /* Size of the wave data in bytes */ - int loop_start, loop_end; /* Byte offsets from the beginning */ - -/* - * The base_freq and base_note fields are used when computing the - * playback speed for a note. The base_note defines the tone frequency - * which is heard if the sample is played using the base_freq as the - * playback speed. - * - * The low_note and high_note fields define the minimum and maximum note - * frequencies for which this sample is valid. It is possible to define - * more than one samples for an instrument number at the same time. The - * low_note and high_note fields are used to select the most suitable one. - * - * The fields base_note, high_note and low_note should contain - * the note frequency multiplied by 1000. For example value for the - * middle A is 440*1000. - */ - - unsigned int base_freq; - unsigned int base_note; - unsigned int high_note; - unsigned int low_note; - int panning; /* -128=left, 127=right */ - int detuning; - - /* Envelope. Enabled by mode bit WAVE_ENVELOPES */ - unsigned char env_rate[6]; /* GUS HW ramping rate */ - unsigned char env_offset[6]; /* 255 == 100% */ - - /* - * The tremolo, vibrato and scale info are not supported yet. - * Enable by setting the mode bits WAVE_TREMOLO, WAVE_VIBRATO or - * WAVE_SCALE - */ - - unsigned char tremolo_sweep; - unsigned char tremolo_rate; - unsigned char tremolo_depth; - - unsigned char vibrato_sweep; - unsigned char vibrato_rate; - unsigned char vibrato_depth; - - int scale_frequency; - unsigned int scale_factor; /* from 0 to 2048 or 0 to 2 */ - - int volume; - int fractions; - int reserved1; - int spare[2]; - char data[1]; /* The waveform data starts here */ -}; - -struct sysex_info -{ - short key; /* Use SYSEX_PATCH or MAUI_PATCH here */ -#define SYSEX_PATCH _PATCHKEY(0x05) -#define MAUI_PATCH _PATCHKEY(0x06) - short device_no; /* Synthesizer number */ - int len; /* Size of the sysex data in bytes */ - unsigned char data[1]; /* Sysex data starts here */ -}; - -/* - * /dev/sequencer input events. - * - * The data written to the /dev/sequencer is a stream of events. Events - * are records of 4 or 8 bytes. The first byte defines the size. - * Any number of events can be written with a write call. There - * is a set of macros for sending these events. Use these macros if you - * want to maximize portability of your program. - * - * Events SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO. Are also input events. - * (All input events are currently 4 bytes long. Be prepared to support - * 8 byte events also. If you receive any event having first byte >= 128, - * it's a 8 byte event. - * - * The events are documented at the end of this file. - * - * Normal events (4 bytes) - * There is also a 8 byte version of most of the 4 byte events. The - * 8 byte one is recommended. - * - * NOTE! All 4 byte events are now obsolete. Applications should not write - * them. However 4 byte events are still used as inputs from - * /dev/sequencer (/dev/music uses only 8 byte ones). - */ -#define SEQ_NOTEOFF 0 -#define SEQ_FMNOTEOFF SEQ_NOTEOFF /* Just old name */ -#define SEQ_NOTEON 1 -#define SEQ_FMNOTEON SEQ_NOTEON -#define SEQ_WAIT TMR_WAIT_ABS -#define SEQ_PGMCHANGE 3 -#define SEQ_FMPGMCHANGE SEQ_PGMCHANGE -#define SEQ_SYNCTIMER TMR_START -#define SEQ_MIDIPUTC 5 -#define SEQ_DRUMON 6 /*** OBSOLETE ***/ -#define SEQ_DRUMOFF 7 /*** OBSOLETE ***/ -#define SEQ_ECHO TMR_ECHO /* For synching programs with output */ -#define SEQ_AFTERTOUCH 9 -#define SEQ_CONTROLLER 10 -#define SEQ_BALANCE 11 -#define SEQ_VOLMODE 12 - -/************************************ - * Midi controller numbers * - ************************************/ -/* - * Controllers 0 to 31 (0x00 to 0x1f) and - * 32 to 63 (0x20 to 0x3f) are continuous - * controllers. - * In the MIDI 1.0 these controllers are sent using - * two messages. Controller numbers 0 to 31 are used - * to send the MSB and the controller numbers 32 to 63 - * are for the LSB. Note that just 7 bits are used in MIDI bytes. - */ - -#define CTL_BANK_SELECT 0x00 -#define CTL_MODWHEEL 0x01 -#define CTL_BREATH 0x02 -/* undefined 0x03 */ -#define CTL_FOOT 0x04 -#define CTL_PORTAMENTO_TIME 0x05 -#define CTL_DATA_ENTRY 0x06 -#define CTL_MAIN_VOLUME 0x07 -#define CTL_BALANCE 0x08 -/* undefined 0x09 */ -#define CTL_PAN 0x0a -#define CTL_EXPRESSION 0x0b -/* undefined 0x0c */ -/* undefined 0x0d */ -/* undefined 0x0e */ -/* undefined 0x0f */ -#define CTL_GENERAL_PURPOSE1 0x10 -#define CTL_GENERAL_PURPOSE2 0x11 -#define CTL_GENERAL_PURPOSE3 0x12 -#define CTL_GENERAL_PURPOSE4 0x13 -/* undefined 0x14 - 0x1f */ - -/* undefined 0x20 */ -/* The controller numbers 0x21 to 0x3f are reserved for the */ -/* least significant bytes of the controllers 0x00 to 0x1f. */ -/* These controllers are not recognised by the driver. */ - -/* Controllers 64 to 69 (0x40 to 0x45) are on/off switches. */ -/* 0=OFF and 127=ON (intermediate values are possible) */ -#define CTL_DAMPER_PEDAL 0x40 -#define CTL_SUSTAIN 0x40 /* Alias */ -#define CTL_HOLD 0x40 /* Alias */ -#define CTL_PORTAMENTO 0x41 -#define CTL_SOSTENUTO 0x42 -#define CTL_SOFT_PEDAL 0x43 -/* undefined 0x44 */ -#define CTL_HOLD2 0x45 -/* undefined 0x46 - 0x4f */ - -#define CTL_GENERAL_PURPOSE5 0x50 -#define CTL_GENERAL_PURPOSE6 0x51 -#define CTL_GENERAL_PURPOSE7 0x52 -#define CTL_GENERAL_PURPOSE8 0x53 -/* undefined 0x54 - 0x5a */ -#define CTL_EXT_EFF_DEPTH 0x5b -#define CTL_TREMOLO_DEPTH 0x5c -#define CTL_CHORUS_DEPTH 0x5d -#define CTL_DETUNE_DEPTH 0x5e -#define CTL_CELESTE_DEPTH 0x5e /* Alias for the above one */ -#define CTL_PHASER_DEPTH 0x5f -#define CTL_DATA_INCREMENT 0x60 -#define CTL_DATA_DECREMENT 0x61 -#define CTL_NONREG_PARM_NUM_LSB 0x62 -#define CTL_NONREG_PARM_NUM_MSB 0x63 -#define CTL_REGIST_PARM_NUM_LSB 0x64 -#define CTL_REGIST_PARM_NUM_MSB 0x65 -/* undefined 0x66 - 0x78 */ -/* reserved 0x79 - 0x7f */ - -/* Pseudo controllers (not midi compatible) */ -#define CTRL_PITCH_BENDER 255 -#define CTRL_PITCH_BENDER_RANGE 254 -#define CTRL_EXPRESSION 253 /* Obsolete */ -#define CTRL_MAIN_VOLUME 252 /* Obsolete */ - -/* - * Volume mode defines how volumes are used - */ - -#define VOL_METHOD_ADAGIO 1 -#define VOL_METHOD_LINEAR 2 - -/* - * Note! SEQ_WAIT, SEQ_MIDIPUTC and SEQ_ECHO are used also as - * input events. - */ - -/* - * Event codes 0xf0 to 0xfc are reserved for future extensions. - */ - -#define SEQ_FULLSIZE 0xfd /* Long events */ -/* - * SEQ_FULLSIZE events are used for loading patches/samples to the - * synthesizer devices. These events are passed directly to the driver - * of the associated synthesizer device. There is no limit to the size - * of the extended events. These events are not queued but executed - * immediately when the write() is called (execution can take several - * seconds of time). - * - * When a SEQ_FULLSIZE message is written to the device, it must - * be written using exactly one write() call. Other events cannot - * be mixed to the same write. - * - * For FM synths (YM3812/OPL3) use struct sbi_instrument and write it to the - * /dev/sequencer. Don't write other data together with the instrument structure - * Set the key field of the structure to FM_PATCH. The device field is used to - * route the patch to the corresponding device. - * - * For wave table use struct patch_info. Initialize the key field - * to WAVE_PATCH. - */ -#define SEQ_PRIVATE 0xfe /* Low level HW dependent events (8 bytes) */ -#define SEQ_EXTENDED 0xff /* Extended events (8 bytes) OBSOLETE */ - -/* - * Record for FM patches - */ - -typedef unsigned char sbi_instr_data[32]; - -struct sbi_instrument -{ - unsigned short key; /* FM_PATCH or OPL3_PATCH */ -#define FM_PATCH _PATCHKEY(0x01) -#define OPL3_PATCH _PATCHKEY(0x03) - short device; /* Synth# (0-4) */ - int channel; /* Program# to be initialized */ - sbi_instr_data operators; /* Register settings for operator cells (.SBI format) */ -}; - -struct synth_info -{ /* Read only */ - char name[30]; - int device; /* 0-N. INITIALIZE BEFORE CALLING */ - int synth_type; -#define SYNTH_TYPE_FM 0 -#define SYNTH_TYPE_SAMPLE 1 -#define SYNTH_TYPE_MIDI 2 /* Midi interface */ - - int synth_subtype; -#define FM_TYPE_ADLIB 0x00 -#define FM_TYPE_OPL3 0x01 -#define MIDI_TYPE_MPU401 0x401 - -#define SAMPLE_TYPE_BASIC 0x10 -#define SAMPLE_TYPE_GUS SAMPLE_TYPE_BASIC -#define SAMPLE_TYPE_WAVEFRONT 0x11 - - int perc_mode; /* No longer supported */ - int nr_voices; - int nr_drums; /* Obsolete field */ - int instr_bank_size; - unsigned int capabilities; -#define SYNTH_CAP_PERCMODE 0x00000001 /* No longer used */ -#define SYNTH_CAP_OPL3 0x00000002 /* Set if OPL3 supported */ -#define SYNTH_CAP_INPUT 0x00000004 /* Input (MIDI) device */ - int dummies[19]; /* Reserve space */ -}; - -struct sound_timer_info -{ - char name[32]; - int caps; -}; - -struct midi_info /* OBSOLETE */ -{ - char name[30]; - int device; /* 0-N. INITIALIZE BEFORE CALLING */ - unsigned int capabilities; /* To be defined later */ - int dev_type; - int dummies[18]; /* Reserve space */ -}; - -/* - * Level 2 event types for /dev/sequencer - */ - -/* - * The 4 most significant bits of byte 0 specify the class of - * the event: - * - * 0x8X = system level events, - * 0x9X = device/port specific events, event[1] = device/port, - * The last 4 bits give the subtype: - * 0x02 = Channel event (event[3] = chn). - * 0x01 = note event (event[4] = note). - * (0x01 is not used alone but always with bit 0x02). - * event[2] = MIDI message code (0x80=note off etc.) - * - */ - -#define EV_SEQ_LOCAL 0x80 -#define EV_TIMING 0x81 -#define EV_CHN_COMMON 0x92 -#define EV_CHN_VOICE 0x93 -#define EV_SYSEX 0x94 -#define EV_SYSTEM 0x95 /* MIDI system and real time messages (input only) */ -/* - * Event types 200 to 220 are reserved for application use. - * These numbers will not be used by the driver. - */ - -/* - * Events for event type EV_CHN_VOICE - */ - -#define MIDI_NOTEOFF 0x80 -#define MIDI_NOTEON 0x90 -#define MIDI_KEY_PRESSURE 0xA0 - -/* - * Events for event type EV_CHN_COMMON - */ - -#define MIDI_CTL_CHANGE 0xB0 -#define MIDI_PGM_CHANGE 0xC0 -#define MIDI_CHN_PRESSURE 0xD0 -#define MIDI_PITCH_BEND 0xE0 - -#define MIDI_SYSTEM_PREFIX 0xF0 - -/* - * Timer event types - */ -#define TMR_WAIT_REL 1 /* Time relative to the prev time */ -#define TMR_WAIT_ABS 2 /* Absolute time since TMR_START */ -#define TMR_STOP 3 -#define TMR_START 4 -#define TMR_CONTINUE 5 -#define TMR_TEMPO 6 -#define TMR_ECHO 8 -#define TMR_CLOCK 9 /* MIDI clock */ -#define TMR_SPP 10 /* Song position pointer */ -#define TMR_TIMESIG 11 /* Time signature */ - -/* - * Local event types - */ -#define LOCL_STARTAUDIO 1 -#define LOCL_STARTAUDIO2 2 -#define LOCL_STARTAUDIO3 3 -#define LOCL_STARTAUDIO4 4 - -#if (!defined(__KERNEL__) && !defined(KERNEL) && !defined(INKERNEL) && !defined(_KERNEL)) || defined(USE_SEQ_MACROS) -/* - * Some convenience macros to simplify programming of the - * /dev/sequencer interface - * - * These macros define the API which should be used when possible. - */ -#define SEQ_DECLAREBUF() SEQ_USE_EXTBUF() - -void seqbuf_dump (void); /* This function must be provided by programs */ - -EXTERNC int OSS_init (int seqfd, int buflen); -EXTERNC void OSS_seqbuf_dump (int fd, unsigned char *buf, int buflen); -EXTERNC void OSS_seq_advbuf (int len, int fd, unsigned char *buf, int buflen); -EXTERNC void OSS_seq_needbuf (int len, int fd, unsigned char *buf, - int buflen); -EXTERNC void OSS_patch_caching (int dev, int chn, int patch, int fd, - unsigned char *buf, int buflen); -EXTERNC void OSS_drum_caching (int dev, int chn, int patch, int fd, - unsigned char *buf, int buflen); -EXTERNC void OSS_write_patch (int fd, unsigned char *buf, int len); -EXTERNC int OSS_write_patch2 (int fd, unsigned char *buf, int len); - -#define SEQ_PM_DEFINES int __foo_bar___ -#ifdef OSSLIB -# define SEQ_USE_EXTBUF() \ - EXTERNC unsigned char *_seqbuf; \ - EXTERNC int _seqbuflen;EXTERNC int _seqbufptr -# define SEQ_DEFINEBUF(len) SEQ_USE_EXTBUF();static int _requested_seqbuflen=len -# define _SEQ_ADVBUF(len) OSS_seq_advbuf(len, seqfd, _seqbuf, _seqbuflen) -# define _SEQ_NEEDBUF(len) OSS_seq_needbuf(len, seqfd, _seqbuf, _seqbuflen) -# define SEQ_DUMPBUF() OSS_seqbuf_dump(seqfd, _seqbuf, _seqbuflen) - -# define SEQ_LOAD_GMINSTR(dev, instr) \ - OSS_patch_caching(dev, -1, instr, seqfd, _seqbuf, _seqbuflen) -# define SEQ_LOAD_GMDRUM(dev, drum) \ - OSS_drum_caching(dev, -1, drum, seqfd, _seqbuf, _seqbuflen) -#else /* !OSSLIB */ - -# define SEQ_LOAD_GMINSTR(dev, instr) -# define SEQ_LOAD_GMDRUM(dev, drum) - -# define SEQ_USE_EXTBUF() \ - EXTERNC unsigned char _seqbuf[]; \ - EXTERNC int _seqbuflen;EXTERNC int _seqbufptr - -#ifndef USE_SIMPLE_MACROS -/* Sample seqbuf_dump() implementation: - * - * SEQ_DEFINEBUF (2048); -- Defines a buffer for 2048 bytes - * - * int seqfd; -- The file descriptor for /dev/sequencer. - * - * void - * seqbuf_dump () - * { - * if (_seqbufptr) - * if (write (seqfd, _seqbuf, _seqbufptr) == -1) - * { - * perror ("write /dev/sequencer"); - * exit (-1); - * } - * _seqbufptr = 0; - * } - */ - -#define SEQ_DEFINEBUF(len) \ - unsigned char _seqbuf[len]; int _seqbuflen = len;int _seqbufptr = 0 -#define _SEQ_NEEDBUF(len) \ - if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump() -#define _SEQ_ADVBUF(len) _seqbufptr += len -#define SEQ_DUMPBUF seqbuf_dump -#else -/* - * This variation of the sequencer macros is used just to format one event - * using fixed buffer. - * - * The program using the macro library must define the following macros before - * using this library. - * - * #define _seqbuf name of the buffer (unsigned char[]) - * #define _SEQ_ADVBUF(len) If the applic needs to know the exact - * size of the event, this macro can be used. - * Otherwise this must be defined as empty. - * #define _seqbufptr Define the name of index variable or 0 if - * not required. - */ -#define _SEQ_NEEDBUF(len) /* empty */ -#endif -#endif /* !OSSLIB */ - -#define SEQ_VOLUME_MODE(dev, mode) \ - {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ - _seqbuf[_seqbufptr+1] = SEQ_VOLMODE;\ - _seqbuf[_seqbufptr+2] = (dev);\ - _seqbuf[_seqbufptr+3] = (mode);\ - _seqbuf[_seqbufptr+4] = 0;\ - _seqbuf[_seqbufptr+5] = 0;\ - _seqbuf[_seqbufptr+6] = 0;\ - _seqbuf[_seqbufptr+7] = 0;\ - _SEQ_ADVBUF(8);} - -/* - * Midi voice messages - */ - -#define _CHN_VOICE(dev, event, chn, note, parm) \ - {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr] = EV_CHN_VOICE;\ - _seqbuf[_seqbufptr+1] = (dev);\ - _seqbuf[_seqbufptr+2] = (event);\ - _seqbuf[_seqbufptr+3] = (chn);\ - _seqbuf[_seqbufptr+4] = (note);\ - _seqbuf[_seqbufptr+5] = (parm);\ - _seqbuf[_seqbufptr+6] = (0);\ - _seqbuf[_seqbufptr+7] = 0;\ - _SEQ_ADVBUF(8);} - -#define SEQ_START_NOTE(dev, chn, note, vol) \ - _CHN_VOICE(dev, MIDI_NOTEON, chn, note, vol) - -#define SEQ_STOP_NOTE(dev, chn, note, vol) \ - _CHN_VOICE(dev, MIDI_NOTEOFF, chn, note, vol) - -#define SEQ_KEY_PRESSURE(dev, chn, note, pressure) \ - _CHN_VOICE(dev, MIDI_KEY_PRESSURE, chn, note, pressure) - -/* - * Midi channel messages - */ - -#define _CHN_COMMON(dev, event, chn, p1, p2, w14) \ - {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr] = EV_CHN_COMMON;\ - _seqbuf[_seqbufptr+1] = (dev);\ - _seqbuf[_seqbufptr+2] = (event);\ - _seqbuf[_seqbufptr+3] = (chn);\ - _seqbuf[_seqbufptr+4] = (p1);\ - _seqbuf[_seqbufptr+5] = (p2);\ - *(short *)&_seqbuf[_seqbufptr+6] = (w14);\ - _SEQ_ADVBUF(8);} -/* - * SEQ_SYSEX permits sending of sysex messages. (It may look that it permits - * sending any MIDI bytes but it's absolutely not possible. Trying to do - * so _will_ cause problems with MPU401 intelligent mode). - * - * Sysex messages are sent in blocks of 1 to 6 bytes. Longer messages must be - * sent by calling SEQ_SYSEX() several times (there must be no other events - * between them). First sysex fragment must have 0xf0 in the first byte - * and the last byte (buf[len-1] of the last fragment must be 0xf7. No byte - * between these sysex start and end markers cannot be larger than 0x7f. Also - * lengths of each fragments (except the last one) must be 6. - * - * Breaking the above rules may work with some MIDI ports but is likely to - * cause fatal problems with some other devices (such as MPU401). - */ -#define SEQ_SYSEX(dev, buf, len) \ - {int ii, ll=(len); \ - unsigned char *bufp=buf;\ - if (ll>6)ll=6;\ - _SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr] = EV_SYSEX;\ - _seqbuf[_seqbufptr+1] = (dev);\ - for(ii=0;ii>8)&0xff);\ - _seqbuf[_seqbufptr+7] = 0;\ - _SEQ_ADVBUF(8);} -/* - * The following 5 macros are incorrectly implemented and obsolete. - * Use SEQ_BENDER and SEQ_CONTROL (with proper controller) instead. - */ -#define SEQ_PITCHBEND(dev, voice, value) \ - SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER, value) -#define SEQ_BENDER_RANGE(dev, voice, value) \ - SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER_RANGE, value) -#define SEQ_EXPRESSION(dev, voice, value) \ - SEQ_CONTROL(dev, voice, CTL_EXPRESSION, value*128) -#define SEQ_MAIN_VOLUME(dev, voice, value) \ - SEQ_CONTROL(dev, voice, CTL_MAIN_VOLUME, (value*16383)/100) -#define SEQ_PANNING(dev, voice, pos) \ - SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2) - -/* - * Timing and syncronization macros - */ - -#define _TIMER_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr+0] = EV_TIMING; \ - _seqbuf[_seqbufptr+1] = (ev); \ - _seqbuf[_seqbufptr+2] = 0;\ - _seqbuf[_seqbufptr+3] = 0;\ - *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ - _SEQ_ADVBUF(8);} - -#define SEQ_START_TIMER() _TIMER_EVENT(TMR_START, 0) -#define SEQ_STOP_TIMER() _TIMER_EVENT(TMR_STOP, 0) -#define SEQ_CONTINUE_TIMER() _TIMER_EVENT(TMR_CONTINUE, 0) -#define SEQ_WAIT_TIME(ticks) _TIMER_EVENT(TMR_WAIT_ABS, ticks) -#define SEQ_DELTA_TIME(ticks) _TIMER_EVENT(TMR_WAIT_REL, ticks) -#define SEQ_ECHO_BACK(key) _TIMER_EVENT(TMR_ECHO, key) -#define SEQ_SET_TEMPO(value) _TIMER_EVENT(TMR_TEMPO, value) -#define SEQ_SONGPOS(pos) _TIMER_EVENT(TMR_SPP, pos) -#define SEQ_TIME_SIGNATURE(sig) _TIMER_EVENT(TMR_TIMESIG, sig) - -/* - * Local control events - */ - -#define _LOCAL_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ - _seqbuf[_seqbufptr+0] = EV_SEQ_LOCAL; \ - _seqbuf[_seqbufptr+1] = (ev); \ - _seqbuf[_seqbufptr+2] = 0;\ - _seqbuf[_seqbufptr+3] = 0;\ - *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ - _SEQ_ADVBUF(8);} - -#define SEQ_PLAYAUDIO(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO, devmask) -#define SEQ_PLAYAUDIO2(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO2, devmask) -#define SEQ_PLAYAUDIO3(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO3, devmask) -#define SEQ_PLAYAUDIO4(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO4, devmask) -/* - * Events for the level 1 interface only - */ - -#define SEQ_MIDIOUT(device, byte) {_SEQ_NEEDBUF(4);\ - _seqbuf[_seqbufptr] = SEQ_MIDIPUTC;\ - _seqbuf[_seqbufptr+1] = (byte);\ - _seqbuf[_seqbufptr+2] = (device);\ - _seqbuf[_seqbufptr+3] = 0;\ - _SEQ_ADVBUF(4);} - -/* - * Patch loading. - */ -#ifdef OSSLIB -# define SEQ_WRPATCH(patchx, len) \ - OSS_write_patch(seqfd, (char*)(patchx), len) -# define SEQ_WRPATCH2(patchx, len) \ - OSS_write_patch2(seqfd, (char*)(patchx), len) -#else -# define SEQ_WRPATCH(patchx, len) \ - {if (_seqbufptr) SEQ_DUMPBUF();\ - if (write(seqfd, (char*)(patchx), len)==-1) \ - perror("Write patch: /dev/sequencer");} -# define SEQ_WRPATCH2(patchx, len) \ - (SEQ_DUMPBUF(), write(seqfd, (char*)(patchx), len)) -#endif - -#endif -#endif /* ifndef DISABLE_SEQUENCER */ - -/* - **************************************************************************** - * ioctl commands for the /dev/midi## - ****************************************************************************/ -#define SNDCTL_MIDI_PRETIME __SIOWR('m', 0, int) - -#if 0 -/* - * The SNDCTL_MIDI_MPUMODE and SNDCTL_MIDI_MPUCMD calls - * are completely obsolete. The hardware device (MPU-401 "intelligent mode" - * and compatibles) has disappeared from the market 10 years ago so there - * is no need for this stuff. The MPU-401 "UART" mode devices don't support - * this stuff. - */ -typedef struct -{ - unsigned char cmd; - char nr_args, nr_returns; - unsigned char data[30]; -} mpu_command_rec; - -#define SNDCTL_MIDI_MPUMODE __SIOWR('m', 1, int) -#define SNDCTL_MIDI_MPUCMD __SIOWR('m', 2, mpu_command_rec) -#endif - -/* - * SNDCTL_MIDI_MTCINPUT turns on a mode where OSS automatically inserts - * MTC quarter frame messages (F1 xx) to the input. - * The argument is the MTC mode: - * - * -1 = Turn MTC messages OFF (default) - * 24 = 24 FPS - * 25 = 25 FPS - * 29 = 30 FPS drop frame - * 30 = 30 FPS - * - * Note that 25 FPS mode is probably the only mode that is supported. Other - * modes may be supported in the future versions of OSS, 25 FPS is handy - * because it generates 25*4=100 quarter frame messages per second which - * matches the usual 100 HZ system timer rate). - * - * The quarter frame timer will be reset to 0:00:00:00.0 at the moment this - * ioctl is made. - */ -#define SNDCTL_MIDI_MTCINPUT __SIOWR('m', 3, int) - -/* - * MTC/SMPTE time code record (for future use) - */ -typedef struct -{ - unsigned char hours, minutes, seconds, frames, qframes; - char direction; -#define MTC_DIR_STOPPED 0 -#define MTC_DIR_FORWARD 1 -#define MTC_DIR_BACKWARD -1 - unsigned char time_code_type; - unsigned int flags; -} oss_mtc_data_t; - -#define SNDCTL_MIDI_SETMODE __SIOWR('m', 6, int) -# define MIDI_MODE_TRADITIONAL 0 -# define MIDI_MODE_TIMED 1 /* Input times are in MIDI ticks */ -# define MIDI_MODE_TIMED_ABS 2 /* Input times are absolute (usecs) */ - -/* - * Packet header for MIDI_MODE_TIMED and MIDI_MODE_TIMED_ABS - */ -typedef unsigned long long oss_midi_time_t; /* Variable type for MIDI time (clock ticks) */ - -typedef struct -{ - int magic; /* Initialize to MIDI_HDR_MAGIC */ -#define MIDI_HDR_MAGIC -1 - unsigned short event_type; -#define MIDI_EV_WRITE 0 /* Write or read (with payload) */ -#define MIDI_EV_TEMPO 1 -#define MIDI_EV_ECHO 2 -#define MIDI_EV_START 3 -#define MIDI_EV_STOP 4 -#define MIDI_EV_CONTINUE 5 -#define MIDI_EV_XPRESSWRITE 6 -#define MIDI_EV_TIMEBASE 7 -#define MIDI_EV_DEVCTL 8 /* Device control read/write */ - unsigned short options; -#define MIDI_OPT_NONE 0x0000 -#define MIDI_OPT_TIMED 0x0001 -#define MIDI_OPT_CONTINUATION 0x0002 -#define MIDI_OPT_USECTIME 0x0004 /* Time is absolute (in usecs) */ -#define MIDI_OPT_BUSY 0x0008 /* Reserved for internal use */ - oss_midi_time_t time; - int parm; - int filler[3]; /* Fur future expansion - init to zeros */ -} midi_packet_header_t; -/* - * MIDI_PAYLOAD_SIZE is the maximum size of one MIDI input chunk. It must be - * less (or equal) than 1024 which is the read size recommended in the - * documentation. TODO: Explain this better. - */ -#define MIDI_PAYLOAD_SIZE 1000 - -typedef struct -{ - midi_packet_header_t hdr; - unsigned char payload[MIDI_PAYLOAD_SIZE]; -} midi_packet_t; - -#define SNDCTL_MIDI_TIMEBASE __SIOWR('m', 7, int) -#define SNDCTL_MIDI_TEMPO __SIOWR('m', 8, int) -/* - * User land MIDI servers (synths) can use SNDCTL_MIDI_SET_LATENCY - * to request MIDI events to be sent to them in advance. The parameter - * (in microseconds) tells how much before the events are submitted. - * - * This feature is only valid for loopback devices and possibly some other - * types of virtual devices. - */ -#define SNDCTL_MIDI_SET_LATENCY __SIOW ('m', 9, int) -/* - **************************************************************************** - * IOCTL commands for /dev/dsp - ****************************************************************************/ - -#define SNDCTL_DSP_HALT __SIO ('P', 0) -#define SNDCTL_DSP_RESET SNDCTL_DSP_HALT /* Old name */ -#define SNDCTL_DSP_SYNC __SIO ('P', 1) -#define SNDCTL_DSP_SPEED __SIOWR('P', 2, int) - -/* SNDCTL_DSP_STEREO is obsolete - use SNDCTL_DSP_CHANNELS instead */ -#define SNDCTL_DSP_STEREO __SIOWR('P', 3, int) -/* SNDCTL_DSP_STEREO is obsolete - use SNDCTL_DSP_CHANNELS instead */ - -#define SNDCTL_DSP_GETBLKSIZE __SIOWR('P', 4, int) -#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT -#define SNDCTL_DSP_CHANNELS __SIOWR('P', 6, int) -#define SNDCTL_DSP_POST __SIO ('P', 8) -#define SNDCTL_DSP_SUBDIVIDE __SIOWR('P', 9, int) -#define SNDCTL_DSP_SETFRAGMENT __SIOWR('P',10, int) - -/* Audio data formats (Note! U8=8 and S16_LE=16 for compatibility) */ -#define SNDCTL_DSP_GETFMTS __SIOR ('P',11, int) /* Returns a mask */ -#define SNDCTL_DSP_SETFMT __SIOWR('P',5, int) /* Selects ONE fmt */ -# define AFMT_QUERY 0x00000000 /* Return current fmt */ -# define AFMT_MU_LAW 0x00000001 -# define AFMT_A_LAW 0x00000002 -# define AFMT_IMA_ADPCM 0x00000004 -# define AFMT_U8 0x00000008 -# define AFMT_S16_LE 0x00000010 /* Little endian signed 16 */ -# define AFMT_S16_BE 0x00000020 /* Big endian signed 16 */ -# define AFMT_S8 0x00000040 -# define AFMT_U16_LE 0x00000080 /* Little endian U16 */ -# define AFMT_U16_BE 0x00000100 /* Big endian U16 */ -# define AFMT_MPEG 0x00000200 /* MPEG (2) audio */ - -/* AC3 _compressed_ bitstreams (See Programmer's Guide for details). */ -# define AFMT_AC3 0x00000400 -/* Ogg Vorbis _compressed_ bit streams */ -# define AFMT_VORBIS 0x00000800 - -/* 32 bit formats (MSB aligned) formats */ -# define AFMT_S32_LE 0x00001000 -# define AFMT_S32_BE 0x00002000 - -/* Reserved for _native_ endian double precision IEEE floating point */ -# define AFMT_FLOAT 0x00004000 - -/* 24 bit formats (LSB aligned in 32 bit word) formats */ -# define AFMT_S24_LE 0x00008000 -# define AFMT_S24_BE 0x00010000 - -/* - * S/PDIF raw format. In this format the S/PDIF frames (including all - * control and user bits) are included in the data stream. Each sample - * is stored in a 32 bit frame (see IEC-958 for more info). This format - * is supported by very few devices and it's only usable for purposes - * where full access to the control/user bits is required (real time control). - */ -# define AFMT_SPDIF_RAW 0x00020000 - -/* 24 bit packed (3 byte) little endian format (USB compatibility) */ -# define AFMT_S24_PACKED 0x00040000 - - -/* - * Some big endian/little endian handling macros (native endian and opposite - * endian formats). The usage of these macros is described in the OSS - * Programmer's Manual. - */ - -#if defined(_AIX) || defined(AIX) || defined(sparc) || defined(__hppa) || defined(PPC) || defined(__powerpc__) && !defined(i386) && !defined(__i386) && !defined(__i386__) - -/* Big endian machines */ -# define _PATCHKEY(id) (0xfd00|id) -# define AFMT_S16_NE AFMT_S16_BE -# define AFMT_U16_NE AFMT_U16_BE -# define AFMT_S32_NE AFMT_S32_BE -# define AFMT_S24_NE AFMT_S24_BE -# define AFMT_S16_OE AFMT_S16_LE -# define AFMT_S32_OE AFMT_S32_LE -# define AFMT_S24_OE AFMT_S24_LE -#else -# define _PATCHKEY(id) ((id<<8)|0xfd) -# define AFMT_S16_NE AFMT_S16_LE -# define AFMT_U16_NE AFMT_U16_LE -# define AFMT_S32_NE AFMT_S32_LE -# define AFMT_S24_NE AFMT_S24_LE -# define AFMT_S16_OE AFMT_S16_BE -# define AFMT_S32_OE AFMT_S32_BE -# define AFMT_S24_OE AFMT_S24_BE -#endif -/* - * Buffer status queries. - */ -typedef struct audio_buf_info -{ - int fragments; /* # of available fragments (partially usend ones not counted) */ - int fragstotal; /* Total # of fragments allocated */ - int fragsize; /* Size of a fragment in bytes */ - int bytes; /* Available space in bytes (includes partially used fragments) */ - /* Note! 'bytes' could be more than fragments*fragsize */ -} audio_buf_info; - -#define SNDCTL_DSP_GETOSPACE __SIOR ('P',12, audio_buf_info) -#define SNDCTL_DSP_GETISPACE __SIOR ('P',13, audio_buf_info) -#define SNDCTL_DSP_GETCAPS __SIOR ('P',15, int) -# define PCM_CAP_REVISION 0x000000ff /* Bits for revision level (0 to 255) */ -# define PCM_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */ -# define PCM_CAP_REALTIME 0x00000200 /* Not in use */ -# define PCM_CAP_BATCH 0x00000400 /* Device has some kind of */ - /* internal buffers which may */ - /* cause some delays and */ - /* decrease precision of timing */ -# define PCM_CAP_COPROC 0x00000800 /* Has a coprocessor */ - /* Sometimes it's a DSP */ - /* but usually not */ -# define PCM_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */ -# define PCM_CAP_MMAP 0x00002000 /* Supports mmap() */ -# define PCM_CAP_MULTI 0x00004000 /* Supports multiple open */ -# define PCM_CAP_BIND 0x00008000 /* Supports binding to front/rear/center/lfe */ -# define PCM_CAP_INPUT 0x00010000 /* Supports recording */ -# define PCM_CAP_OUTPUT 0x00020000 /* Supports playback */ -# define PCM_CAP_VIRTUAL 0x00040000 /* Virtuial device */ -/* 0x00040000 and 0x00080000 reserved for future use */ - -/* Analog/digital control capabilities */ -# define PCM_CAP_ANALOGOUT 0x00100000 -# define PCM_CAP_ANALOGIN 0x00200000 -# define PCM_CAP_DIGITALOUT 0x00400000 -# define PCM_CAP_DIGITALIN 0x00800000 -# define PCM_CAP_ADMASK 0x00f00000 -/* - * NOTE! (capabilities & PCM_CAP_ADMASK)==0 means just that the - * digital/analog interface control features are not supported by the - * device/driver. However the device still supports analog, digital or - * both inputs/outputs (depending on the device). See the OSS Programmer's - * Guide for full details. - */ -# define PCM_CAP_SHADOW 0x01000000 /* "Shadow" device */ - -/* - * Preferred channel usage. These bits can be used to - * give recommendations to the application. Used by few drivers. - * For example if ((caps & DSP_CH_MASK) == DSP_CH_MONO) means that - * the device works best in mono mode. However it doesn't necessarily mean - * that the device cannot be used in stereo. These bits should only be used - * special applications such as multi track hard disk recorders to find out - * the initial setup. However the user should be able to override this - * selection. - * - * To find out which modes are actually supported the application should - * try to select them using SNDCTL_DSP_CHANNELS. - */ -# define DSP_CH_MASK 0x06000000 /* Mask */ -# define DSP_CH_ANY 0x00000000 /* No preferred mode */ -# define DSP_CH_MONO 0x02000000 -# define DSP_CH_STEREO 0x04000000 -# define DSP_CH_MULTI 0x06000000 /* More than two channels */ - -# define PCM_CAP_HIDDEN 0x08000000 /* Hidden device */ -# define PCM_CAP_FREERATE 0x10000000 -# define PCM_CAP_MODEM 0x20000000 /* Modem device */ -# define PCM_CAP_DEFAULT 0x40000000 /* "Default" device */ - -/* - * The PCM_CAP_* capability names were known as DSP_CAP_* prior OSS 4.0 - * so it's necessary to define the older names too. - */ -#define DSP_CAP_ADMASK PCM_CAP_ADMASK -#define DSP_CAP_ANALOGIN PCM_CAP_ANALOGIN -#define DSP_CAP_ANALOGOUT PCM_CAP_ANALOGOUT -#define DSP_CAP_BATCH PCM_CAP_BATCH -#define DSP_CAP_BIND PCM_CAP_BIND -#define DSP_CAP_COPROC PCM_CAP_COPROC -#define DSP_CAP_DEFAULT PCM_CAP_DEFAULT -#define DSP_CAP_DIGITALIN PCM_CAP_DIGITALIN -#define DSP_CAP_DIGITALOUT PCM_CAP_DIGITALOUT -#define DSP_CAP_DUPLEX PCM_CAP_DUPLEX -#define DSP_CAP_FREERATE PCM_CAP_FREERATE -#define DSP_CAP_HIDDEN PCM_CAP_HIDDEN -#define DSP_CAP_INPUT PCM_CAP_INPUT -#define DSP_CAP_MMAP PCM_CAP_MMAP -#define DSP_CAP_MODEM PCM_CAP_MODEM -#define DSP_CAP_MULTI PCM_CAP_MULTI -#define DSP_CAP_OUTPUT PCM_CAP_OUTPUT -#define DSP_CAP_REALTIME PCM_CAP_REALTIME -#define DSP_CAP_REVISION PCM_CAP_REVISION -#define DSP_CAP_SHADOW PCM_CAP_SHADOW -#define DSP_CAP_TRIGGER PCM_CAP_TRIGGER -#define DSP_CAP_VIRTUAL PCM_CAP_VIRTUAL - -#define SNDCTL_DSP_GETTRIGGER __SIOR ('P',16, int) -#define SNDCTL_DSP_SETTRIGGER __SIOW ('P',16, int) -# define PCM_ENABLE_INPUT 0x00000001 -# define PCM_ENABLE_OUTPUT 0x00000002 - -typedef struct count_info -{ - unsigned int bytes; /* Total # of bytes processed */ - int blocks; /* # of fragment transitions since last time */ - int ptr; /* Current DMA pointer value */ -} count_info; - -#define SNDCTL_DSP_GETIPTR __SIOR ('P',17, count_info) -#define SNDCTL_DSP_GETOPTR __SIOR ('P',18, count_info) - -typedef struct buffmem_desc -{ - unsigned *buffer; - int size; -} buffmem_desc; -#define SNDCTL_DSP_SETSYNCRO __SIO ('P', 21) -#define SNDCTL_DSP_SETDUPLEX __SIO ('P', 22) - -#define SNDCTL_DSP_PROFILE __SIOW ('P', 23, int) /* OBSOLETE */ -#define APF_NORMAL 0 /* Normal applications */ -#define APF_NETWORK 1 /* Underruns probably caused by an "external" delay */ -#define APF_CPUINTENS 2 /* Underruns probably caused by "overheating" the CPU */ - -#define SNDCTL_DSP_GETODELAY __SIOR ('P', 23, int) - -typedef struct audio_errinfo -{ - int play_underruns; - int rec_overruns; - unsigned int play_ptradjust; - unsigned int rec_ptradjust; - int play_errorcount; - int rec_errorcount; - int play_lasterror; - int rec_lasterror; - int play_errorparm; - int rec_errorparm; - int filler[16]; -} audio_errinfo; - -#define SNDCTL_DSP_GETPLAYVOL __SIOR ('P', 24, int) -#define SNDCTL_DSP_SETPLAYVOL __SIOWR('P', 24, int) -#define SNDCTL_DSP_GETERROR __SIOR ('P', 25, audio_errinfo) -/* - **************************************************************************** - * Digital interface (S/PDIF) control interface - */ - -typedef struct oss_digital_control -{ - unsigned int caps; -#define DIG_CBITIN_NONE 0x00000000 -#define DIG_CBITIN_LIMITED 0x00000001 -#define DIG_CBITIN_DATA 0x00000002 -#define DIG_CBITIN_BYTE0 0x00000004 -#define DIG_CBITIN_FULL 0x00000008 -#define DIG_CBITIN_MASK 0x0000000f -#define DIG_CBITOUT_NONE 0x00000000 -#define DIG_CBITOUT_LIMITED 0x00000010 -#define DIG_CBITOUT_BYTE0 0x00000020 -#define DIG_CBITOUT_FULL 0x00000040 -#define DIG_CBITOUT_DATA 0x00000080 -#define DIG_CBITOUT_MASK 0x000000f0 -#define DIG_UBITIN 0x00000100 -#define DIG_UBITOUT 0x00000200 -#define DIG_VBITOUT 0x00000400 -#define DIG_OUTRATE 0x00000800 -#define DIG_INRATE 0x00001000 -#define DIG_INBITS 0x00002000 -#define DIG_OUTBITS 0x00004000 -#define DIG_EXACT 0x00010000 -#define DIG_PRO 0x00020000 -#define DIG_CONSUMER 0x00040000 -#define DIG_PASSTHROUGH 0x00080000 -#define DIG_OUTSEL 0x00100000 - - unsigned int valid; -#define VAL_CBITIN 0x00000001 -#define VAL_UBITIN 0x00000002 -#define VAL_CBITOUT 0x00000004 -#define VAL_UBITOUT 0x00000008 -#define VAL_ISTATUS 0x00000010 -#define VAL_IRATE 0x00000020 -#define VAL_ORATE 0x00000040 -#define VAL_INBITS 0x00000080 -#define VAL_OUTBITS 0x00000100 -#define VAL_REQUEST 0x00000200 -#define VAL_OUTSEL 0x00000400 - -#define VAL_OUTMASK (VAL_CBITOUT|VAL_UBITOUT|VAL_ORATE|VAL_OUTBITS|VAL_OUTSEL) - - unsigned int request, param; -#define SPD_RQ_PASSTHROUGH 1 - - unsigned char cbitin[24]; - unsigned char ubitin[24]; - unsigned char cbitout[24]; - unsigned char ubitout[24]; - - unsigned int outsel; -#define OUTSEL_DIGITAL 1 -#define OUTSEL_ANALOG 2 -#define OUTSEL_BOTH (OUTSEL_DIGITAL|OUTSEL_ANALOG) - - int in_data; /* Audio/data if autodetectable by the receiver */ -#define IND_UNKNOWN 0 -#define IND_AUDIO 1 -#define IND_DATA 2 - - int in_locked; /* Receiver locked */ -#define LOCK_NOT_INDICATED 0 -#define LOCK_UNLOCKED 1 -#define LOCK_LOCKED 2 - - int in_quality; /* Input signal quality */ -#define IN_QUAL_NOT_INDICATED 0 -#define IN_QUAL_POOR 1 -#define IN_QUAL_GOOD 2 - - int in_vbit, out_vbit; /* V bits */ -#define VBIT_NOT_INDICATED 0 -#define VBIT_OFF 1 -#define VBIT_ON 2 - - unsigned int in_errors; /* Various input errro conditions */ -#define INERR_CRC 0x0001 -#define INERR_QCODE_CRC 0x0002 -#define INERR_PARITY 0x0004 -#define INERR_BIPHASE 0x0008 - - int srate_in, srate_out; - int bits_in, bits_out; - - int filler[32]; -} oss_digital_control; - -#define SNDCTL_DSP_READCTL __SIOWR('P', 26, oss_digital_control) -#define SNDCTL_DSP_WRITECTL __SIOWR('P', 27, oss_digital_control) - -/* - **************************************************************************** - * Sync groups for audio devices - */ -typedef struct oss_syncgroup -{ - int id; - int mode; - int filler[16]; -} oss_syncgroup; - -#define SNDCTL_DSP_SYNCGROUP __SIOWR('P', 28, oss_syncgroup) -#define SNDCTL_DSP_SYNCSTART __SIOW ('P', 29, int) - -/* - ************************************************************************** - * "cooked" mode enables software based conversions for sample rate, sample - * format (bits) and number of channels (mono/stereo). These conversions are - * required with some devices that support only one sample rate or just stereo - * to let the applications to use other formats. The cooked mode is enabled by - * default. However it's necessary to disable this mode when mmap() is used or - * when very deterministic timing is required. SNDCTL_DSP_COOKEDMODE is an - * optional call introduced in OSS 3.9.6f. It's _error return must be ignored_ - * since normally this call will return erno=EINVAL. - * - * SNDCTL_DSP_COOKEDMODE must be called immediately after open before doing - * anything else. Otherwise the call will not have any effect. - */ -#define SNDCTL_DSP_COOKEDMODE __SIOW ('P', 30, int) - -/* - ************************************************************************** - * SNDCTL_DSP_SILENCE and SNDCTL_DSP_SKIP are new calls in OSS 3.99.0 - * that can be used to implement pause/continue during playback (no effect - * on recording). - */ -#define SNDCTL_DSP_SILENCE __SIO ('P', 31) -#define SNDCTL_DSP_SKIP __SIO ('P', 32) -/* - **************************************************************************** - * Abort transfer (reset) functions for input and output - */ -#define SNDCTL_DSP_HALT_INPUT __SIO ('P', 33) -#define SNDCTL_DSP_RESET_INPUT SNDCTL_DSP_HALT_INPUT /* Old name */ -#define SNDCTL_DSP_HALT_OUTPUT __SIO ('P', 34) -#define SNDCTL_DSP_RESET_OUTPUT SNDCTL_DSP_HALT_OUTPUT /* Old name */ -/* - **************************************************************************** - * Low water level control - */ -#define SNDCTL_DSP_LOW_WATER __SIOW ('P', 34, int) - -/* - **************************************************************************** - * 64 bit pointer support. Only available in environments that support - * the 64 bit (long long) integer type. - */ -#ifndef OSS_NO_LONG_LONG -typedef struct -{ - long long samples; - int fifo_samples; - int filler[32]; /* For future use */ -} oss_count_t; - -#define SNDCTL_DSP_CURRENT_IPTR __SIOR ('P', 35, oss_count_t) -#define SNDCTL_DSP_CURRENT_OPTR __SIOR ('P', 36, oss_count_t) -#endif - -/* - **************************************************************************** - * Interface for selecting recording sources and playback output routings. - */ -#define SNDCTL_DSP_GET_RECSRC_NAMES __SIOR ('P', 37, oss_mixer_enuminfo) -#define SNDCTL_DSP_GET_RECSRC __SIOR ('P', 38, int) -#define SNDCTL_DSP_SET_RECSRC __SIOWR('P', 38, int) - -#define SNDCTL_DSP_GET_PLAYTGT_NAMES __SIOR ('P', 39, oss_mixer_enuminfo) -#define SNDCTL_DSP_GET_PLAYTGT __SIOR ('P', 40, int) -#define SNDCTL_DSP_SET_PLAYTGT __SIOWR('P', 40, int) -#define SNDCTL_DSP_GETRECVOL __SIOR ('P', 41, int) -#define SNDCTL_DSP_SETRECVOL __SIOWR('P', 41, int) - -/* - *************************************************************************** - * Some calls for setting the channel assignment with multi channel devices - * (see the manual for details). - */ -#ifndef OSS_NO_LONG_LONG -#define SNDCTL_DSP_GET_CHNORDER __SIOR ('P', 42, unsigned long long) -#define SNDCTL_DSP_SET_CHNORDER __SIOWR('P', 42, unsigned long long) -# define CHID_UNDEF 0 -# define CHID_L 1 -# define CHID_R 2 -# define CHID_C 3 -# define CHID_LFE 4 -# define CHID_LS 5 -# define CHID_RS 6 -# define CHID_LR 7 -# define CHID_RR 8 -#define CHNORDER_UNDEF 0x0000000000000000ULL -#define CHNORDER_NORMAL 0x0000000087654321ULL -#endif - -#define MAX_PEAK_CHANNELS 128 -typedef unsigned short oss_peaks_t[MAX_PEAK_CHANNELS]; -#define SNDCTL_DSP_GETIPEAKS __SIOR('P', 43, oss_peaks_t) -#define SNDCTL_DSP_GETOPEAKS __SIOR('P', 44, oss_peaks_t) - -#define SNDCTL_DSP_POLICY __SIOW('P', 45, int) /* See the manual */ - -/* - **************************************************************************** - * Few ioctl calls that are not official parts of OSS. They have been used - * by few freeware implementations of OSS. - */ -#define SNDCTL_DSP_GETCHANNELMASK __SIOWR('P', 64, int) -#define SNDCTL_DSP_BIND_CHANNEL __SIOWR('P', 65, int) -# define DSP_BIND_QUERY 0x00000000 -# define DSP_BIND_FRONT 0x00000001 -# define DSP_BIND_SURR 0x00000002 -# define DSP_BIND_CENTER_LFE 0x00000004 -# define DSP_BIND_HANDSET 0x00000008 -# define DSP_BIND_MIC 0x00000010 -# define DSP_BIND_MODEM1 0x00000020 -# define DSP_BIND_MODEM2 0x00000040 -# define DSP_BIND_I2S 0x00000080 -# define DSP_BIND_SPDIF 0x00000100 -# define DSP_BIND_REAR 0x00000200 - -#ifndef NO_LEGACY_MIXER -/* - **************************************************************************** - * IOCTL commands for the "legacy " /dev/mixer API (obsolete) - * - * Mixer controls - * - * There can be up to 20 different analog mixer channels. The - * SOUND_MIXER_NRDEVICES gives the currently supported maximum. - * The SOUND_MIXER_READ_DEVMASK returns a bitmask which tells - * the devices supported by the particular mixer. - * - * {!notice This "legacy" mixer API is obsolete. It has been superceded - * by a new one (see below). - */ - -#define SOUND_MIXER_NRDEVICES 28 -#define SOUND_MIXER_VOLUME 0 -#define SOUND_MIXER_BASS 1 -#define SOUND_MIXER_TREBLE 2 -#define SOUND_MIXER_SYNTH 3 -#define SOUND_MIXER_PCM 4 -#define SOUND_MIXER_SPEAKER 5 -#define SOUND_MIXER_LINE 6 -#define SOUND_MIXER_MIC 7 -#define SOUND_MIXER_CD 8 -#define SOUND_MIXER_IMIX 9 /* Recording monitor */ -#define SOUND_MIXER_ALTPCM 10 -#define SOUND_MIXER_RECLEV 11 /* Recording level */ -#define SOUND_MIXER_IGAIN 12 /* Input gain */ -#define SOUND_MIXER_OGAIN 13 /* Output gain */ -/* - * Some soundcards have three line level inputs (line, aux1 and aux2). - * Since each card manufacturer has assigned different meanings to - * these inputs, it's impractical to assign specific meanings - * (eg line, cd, synth etc.) to them. - */ -#define SOUND_MIXER_LINE1 14 /* Input source 1 (aux1) */ -#define SOUND_MIXER_LINE2 15 /* Input source 2 (aux2) */ -#define SOUND_MIXER_LINE3 16 /* Input source 3 (line) */ -#define SOUND_MIXER_DIGITAL1 17 /* Digital I/O 1 */ -#define SOUND_MIXER_DIGITAL2 18 /* Digital I/O 2 */ -#define SOUND_MIXER_DIGITAL3 19 /* Digital I/O 3 */ -#define SOUND_MIXER_PHONE 20 /* Phone */ -#define SOUND_MIXER_MONO 21 /* Mono Output */ -#define SOUND_MIXER_VIDEO 22 /* Video/TV (audio) in */ -#define SOUND_MIXER_RADIO 23 /* Radio in */ -#define SOUND_MIXER_DEPTH 24 /* Surround depth */ -#define SOUND_MIXER_REARVOL 25 /* Rear/Surround speaker vol */ -#define SOUND_MIXER_CENTERVOL 26 /* Center/LFE speaker vol */ -#define SOUND_MIXER_SIDEVOL 27 /* Side-Surround (8speaker) vol */ - -/* - * Warning: SOUND_MIXER_SURRVOL is an old name of SOUND_MIXER_SIDEVOL. - * They are both assigned to the same mixer control. Don't - * use both control names in the same program/driver. - */ -#define SOUND_MIXER_SURRVOL SOUND_MIXER_SIDEVOL - -/* Some on/off settings (SOUND_SPECIAL_MIN - SOUND_SPECIAL_MAX) */ -/* Not counted to SOUND_MIXER_NRDEVICES, but use the same number space */ -#define SOUND_ONOFF_MIN 28 -#define SOUND_ONOFF_MAX 30 - -/* Note! Number 31 cannot be used since the sign bit is reserved */ -#define SOUND_MIXER_NONE 31 - -/* - * The following unsupported macros are no longer functional. - * Use SOUND_MIXER_PRIVATE# macros in future. - */ -#define SOUND_MIXER_ENHANCE SOUND_MIXER_NONE -#define SOUND_MIXER_MUTE SOUND_MIXER_NONE -#define SOUND_MIXER_LOUD SOUND_MIXER_NONE - -#define SOUND_DEVICE_LABELS \ - {"Vol ", "Bass ", "Treble", "Synth", "Pcm ", "Speaker ", "Line ", \ - "Mic ", "CD ", "Mix ", "Pcm2 ", "Rec ", "IGain", "OGain", \ - "Aux1", "Aux2", "Aux3", "Digital1", "Digital2", "Digital3", \ - "Phone", "Mono", "Video", "Radio", "Depth", \ - "Rear", "Center", "Side"} - -#define SOUND_DEVICE_NAMES \ - {"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \ - "mic", "cd", "mix", "pcm2", "rec", "igain", "ogain", \ - "aux1", "aux2", "aux3", "dig1", "dig2", "dig3", \ - "phone", "mono", "video", "radio", "depth", \ - "rear", "center", "side"} - -/* Device bitmask identifiers */ - -#define SOUND_MIXER_RECSRC 0xff /* Arg contains a bit for each recording source */ -#define SOUND_MIXER_DEVMASK 0xfe /* Arg contains a bit for each supported device */ -#define SOUND_MIXER_RECMASK 0xfd /* Arg contains a bit for each supported recording source */ -#define SOUND_MIXER_CAPS 0xfc -# define SOUND_CAP_EXCL_INPUT 0x00000001 /* Only one recording source at a time */ -# define SOUND_CAP_NOLEGACY 0x00000004 /* For internal use only */ -# define SOUND_CAP_NORECSRC 0x00000008 -#define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */ - -/* OSS/Free ONLY */ -#define SOUND_MIXER_OUTSRC 0xfa /* Arg contains a bit for each input source to output */ -#define SOUND_MIXER_OUTMASK 0xf9 /* Arg contains a bit for each supported input source to output */ -/* OSS/Free ONLY */ - -/* Device mask bits */ - -#define SOUND_MASK_VOLUME (1 << SOUND_MIXER_VOLUME) -#define SOUND_MASK_BASS (1 << SOUND_MIXER_BASS) -#define SOUND_MASK_TREBLE (1 << SOUND_MIXER_TREBLE) -#define SOUND_MASK_SYNTH (1 << SOUND_MIXER_SYNTH) -#define SOUND_MASK_PCM (1 << SOUND_MIXER_PCM) -#define SOUND_MASK_SPEAKER (1 << SOUND_MIXER_SPEAKER) -#define SOUND_MASK_LINE (1 << SOUND_MIXER_LINE) -#define SOUND_MASK_MIC (1 << SOUND_MIXER_MIC) -#define SOUND_MASK_CD (1 << SOUND_MIXER_CD) -#define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX) -#define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM) -#define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV) -#define SOUND_MASK_IGAIN (1 << SOUND_MIXER_IGAIN) -#define SOUND_MASK_OGAIN (1 << SOUND_MIXER_OGAIN) -#define SOUND_MASK_LINE1 (1 << SOUND_MIXER_LINE1) -#define SOUND_MASK_LINE2 (1 << SOUND_MIXER_LINE2) -#define SOUND_MASK_LINE3 (1 << SOUND_MIXER_LINE3) -#define SOUND_MASK_DIGITAL1 (1 << SOUND_MIXER_DIGITAL1) -#define SOUND_MASK_DIGITAL2 (1 << SOUND_MIXER_DIGITAL2) -#define SOUND_MASK_DIGITAL3 (1 << SOUND_MIXER_DIGITAL3) -#define SOUND_MASK_MONO (1 << SOUND_MIXER_MONO) -#define SOUND_MASK_PHONE (1 << SOUND_MIXER_PHONE) -#define SOUND_MASK_RADIO (1 << SOUND_MIXER_RADIO) -#define SOUND_MASK_VIDEO (1 << SOUND_MIXER_VIDEO) -#define SOUND_MASK_DEPTH (1 << SOUND_MIXER_DEPTH) -#define SOUND_MASK_REARVOL (1 << SOUND_MIXER_REARVOL) -#define SOUND_MASK_CENTERVOL (1 << SOUND_MIXER_CENTERVOL) -#define SOUND_MASK_SIDEVOL (1 << SOUND_MIXER_SIDEVOL) - -/* Note! SOUND_MASK_SURRVOL is alias of SOUND_MASK_SIDEVOL */ -#define SOUND_MASK_SURRVOL (1 << SOUND_MIXER_SIDEVOL) - -/* Obsolete macros */ -#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE) -#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE) -#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD) - -#define MIXER_READ(dev) __SIOR('M', dev, int) -#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME) -#define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS) -#define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE) -#define SOUND_MIXER_READ_SYNTH MIXER_READ(SOUND_MIXER_SYNTH) -#define SOUND_MIXER_READ_PCM MIXER_READ(SOUND_MIXER_PCM) -#define SOUND_MIXER_READ_SPEAKER MIXER_READ(SOUND_MIXER_SPEAKER) -#define SOUND_MIXER_READ_LINE MIXER_READ(SOUND_MIXER_LINE) -#define SOUND_MIXER_READ_MIC MIXER_READ(SOUND_MIXER_MIC) -#define SOUND_MIXER_READ_CD MIXER_READ(SOUND_MIXER_CD) -#define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX) -#define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM) -#define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV) -#define SOUND_MIXER_READ_IGAIN MIXER_READ(SOUND_MIXER_IGAIN) -#define SOUND_MIXER_READ_OGAIN MIXER_READ(SOUND_MIXER_OGAIN) -#define SOUND_MIXER_READ_LINE1 MIXER_READ(SOUND_MIXER_LINE1) -#define SOUND_MIXER_READ_LINE2 MIXER_READ(SOUND_MIXER_LINE2) -#define SOUND_MIXER_READ_LINE3 MIXER_READ(SOUND_MIXER_LINE3) - -/* Obsolete macros */ -#define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE) -#define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE) -#define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD) - -#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC) -#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK) -#define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK) -#define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS) -#define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS) - -#define MIXER_WRITE(dev) __SIOWR('M', dev, int) -#define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME) -#define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS) -#define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE) -#define SOUND_MIXER_WRITE_SYNTH MIXER_WRITE(SOUND_MIXER_SYNTH) -#define SOUND_MIXER_WRITE_PCM MIXER_WRITE(SOUND_MIXER_PCM) -#define SOUND_MIXER_WRITE_SPEAKER MIXER_WRITE(SOUND_MIXER_SPEAKER) -#define SOUND_MIXER_WRITE_LINE MIXER_WRITE(SOUND_MIXER_LINE) -#define SOUND_MIXER_WRITE_MIC MIXER_WRITE(SOUND_MIXER_MIC) -#define SOUND_MIXER_WRITE_CD MIXER_WRITE(SOUND_MIXER_CD) -#define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX) -#define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM) -#define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV) -#define SOUND_MIXER_WRITE_IGAIN MIXER_WRITE(SOUND_MIXER_IGAIN) -#define SOUND_MIXER_WRITE_OGAIN MIXER_WRITE(SOUND_MIXER_OGAIN) -#define SOUND_MIXER_WRITE_LINE1 MIXER_WRITE(SOUND_MIXER_LINE1) -#define SOUND_MIXER_WRITE_LINE2 MIXER_WRITE(SOUND_MIXER_LINE2) -#define SOUND_MIXER_WRITE_LINE3 MIXER_WRITE(SOUND_MIXER_LINE3) - -/* Obsolete macros */ -#define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE) -#define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE) -#define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD) - -#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC) - -typedef struct mixer_info /* OBSOLETE */ -{ - char id[16]; - char name[32]; - int modify_counter; - int card_number; - int port_number; - char handle[32]; -} mixer_info; - -/* SOUND_MIXER_INFO is obsolete - use SNDCTL_MIXERINFO instead */ -#define SOUND_MIXER_INFO __SIOR ('M', 101, mixer_info) - -/* - * Two ioctls for special souncard function (OSS/Free only) - */ -#define SOUND_MIXER_AGC _SIOWR('M', 103, int) -#define SOUND_MIXER_3DSE _SIOWR('M', 104, int) -/* - * The SOUND_MIXER_PRIVATE# commands can be redefined by low level drivers. - * These features can be used when accessing device specific features. - */ -#define SOUND_MIXER_PRIVATE1 __SIOWR('M', 111, int) -#define SOUND_MIXER_PRIVATE2 __SIOWR('M', 112, int) -#define SOUND_MIXER_PRIVATE3 __SIOWR('M', 113, int) -#define SOUND_MIXER_PRIVATE4 __SIOWR('M', 114, int) -#define SOUND_MIXER_PRIVATE5 __SIOWR('M', 115, int) - -/* The following two controls were never implemented and they should not be used. */ -#define SOUND_MIXER_READ_MAINVOL __SIOR ('M', 116, int) -#define SOUND_MIXER_WRITE_MAINVOL __SIOWR('M', 116, int) - -/* - * SOUND_MIXER_GETLEVELS and SOUND_MIXER_SETLEVELS calls can be used - * for querying current mixer settings from the driver and for loading - * default volume settings _prior_ activating the mixer (loading - * doesn't affect current state of the mixer hardware). These calls - * are for internal use by the driver software only. - */ - -typedef struct mixer_vol_table -{ - int num; /* Index to volume table */ - char name[32]; - int levels[32]; -} mixer_vol_table; - -#define SOUND_MIXER_GETLEVELS __SIOWR('M', 116, mixer_vol_table) -#define SOUND_MIXER_SETLEVELS __SIOWR('M', 117, mixer_vol_table) - -#define OSS_GETVERSION __SIOR ('M', 118, int) - -/* - * Calls to set/get the recording gain for the currently active - * recording source. These calls automatically map to the right control. - * Note that these calls are not supported by all drivers. In this case - * the call will return -1 with errno set to EINVAL - * - * The _MONGAIN work in similar way but set/get the monitoring gain for - * the currently selected recording source. - */ -#define SOUND_MIXER_READ_RECGAIN __SIOR ('M', 119, int) -#define SOUND_MIXER_WRITE_RECGAIN __SIOWR('M', 119, int) -#define SOUND_MIXER_READ_MONGAIN __SIOR ('M', 120, int) -#define SOUND_MIXER_WRITE_MONGAIN __SIOWR('M', 120, int) - -/* The following call is for driver development time purposes. It's not - * present in any released drivers. - */ -typedef unsigned char oss_reserved_t[512]; -#define SOUND_MIXER_RESERVED __SIOWR('M', 121, oss_reserved_t) -#endif /* ifndef NO_LEGACY_MIXER */ - -/* - ************************************************************************* - * The "new" mixer API of OSS 4.0 and later. - * - * This improved mixer API makes it possible to access every possible feature - * of every possible device. However you should read the mixer programming - * section of the OSS API Developer's Manual. There is no chance that you - * could use this interface correctly just by examining this header. - */ - -typedef struct oss_sysinfo -{ - char product[32]; /* For example OSS/Free, OSS/Linux or OSS/Solaris */ - char version[32]; /* For example 4.0a */ - int versionnum; /* See OSS_GETVERSION */ - char options[128]; /* Reserved */ - - int numaudios; /* # of audio/dsp devices */ - int openedaudio[8]; /* Bit mask telling which audio devices are busy */ - - int numsynths; /* # of availavle synth devices */ - int nummidis; /* # of available MIDI ports */ - int numtimers; /* # of available timer devices */ - int nummixers; /* # of mixer devices */ - - int openedmidi[8]; /* Bit mask telling which midi devices are busy */ - int numcards; /* Number of sound cards in the system */ - int numaudioengines; /* Number of audio engines in the system */ - int filler[240]; /* For future expansion (set to -1) */ -} oss_sysinfo; - -typedef struct oss_mixext -{ - int dev; /* Mixer device number */ - int ctrl; /* Controller number */ - int type; /* Entry type */ -# define MIXT_DEVROOT 0 /* Device root entry */ -# define MIXT_GROUP 1 /* Controller group */ -# define MIXT_ONOFF 2 /* OFF (0) or ON (1) */ -# define MIXT_ENUM 3 /* Enumerated (0 to maxvalue) */ -# define MIXT_MONOSLIDER 4 /* Mono slider (0 to 255) */ -# define MIXT_STEREOSLIDER 5 /* Stereo slider (dual 0 to 255) */ -# define MIXT_MESSAGE 6 /* (Readable) textual message */ -# define MIXT_MONOVU 7 /* VU meter value (mono) */ -# define MIXT_STEREOVU 8 /* VU meter value (stereo) */ -# define MIXT_MONOPEAK 9 /* VU meter peak value (mono) */ -# define MIXT_STEREOPEAK 10 /* VU meter peak value (stereo) */ -# define MIXT_RADIOGROUP 11 /* Radio button group */ -# define MIXT_MARKER 12 /* Separator between normal and extension entries */ -# define MIXT_VALUE 13 /* Decimal value entry */ -# define MIXT_HEXVALUE 14 /* Hexadecimal value entry */ -# define MIXT_MONODB 15 /* OBSOLETE */ -# define MIXT_STEREODB 16 /* OBSOLETE */ -# define MIXT_SLIDER 17 /* Slider (mono) with full (31 bit) postitive integer range */ -# define MIXT_3D 18 - -/* - * Sliders with range expanded to 15 bits per channel (0-32767) - */ -# define MIXT_MONOSLIDER16 19 -# define MIXT_STEREOSLIDER16 20 - - /* Possible value range (minvalue to maxvalue) */ - /* Note that maxvalue may also be smaller than minvalue */ - int maxvalue; - int minvalue; - - int flags; -# define MIXF_READABLE 0x00000001 /* Has readable value */ -# define MIXF_WRITEABLE 0x00000002 /* Has writeable value */ -# define MIXF_POLL 0x00000004 /* May change itself */ -# define MIXF_HZ 0x00000008 /* Herz scale */ -# define MIXF_STRING 0x00000010 /* Use dynamic extensions for value */ -# define MIXF_DYNAMIC 0x00000010 /* Supports dynamic extensions */ -# define MIXF_OKFAIL 0x00000020 /* Interpret value as 1=OK, 0=FAIL */ -# define MIXF_FLAT 0x00000040 /* Flat vertical space requirements */ -# define MIXF_LEGACY 0x00000080 /* Legacy mixer control group */ -# define MIXF_CENTIBEL 0x00000100 /* Centibel (0.1 dB) step size */ -# define MIXF_DECIBEL 0x00000200 /* Step size of 1 dB */ -# define MIXF_MAINVOL 0x00000400 /* Main volume control */ -# define MIXF_PCMVOL 0x00000800 /* PCM output volume control */ -# define MIXF_RECVOL 0x00001000 /* PCM recording volume control */ - char id[16]; /* Mnemonic ID (mainly for internal use) */ - int parent; /* Entry# of parent (group) node (-1 if root) */ - - int dummy; /* Internal use */ - - int timestamp; - - char data[64]; /* Misc data (entry type dependent) */ - unsigned char enum_present[32]; /* Mask of allowed enum values */ - int control_no; /* SOUND_MIXER_VOLUME..SOUND_MIXER_MIDI */ - /* (-1 means not indicated) */ - -/* - * The desc field is reserved for internal purposes of OSS. It should not be - * used by applications. - */ - unsigned int desc; -#define MIXEXT_SCOPE_MASK 0x0000003f -#define MIXEXT_SCOPE_OTHER 0x00000000 -#define MIXEXT_SCOPE_INPUT 0x00000001 -#define MIXEXT_SCOPE_OUTPUT 0x00000002 -#define MIXEXT_SCOPE_MONITOR 0x00000003 -#define MIXEXT_SCOPE_RECSWITCH 0x00000004 - - char extname[32]; - int update_counter; - int filler[7]; -} oss_mixext; - -typedef struct oss_mixext_root -{ - char id[16]; - char name[48]; -} oss_mixext_root; - -typedef struct oss_mixer_value -{ - int dev; - int ctrl; - int value; - int flags; /* Reserved for future use. Initialize to 0 */ - int timestamp; /* Must be set to oss_mixext.timestamp */ - int filler[8]; /* Reserved for future use. Initialize to 0 */ -} oss_mixer_value; - -#define OSS_ENUM_MAXVALUE 255 -typedef struct oss_mixer_enuminfo -{ - int dev; - int ctrl; - int nvalues; - int version; /* Read the manual */ - short strindex[OSS_ENUM_MAXVALUE]; - char strings[3000]; -} oss_mixer_enuminfo; - -#define OPEN_READ PCM_ENABLE_INPUT -#define OPEN_WRITE PCM_ENABLE_OUTPUT -#define OPEN_READWRITE (OPEN_READ|OPEN_WRITE) - -typedef struct oss_audioinfo -{ - int dev; /* Audio device number */ - char name[64]; - int busy; /* 0, OPEN_READ, OPEN_WRITE or OPEN_READWRITE */ - int pid; - int caps; /* PCM_CAP_INPUT, PCM_CAP_OUTPUT */ - int iformats, oformats; - int magic; /* Reserved for internal use */ - char cmd[64]; /* Command using the device (if known) */ - int card_number; - int port_number; - int mixer_dev; - int legacy_device; /* Obsolete field. Replaced by devnode */ - int enabled; /* 1=enabled, 0=device not ready at this moment */ - int flags; /* For internal use only - no practical meaning */ - int min_rate, max_rate; /* Sample rate limits */ - int min_channels, max_channels; /* Number of channels supported */ - int binding; /* DSP_BIND_FRONT, etc. 0 means undefined */ - int rate_source; - char handle[32]; -#define OSS_MAX_SAMPLE_RATES 20 /* Cannot be changed */ - unsigned int nrates, rates[OSS_MAX_SAMPLE_RATES]; /* Please read the manual before using these */ - oss_longname_t song_name; /* Song name (if given) */ - oss_label_t label; /* Device label (if given) */ - int latency; /* In usecs, -1=unknown */ - oss_devnode_t devnode; /* Device special file name (absolute path) */ - int next_play_engine; /* Read the documentation for more info */ - int next_rec_engine; /* Read the documentation for more info */ - int filler[184]; -} oss_audioinfo; - -typedef struct oss_mixerinfo -{ - int dev; - char id[16]; - char name[32]; - int modify_counter; - int card_number; - int port_number; - char handle[32]; - int magic; /* Reserved */ - int enabled; /* Reserved */ - int caps; -#define MIXER_CAP_VIRTUAL 0x00000001 -#define MIXER_CAP_LAYOUT_B 0x00000002 /* For internal use only */ -#define MIXER_CAP_NARROW 0x00000004 /* Conserve horiz space */ - int flags; /* Reserved */ - int nrext; - /* - * The priority field can be used to select the default (motherboard) - * mixer device. The mixer with the highest priority is the - * most preferred one. -2 or less means that this device cannot be used - * as the default mixer. - */ - int priority; - oss_devnode_t devnode; /* Device special file name (absolute path) */ - int legacy_device; - int filler[245]; /* Reserved */ -} oss_mixerinfo; - -typedef struct oss_midi_info -{ - int dev; /* Midi device number */ - char name[64]; - int busy; /* 0, OPEN_READ, OPEN_WRITE or OPEN_READWRITE */ - int pid; - char cmd[64]; /* Command using the device (if known) */ - int caps; -#define MIDI_CAP_MPU401 0x00000001 /**** OBSOLETE ****/ -#define MIDI_CAP_INPUT 0x00000002 -#define MIDI_CAP_OUTPUT 0x00000004 -#define MIDI_CAP_INOUT (MIDI_CAP_INPUT|MIDI_CAP_OUTPUT) -#define MIDI_CAP_VIRTUAL 0x00000008 /* Pseudo device */ -#define MIDI_CAP_MTCINPUT 0x00000010 /* Supports SNDCTL_MIDI_MTCINPUT */ -#define MIDI_CAP_CLIENT 0x00000020 /* Virtual client side device */ -#define MIDI_CAP_SERVER 0x00000040 /* Virtual server side device */ -#define MIDI_CAP_INTERNAL 0x00000080 /* Internal (synth) device */ -#define MIDI_CAP_EXTERNAL 0x00000100 /* external (MIDI port) device */ -#define MIDI_CAP_PTOP 0x00000200 /* Point to point link to one device */ -#define MIDI_CAP_MTC 0x00000400 /* MTC/SMPTE (control) device */ - int magic; /* Reserved for internal use */ - int card_number; - int port_number; - int enabled; /* 1=enabled, 0=device not ready at this moment */ - int flags; /* For internal use only - no practical meaning */ - char handle[32]; - oss_longname_t song_name; /* Song name (if known) */ - oss_label_t label; /* Device label (if given) */ - int latency; /* In usecs, -1=unknown */ - oss_devnode_t devnode; /* Device special file name (absolute path) */ - int legacy_device; /* Legacy device mapping */ - int filler[235]; -} oss_midi_info; - -typedef struct oss_card_info -{ - int card; - char shortname[16]; - char longname[128]; - int flags; - int filler[256]; -} oss_card_info; - -#define SNDCTL_SYSINFO __SIOR ('X', 1, oss_sysinfo) -#define OSS_SYSINFO SNDCTL_SYSINFO /* Old name */ - -#define SNDCTL_MIX_NRMIX __SIOR ('X', 2, int) -#define SNDCTL_MIX_NREXT __SIOWR('X', 3, int) -#define SNDCTL_MIX_EXTINFO __SIOWR('X', 4, oss_mixext) -#define SNDCTL_MIX_READ __SIOWR('X', 5, oss_mixer_value) -#define SNDCTL_MIX_WRITE __SIOWR('X', 6, oss_mixer_value) - -#define SNDCTL_AUDIOINFO __SIOWR('X', 7, oss_audioinfo) -#define SNDCTL_MIX_ENUMINFO __SIOWR('X', 8, oss_mixer_enuminfo) -#define SNDCTL_MIDIINFO __SIOWR('X', 9, oss_midi_info) -#define SNDCTL_MIXERINFO __SIOWR('X',10, oss_mixerinfo) -#define SNDCTL_CARDINFO __SIOWR('X',11, oss_card_info) -#define SNDCTL_ENGINEINFO __SIOWR('X',12, oss_audioinfo) -#define SNDCTL_AUDIOINFO_EX __SIOWR('X',13, oss_audioinfo) - -/* ioctl codes 'X', 200-255 are reserved for internal use */ - -/* - * Few more "globally" available ioctl calls. - */ -#define SNDCTL_SETSONG __SIOW ('Y', 2, oss_longname_t) -#define SNDCTL_GETSONG __SIOR ('Y', 2, oss_longname_t) -#define SNDCTL_SETNAME __SIOW ('Y', 3, oss_longname_t) -#define SNDCTL_SETLABEL __SIOW ('Y', 4, oss_label_t) -#define SNDCTL_GETLABEL __SIOR ('Y', 4, oss_label_t) -/* - * The "new" mixer API definitions end here. - *************************************** - */ - -/* - ********************************************************* - * Few routines that are included in -lOSSlib - * - * At this moment this interface is not used. OSSlib contains just - * stubs that call the related system calls directly. - */ -#ifdef OSSLIB -extern int osslib_open (const char *path, int flags, int dummy); -extern void osslib_close (int fd); -extern int osslib_write (int fd, const void *buf, int count); -extern int osslib_read (int fd, void *buf, int count); -extern int osslib_ioctl (int fd, unsigned int request, void *arg); -#else -# define osslib_open open -# define osslib_close close -# define osslib_write write -# define osslib_read read -# define osslib_ioctl ioctl -#endif - -#if 1 -#define SNDCTL_DSP_NONBLOCK __SIO ('P',14) /* Obsolete. Not supported any more */ -#endif - -#if 1 -/* - * Some obsolete macros that are not part of Open Sound System API. - */ -#define SOUND_PCM_READ_RATE SOUND_PCM_READ_RATE_is_obsolete -#define SOUND_PCM_READ_BITS SOUND_PCM_READ_BITS_is_obsolete -#define SOUND_PCM_READ_CHANNELS SOUND_PCM_READ_CHANNELS_is_obsolete -#define SOUND_PCM_WRITE_RATE SOUND_PCM_WRITE_RATE_is_obsolet_use_SNDCTL_DSP_SPEED_instead -#define SOUND_PCM_WRITE_CHANNELS SOUND_PCM_WRITE_CHANNELS_is_obsolete_use_SNDCTL_DSP_CHANNELS_instead -#define SOUND_PCM_WRITE_BITS SOUND_PCM_WRITE_BITS_is_obsolete_use_SNDCTL_DSP_SETFMT_instead -#define SOUND_PCM_POST SOUND_PCM_POST_is_obsolete_use_SNDCTL_DSP_POST_instead -#define SOUND_PCM_RESET SOUND_PCM_RESET_is_obsolete_use_SNDCTL_DSP_HALT_instead -#define SOUND_PCM_SYNC SOUND_PCM_SYNC_is_obsolete_use_SNDCTL_DSP_SYNC_instead -#define SOUND_PCM_SUBDIVIDE SOUND_PCM_SUBDIVIDE_is_obsolete_use_SNDCTL_DSP_SUBDIVIDE_instead -#define SOUND_PCM_SETFRAGMENT SOUND_PCM_SETFRAGMENT_is_obsolete_use_SNDCTL_DSP_SETFRAGMENT_instead -#define SOUND_PCM_GETFMTS SOUND_PCM_GETFMTS_is_obsolete_use_SNDCTL_DSP_GETFMTS_instead -#define SOUND_PCM_SETFMT SOUND_PCM_SETFMT_is_obsolete_use_SNDCTL_DSP_SETFMT_instead -#define SOUND_PCM_GETOSPACE SOUND_PCM_GETOSPACE_is_obsolete_use_SNDCTL_DSP_GETOSPACE_instead -#define SOUND_PCM_GETISPACE SOUND_PCM_GETISPACE_is_obsolete_use_SNDCTL_DSP_GETISPACE_instead -#define SOUND_PCM_NONBLOCK SOUND_PCM_NONBLOCK_is_obsolete_use_SNDCTL_DSP_NONBLOCK_instead -#define SOUND_PCM_GETCAPS SOUND_PCM_GETCAPS_is_obsolete_use_SNDCTL_DSP_GETCAPS_instead -#define SOUND_PCM_GETTRIGGER SOUND_PCM_GETTRIGGER_is_obsolete_use_SNDCTL_DSP_GETTRIGGER_instead -#define SOUND_PCM_SETTRIGGER SOUND_PCM_SETTRIGGER_is_obsolete_use_SNDCTL_DSP_SETTRIGGER_instead -#define SOUND_PCM_SETSYNCRO SOUND_PCM_SETSYNCRO_is_obsolete_use_SNDCTL_DSP_SETSYNCRO_instead -#define SOUND_PCM_GETIPTR SOUND_PCM_GETIPTR_is_obsolete_use_SNDCTL_DSP_GETIPTR_instead -#define SOUND_PCM_GETOPTR SOUND_PCM_GETOPTR_is_obsolete_use_SNDCTL_DSP_GETOPTR_instead -#define SOUND_PCM_MAPINBUF SOUND_PCM_MAPINBUF_is_obsolete_use_SNDCTL_DSP_MAPINBUF_instead -#define SOUND_PCM_MAPOUTBUF SOUND_PCM_MAPOUTBUF_is_obsolete_use_SNDCTL_DSP_MAPOUTBUF_instead -#endif - -#endif diff --git a/tests/Makefile.in b/tests/Makefile.in index bc17be5..ec41447 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -3,49 +3,52 @@ PROGRAMS = audioprobe playsaw playraw record duplex testall RM = /bin/rm -SRC_PATH = ../ -INCLUDE = ../ +SRC_PATH = .. +INCLUDE = .. OBJECT_PATH = @object_path@ vpath %.o $(OBJECT_PATH) -OBJECTS = RtAudio.o +OBJECTS = RtAudio.o @objects@ CC = @CXX@ DEFS = @debug@ DEFS += @audio_apis@ CFLAGS = @cflags@ -CFLAGS += @warn@ -I$(INCLUDE) +CFLAGS += @warn@ -I$(INCLUDE) -I../include LIBRARY = @LIBS@ LIBRARY += @frameworks@ %.o : $(SRC_PATH)/%.cpp $(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@ +%.o : ../include/%.cpp + $(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@ + all : $(PROGRAMS) audioprobe : audioprobe.cpp $(OBJECTS) - $(CC) $(CFLAGS) $(DEFS) -o audioprobe audioprobe.cpp $(OBJECT_PATH)/RtAudio.o $(LIBRARY) + $(CC) $(CFLAGS) $(DEFS) -o audioprobe audioprobe.cpp $(OBJECT_PATH)/*.o $(LIBRARY) playsaw : playsaw.cpp $(OBJECTS) - $(CC) $(CFLAGS) $(DEFS) -o playsaw playsaw.cpp $(OBJECT_PATH)/RtAudio.o $(LIBRARY) + $(CC) $(CFLAGS) $(DEFS) -o playsaw playsaw.cpp $(OBJECT_PATH)/*.o $(LIBRARY) playraw : playraw.cpp $(OBJECTS) - $(CC) $(CFLAGS) $(DEFS) -o playraw playraw.cpp $(OBJECT_PATH)/RtAudio.o $(LIBRARY) + $(CC) $(CFLAGS) $(DEFS) -o playraw playraw.cpp $(OBJECT_PATH)/*.o $(LIBRARY) record : record.cpp $(OBJECTS) - $(CC) $(CFLAGS) $(DEFS) -o record record.cpp $(OBJECT_PATH)/RtAudio.o $(LIBRARY) + $(CC) $(CFLAGS) $(DEFS) -o record record.cpp $(OBJECT_PATH)/*.o $(LIBRARY) duplex : duplex.cpp $(OBJECTS) - $(CC) $(CFLAGS) $(DEFS) -o duplex duplex.cpp $(OBJECT_PATH)/RtAudio.o $(LIBRARY) + $(CC) $(CFLAGS) $(DEFS) -o duplex duplex.cpp $(OBJECT_PATH)/*.o $(LIBRARY) testall : testall.cpp $(OBJECTS) - $(CC) $(CFLAGS) $(DEFS) -o testall testall.cpp $(OBJECT_PATH)/RtAudio.o $(LIBRARY) + $(CC) $(CFLAGS) $(DEFS) -o testall testall.cpp $(OBJECT_PATH)/*.o $(LIBRARY) clean : -rm $(OBJECT_PATH)/*.o -rm $(PROGRAMS) - -rm -f *.raw *~ + -rm -f *.raw *~ *.exe strip : strip $(PROGRAMS) diff --git a/tests/Windows/rtaudio.dsw b/tests/Windows/rtaudio.dsw index ee73090..fe5f324 100755 --- a/tests/Windows/rtaudio.dsw +++ b/tests/Windows/rtaudio.dsw @@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 ############################################################################### -Project: "duplex"=".\duplex.dsp" - Package Owner=<4> +Project: "audioprobe"=.\audioprobe.dsp - Package Owner=<4> Package=<5> {{{ @@ -15,7 +15,7 @@ Package=<4> ############################################################################### -Project: "playraw"=".\playraw.dsp" - Package Owner=<4> +Project: "duplex"=.\duplex.dsp - Package Owner=<4> Package=<5> {{{ @@ -27,7 +27,7 @@ Package=<4> ############################################################################### -Project: "playsaw"=".\playsaw.dsp" - Package Owner=<4> +Project: "playraw"=.\playraw.dsp - Package Owner=<4> Package=<5> {{{ @@ -39,7 +39,7 @@ Package=<4> ############################################################################### -Project: "probe"=".\probe.dsp" - Package Owner=<4> +Project: "playsaw"=.\playsaw.dsp - Package Owner=<4> Package=<5> {{{ @@ -51,7 +51,7 @@ Package=<4> ############################################################################### -Project: "record"=".\record.dsp" - Package Owner=<4> +Project: "record"=.\record.dsp - Package Owner=<4> Package=<5> {{{ @@ -63,7 +63,7 @@ Package=<4> ############################################################################### -Project: "testall"=".\testall.dsp" - Package Owner=<4> +Project: "testall"=.\testall.dsp - Package Owner=<4> Package=<5> {{{ diff --git a/tests/playsaw.cpp b/tests/playsaw.cpp index 772881c..c39bcb4 100644 --- a/tests/playsaw.cpp +++ b/tests/playsaw.cpp @@ -129,8 +129,7 @@ int main( int argc, char *argv[] ) if ( argc > 4 ) offset = (unsigned int) atoi( argv[4] ); - double *data; - data = (double *) calloc( channels, sizeof( double ) ); + double *data = (double *) calloc( channels, sizeof( double ) ); // Let RtAudio print messages to stderr. dac.showWarnings( true ); diff --git a/tests/testall.cpp b/tests/testall.cpp index 5efb0dd..2eeb330 100644 --- a/tests/testall.cpp +++ b/tests/testall.cpp @@ -108,8 +108,7 @@ int main( int argc, char *argv[] ) if ( argc > 4 ) offset = (unsigned int) atoi( argv[4] ); - double *data; - data = (double *) calloc( channels, sizeof( double ) ); + double *data = (double *) calloc( channels, sizeof( double ) ); // Let RtAudio print messages to stderr. dac.showWarnings( true ); -- cgit v1.2.3 From 057ff0c4d3dd63b2cc9e561d53e76e063e9fa413 Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Wed, 5 Dec 2007 19:11:55 +0000 Subject: Change of OSS soundcard.h file path (gps). --- RtAudio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'RtAudio.cpp') diff --git a/RtAudio.cpp b/RtAudio.cpp index f5b324f..5e332dd 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -5970,7 +5970,7 @@ extern "C" void *alsaCallbackHandler( void *ptr ) #include #include #include -#include "oss/soundcard.h" +#include "soundcard.h" #include #include -- cgit v1.2.3 From 3dc6e2e86821303784512f86805683f1fda14ccb Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Fri, 7 Dec 2007 07:41:32 +0000 Subject: More updates for 4.0.3 release. --- RtAudio.cpp | 2 +- RtAudio.h | 2 +- doc/doxygen/Doxyfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'RtAudio.cpp') diff --git a/RtAudio.cpp b/RtAudio.cpp index 5e332dd..cdefda4 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -38,7 +38,7 @@ */ /************************************************************************/ -// RtAudio: Version 4.0 +// RtAudio: Version 4.0.3 #include "RtAudio.h" #include diff --git a/RtAudio.h b/RtAudio.h index 1bb1336..5acc9a5 100644 --- a/RtAudio.h +++ b/RtAudio.h @@ -42,7 +42,7 @@ \file RtAudio.h */ -// RtAudio: Version 4.0 +// RtAudio: Version 4.0.3 #ifndef __RTAUDIO_H #define __RTAUDIO_H diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index e4b0cef..0b72a2a 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = RtAudio # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 4.0 +PROJECT_NUMBER = 4.0.3 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. -- cgit v1.2.3