Various configure changes for MinGW (gps).
authorGary Scavone <gary@music.mcgill.ca>
Tue, 4 Dec 2007 20:09:57 +0000 (20:09 +0000)
committerStephen Sinclair <sinclair@music.mcgill.ca>
Thu, 10 Oct 2013 23:31:24 +0000 (01:31 +0200)
35 files changed:
Makefile.in
RtAudio.cpp
RtAudio.h
asio/asio.cpp [deleted file]
asio/asio.h [deleted file]
asio/asiodrivers.cpp [deleted file]
asio/asiodrivers.h [deleted file]
asio/asiodrvr.h [deleted file]
asio/asiolist.cpp [deleted file]
asio/asiolist.h [deleted file]
asio/asiosys.h [deleted file]
asio/ginclude.h [deleted file]
asio/iasiodrv.h [deleted file]
asio/iasiothiscallresolver.cpp [deleted file]
asio/iasiothiscallresolver.h [deleted file]
configure.ac
include/asio.cpp [new file with mode: 0644]
include/asio.h [new file with mode: 0644]
include/asiodrivers.cpp [new file with mode: 0644]
include/asiodrivers.h [new file with mode: 0644]
include/asiodrvr.h [new file with mode: 0644]
include/asiolist.cpp [new file with mode: 0644]
include/asiolist.h [new file with mode: 0644]
include/asiosys.h [new file with mode: 0644]
include/dsound.h [new file with mode: 0644]
include/ginclude.h [new file with mode: 0644]
include/iasiodrv.h [new file with mode: 0644]
include/iasiothiscallresolver.cpp [new file with mode: 0644]
include/iasiothiscallresolver.h [new file with mode: 0644]
include/soundcard.h [new file with mode: 0644]
oss/soundcard.h [deleted file]
tests/Makefile.in
tests/Windows/rtaudio.dsw
tests/playsaw.cpp
tests/testall.cpp

index dfebb0ebb3028afa36095318782bbc35865e61a6..57df82b16cddb817501bb8951083ae769332f71a 100644 (file)
@@ -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)
index 8b6402b27faa22c8914fd9d8687b3c922251a7cb..f5b324f22539d713e55310196e747ff37dfd7902 100644 (file)
@@ -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 <cmath>
 
 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; i<nDevices; i++ )
+    devices_[i] = getDeviceInfo( i );
+}
+
 bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
                                    unsigned int firstChannel, unsigned int sampleRate,
                                    RtAudioFormat format, unsigned int *bufferSize,
@@ -2482,6 +2495,12 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
     return FAILURE;
   }
 
+  // The getDeviceInfo() function will not work when a stream is open
+  // because ASIO does not allow multiple devices to run at the same
+  // time.  Thus, we'll probe the system before opening a stream and
+  // save the results for use by getDeviceInfo().
+  this->saveDeviceInfo();
+
   // 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;
index 5b6dd30a588709079a4cd52d9eb160a9c1e8b55f..1bb13368078ccedc7f206e45f3458a08c0e6588f 100644 (file)
--- a/RtAudio.h
+++ b/RtAudio.h
@@ -794,6 +794,8 @@ public:
 
   private:
 
+  std::vector<RtAudio::DeviceInfo> 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 (file)
index b241663..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*\r
-       Steinberg Audio Stream I/O API\r
-       (c) 1996, Steinberg Soft- und Hardware GmbH\r
-\r
-       asio.cpp\r
-       \r
-       asio functions entries which translate the\r
-       asio interface to the asiodrvr class methods\r
-*/ \r
-       \r
-#include <string.h>\r
-#include "asiosys.h"           // platform definition\r
-#include "asio.h"\r
-\r
-#if MAC\r
-#include "asiodrvr.h"\r
-\r
-#pragma export on\r
-\r
-AsioDriver *theAsioDriver = 0;\r
-\r
-extern "C"\r
-{\r
-\r
-long main()\r
-{\r
-       return 'ASIO';\r
-}\r
-\r
-#elif WINDOWS\r
-\r
-#include "windows.h"\r
-#include "iasiodrv.h"\r
-#include "asiodrivers.h"\r
-\r
-IASIO *theAsioDriver = 0;\r
-extern AsioDrivers *asioDrivers;\r
-\r
-#elif SGI || SUN || BEOS || LINUX\r
-#include "asiodrvr.h"\r
-static AsioDriver *theAsioDriver = 0;\r
-#endif\r
-\r
-//-----------------------------------------------------------------------------------------------------\r
-ASIOError ASIOInit(ASIODriverInfo *info)\r
-{\r
-#if MAC || SGI || SUN || BEOS || LINUX\r
-       if(theAsioDriver)\r
-       {\r
-               delete theAsioDriver;\r
-               theAsioDriver = 0;\r
-       }               \r
-       info->driverVersion = 0;\r
-       strcpy(info->name, "No ASIO Driver");\r
-       theAsioDriver = getDriver();\r
-       if(!theAsioDriver)\r
-       {\r
-               strcpy(info->errorMessage, "Not enough memory for the ASIO driver!"); \r
-               return ASE_NotPresent;\r
-       }\r
-       if(!theAsioDriver->init(info->sysRef))\r
-       {\r
-               theAsioDriver->getErrorMessage(info->errorMessage);\r
-               delete theAsioDriver;\r
-               theAsioDriver = 0;\r
-               return ASE_NotPresent;\r
-       }\r
-       strcpy(info->errorMessage, "No ASIO Driver Error");\r
-       theAsioDriver->getDriverName(info->name);\r
-       info->driverVersion = theAsioDriver->getDriverVersion();\r
-       return ASE_OK;\r
-\r
-#else\r
-\r
-       info->driverVersion = 0;\r
-       strcpy(info->name, "No ASIO Driver");\r
-       if(theAsioDriver)       // must be loaded!\r
-       {\r
-               if(!theAsioDriver->init(info->sysRef))\r
-               {\r
-                       theAsioDriver->getErrorMessage(info->errorMessage);\r
-                       theAsioDriver = 0;\r
-                       return ASE_NotPresent;\r
-               }               \r
-\r
-               strcpy(info->errorMessage, "No ASIO Driver Error");\r
-               theAsioDriver->getDriverName(info->name);\r
-               info->driverVersion = theAsioDriver->getDriverVersion();\r
-               return ASE_OK;\r
-       }\r
-       return ASE_NotPresent;\r
-\r
-#endif // !MAC\r
-}\r
-\r
-ASIOError ASIOExit(void)\r
-{\r
-       if(theAsioDriver)\r
-       {\r
-#if WINDOWS\r
-               asioDrivers->removeCurrentDriver();\r
-#else\r
-               delete theAsioDriver;\r
-#endif\r
-       }               \r
-       theAsioDriver = 0;\r
-       return ASE_OK;\r
-}\r
-\r
-ASIOError ASIOStart(void)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->start();\r
-}\r
-\r
-ASIOError ASIOStop(void)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->stop();\r
-}\r
-\r
-ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels)\r
-{\r
-       if(!theAsioDriver)\r
-       {\r
-               *numInputChannels = *numOutputChannels = 0;\r
-               return ASE_NotPresent;\r
-       }\r
-       return theAsioDriver->getChannels(numInputChannels, numOutputChannels);\r
-}\r
-\r
-ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency)\r
-{\r
-       if(!theAsioDriver)\r
-       {\r
-               *inputLatency = *outputLatency = 0;\r
-               return ASE_NotPresent;\r
-       }\r
-       return theAsioDriver->getLatencies(inputLatency, outputLatency);\r
-}\r
-\r
-ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity)\r
-{\r
-       if(!theAsioDriver)\r
-       {\r
-               *minSize = *maxSize = *preferredSize = *granularity = 0;\r
-               return ASE_NotPresent;\r
-       }\r
-       return theAsioDriver->getBufferSize(minSize, maxSize, preferredSize, granularity);\r
-}\r
-\r
-ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->canSampleRate(sampleRate);\r
-}\r
-\r
-ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->getSampleRate(currentRate);\r
-}\r
-\r
-ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->setSampleRate(sampleRate);\r
-}\r
-\r
-ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources)\r
-{\r
-       if(!theAsioDriver)\r
-       {\r
-               *numSources = 0;\r
-               return ASE_NotPresent;\r
-       }\r
-       return theAsioDriver->getClockSources(clocks, numSources);\r
-}\r
-\r
-ASIOError ASIOSetClockSource(long reference)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->setClockSource(reference);\r
-}\r
-\r
-ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->getSamplePosition(sPos, tStamp);\r
-}\r
-\r
-ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info)\r
-{\r
-       if(!theAsioDriver)\r
-       {\r
-               info->channelGroup = -1;\r
-               info->type = ASIOSTInt16MSB;\r
-               strcpy(info->name, "None");\r
-               return ASE_NotPresent;\r
-       }\r
-       return theAsioDriver->getChannelInfo(info);\r
-}\r
-\r
-ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
-       long bufferSize, ASIOCallbacks *callbacks)\r
-{\r
-       if(!theAsioDriver)\r
-       {\r
-               ASIOBufferInfo *info = bufferInfos;\r
-               for(long i = 0; i < numChannels; i++, info++)\r
-                       info->buffers[0] = info->buffers[1] = 0;\r
-               return ASE_NotPresent;\r
-       }\r
-       return theAsioDriver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks);\r
-}\r
-\r
-ASIOError ASIODisposeBuffers(void)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->disposeBuffers();\r
-}\r
-\r
-ASIOError ASIOControlPanel(void)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->controlPanel();\r
-}\r
-\r
-ASIOError ASIOFuture(long selector, void *opt)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->future(selector, opt);\r
-}\r
-\r
-ASIOError ASIOOutputReady(void)\r
-{\r
-       if(!theAsioDriver)\r
-               return ASE_NotPresent;\r
-       return theAsioDriver->outputReady();\r
-}\r
-\r
-#if MAC\r
-}      // extern "C"\r
-#pragma export off\r
-#endif\r
-\r
-\r
diff --git a/asio/asio.h b/asio/asio.h
deleted file mode 100644 (file)
index 8ec811f..0000000
+++ /dev/null
@@ -1,1054 +0,0 @@
-//---------------------------------------------------------------------------------------------------\r
-//---------------------------------------------------------------------------------------------------\r
-\r
-/*\r
-       Steinberg Audio Stream I/O API\r
-       (c) 1997 - 2005, Steinberg Media Technologies GmbH\r
-\r
-       ASIO Interface Specification v 2.1\r
-\r
-       2005 - Added support for DSD sample data (in cooperation with Sony)\r
-\r
-\r
-       basic concept is an i/o synchronous double-buffer scheme:\r
-       \r
-       on bufferSwitch(index == 0), host will read/write:\r
-\r
-               after ASIOStart(), the\r
-  read  first input buffer A (index 0)\r
-       |   will be invalid (empty)\r
-       *   ------------------------\r
-       |------------------------|-----------------------|\r
-       |                        |                       |\r
-       |  Input Buffer A (0)    |   Input Buffer B (1)  |\r
-       |                        |                       |\r
-       |------------------------|-----------------------|\r
-       |                        |                       |\r
-       |  Output Buffer A (0)   |   Output Buffer B (1) |\r
-       |                        |                       |\r
-       |------------------------|-----------------------|\r
-       *                        -------------------------\r
-       |                        before calling ASIOStart(),\r
-  write                      host will have filled output\r
-                             buffer B (index 1) already\r
-\r
-  *please* take special care of proper statement of input\r
-  and output latencies (see ASIOGetLatencies()), these\r
-  control sequencer sync accuracy\r
-\r
-*/\r
-\r
-//---------------------------------------------------------------------------------------------------\r
-//---------------------------------------------------------------------------------------------------\r
-\r
-/*\r
-\r
-prototypes summary:\r
-\r
-ASIOError ASIOInit(ASIODriverInfo *info);\r
-ASIOError ASIOExit(void);\r
-ASIOError ASIOStart(void);\r
-ASIOError ASIOStop(void);\r
-ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels);\r
-ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);\r
-ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);\r
-ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate);\r
-ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate);\r
-ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate);\r
-ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);\r
-ASIOError ASIOSetClockSource(long reference);\r
-ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);\r
-ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);\r
-ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
-       long bufferSize, ASIOCallbacks *callbacks);\r
-ASIOError ASIODisposeBuffers(void);\r
-ASIOError ASIOControlPanel(void);\r
-void *ASIOFuture(long selector, void *params);\r
-ASIOError ASIOOutputReady(void);\r
-\r
-*/\r
-\r
-//---------------------------------------------------------------------------------------------------\r
-//---------------------------------------------------------------------------------------------------\r
-\r
-#ifndef __ASIO_H\r
-#define __ASIO_H\r
-\r
-// force 4 byte alignment\r
-#if defined(_MSC_VER) && !defined(__MWERKS__) \r
-#pragma pack(push,4)\r
-#elif PRAGMA_ALIGN_SUPPORTED\r
-#pragma options align = native\r
-#endif\r
-\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-// Type definitions\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-\r
-// number of samples data type is 64 bit integer\r
-#if NATIVE_INT64\r
-       typedef long long int ASIOSamples;\r
-#else\r
-       typedef struct ASIOSamples {\r
-               unsigned long hi;\r
-               unsigned long lo;\r
-       } ASIOSamples;\r
-#endif\r
-\r
-// Timestamp data type is 64 bit integer,\r
-// Time format is Nanoseconds.\r
-#if NATIVE_INT64\r
-       typedef long long int ASIOTimeStamp ;\r
-#else\r
-       typedef struct ASIOTimeStamp {\r
-               unsigned long hi;\r
-               unsigned long lo;\r
-       } ASIOTimeStamp;\r
-#endif\r
-\r
-// Samplerates are expressed in IEEE 754 64 bit double float,\r
-// native format as host computer\r
-#if IEEE754_64FLOAT\r
-       typedef double ASIOSampleRate;\r
-#else\r
-       typedef struct ASIOSampleRate {\r
-               char ieee[8];\r
-       } ASIOSampleRate;\r
-#endif\r
-\r
-// Boolean values are expressed as long\r
-typedef long ASIOBool;\r
-enum {\r
-       ASIOFalse = 0,\r
-       ASIOTrue = 1\r
-};\r
-\r
-// Sample Types are expressed as long\r
-typedef long ASIOSampleType;\r
-enum {\r
-       ASIOSTInt16MSB   = 0,\r
-       ASIOSTInt24MSB   = 1,           // used for 20 bits as well\r
-       ASIOSTInt32MSB   = 2,\r
-       ASIOSTFloat32MSB = 3,           // IEEE 754 32 bit float\r
-       ASIOSTFloat64MSB = 4,           // IEEE 754 64 bit double float\r
-\r
-       // these are used for 32 bit data buffer, with different alignment of the data inside\r
-       // 32 bit PCI bus systems can be more easily used with these\r
-       ASIOSTInt32MSB16 = 8,           // 32 bit data with 16 bit alignment\r
-       ASIOSTInt32MSB18 = 9,           // 32 bit data with 18 bit alignment\r
-       ASIOSTInt32MSB20 = 10,          // 32 bit data with 20 bit alignment\r
-       ASIOSTInt32MSB24 = 11,          // 32 bit data with 24 bit alignment\r
-       \r
-       ASIOSTInt16LSB   = 16,\r
-       ASIOSTInt24LSB   = 17,          // used for 20 bits as well\r
-       ASIOSTInt32LSB   = 18,\r
-       ASIOSTFloat32LSB = 19,          // IEEE 754 32 bit float, as found on Intel x86 architecture\r
-       ASIOSTFloat64LSB = 20,          // IEEE 754 64 bit double float, as found on Intel x86 architecture\r
-\r
-       // these are used for 32 bit data buffer, with different alignment of the data inside\r
-       // 32 bit PCI bus systems can more easily used with these\r
-       ASIOSTInt32LSB16 = 24,          // 32 bit data with 18 bit alignment\r
-       ASIOSTInt32LSB18 = 25,          // 32 bit data with 18 bit alignment\r
-       ASIOSTInt32LSB20 = 26,          // 32 bit data with 20 bit alignment\r
-       ASIOSTInt32LSB24 = 27,          // 32 bit data with 24 bit alignment\r
-\r
-       //      ASIO DSD format.\r
-       ASIOSTDSDInt8LSB1   = 32,               // DSD 1 bit data, 8 samples per byte. First sample in Least significant bit.\r
-       ASIOSTDSDInt8MSB1   = 33,               // DSD 1 bit data, 8 samples per byte. First sample in Most significant bit.\r
-       ASIOSTDSDInt8NER8       = 40,           // DSD 8 bit data, 1 sample per byte. No Endianness required.\r
-\r
-       ASIOSTLastEntry\r
-};\r
-\r
-/*-----------------------------------------------------------------------------\r
-// DSD operation and buffer layout\r
-// Definition by Steinberg/Sony Oxford.\r
-//\r
-// We have tried to treat DSD as PCM and so keep a consistant structure across\r
-// the ASIO interface.\r
-//\r
-// DSD's sample rate is normally referenced as a multiple of 44.1Khz, so\r
-// the standard sample rate is refered to as 64Fs (or 2.8224Mhz). We looked\r
-// at making a special case for DSD and adding a field to the ASIOFuture that\r
-// would allow the user to select the Over Sampleing Rate (OSR) as a seperate\r
-// entity but decided in the end just to treat it as a simple value of\r
-// 2.8224Mhz and use the standard interface to set it.\r
-//\r
-// The second problem was the "word" size, in PCM the word size is always a\r
-// greater than or equal to 8 bits (a byte). This makes life easy as we can\r
-// then pack the samples into the "natural" size for the machine.\r
-// In DSD the "word" size is 1 bit. This is not a major problem and can easily\r
-// be dealt with if we ensure that we always deal with a multiple of 8 samples.\r
-//\r
-// DSD brings with it another twist to the Endianness religion. How are the\r
-// samples packed into the byte. It would be nice to just say the most significant\r
-// bit is always the first sample, however there would then be a performance hit\r
-// on little endian machines. Looking at how some of the processing goes...\r
-// Little endian machines like the first sample to be in the Least Significant Bit,\r
-//   this is because when you write it to memory the data is in the correct format\r
-//   to be shifted in and out of the words.\r
-// Big endian machine prefer the first sample to be in the Most Significant Bit,\r
-//   again for the same reasion.\r
-//\r
-// And just when things were looking really muddy there is a proposed extension to\r
-// DSD that uses 8 bit word sizes. It does not care what endianness you use.\r
-//\r
-// Switching the driver between DSD and PCM mode\r
-// ASIOFuture allows for extending the ASIO API quite transparently.\r
-// See kAsioSetIoFormat, kAsioGetIoFormat, kAsioCanDoIoFormat\r
-//\r
-//-----------------------------------------------------------------------------*/\r
-\r
-\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-// Error codes\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-\r
-typedef long ASIOError;\r
-enum {\r
-       ASE_OK = 0,             // This value will be returned whenever the call succeeded\r
-       ASE_SUCCESS = 0x3f4847a0,       // unique success return value for ASIOFuture calls\r
-       ASE_NotPresent = -1000, // hardware input or output is not present or available\r
-       ASE_HWMalfunction,      // hardware is malfunctioning (can be returned by any ASIO function)\r
-       ASE_InvalidParameter,   // input parameter invalid\r
-       ASE_InvalidMode,        // hardware is in a bad mode or used in a bad mode\r
-       ASE_SPNotAdvancing,     // hardware is not running when sample position is inquired\r
-       ASE_NoClock,            // sample clock or rate cannot be determined or is not present\r
-       ASE_NoMemory            // not enough memory for completing the request\r
-};\r
-\r
-//---------------------------------------------------------------------------------------------------\r
-//---------------------------------------------------------------------------------------------------\r
-\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-// Time Info support\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-\r
-typedef struct ASIOTimeCode\r
-{       \r
-       double          speed;                  // speed relation (fraction of nominal speed)\r
-                                               // optional; set to 0. or 1. if not supported\r
-       ASIOSamples     timeCodeSamples;        // time in samples\r
-       unsigned long   flags;                  // some information flags (see below)\r
-       char future[64];\r
-} ASIOTimeCode;\r
-\r
-typedef enum ASIOTimeCodeFlags\r
-{\r
-       kTcValid                = 1,\r
-       kTcRunning              = 1 << 1,\r
-       kTcReverse              = 1 << 2,\r
-       kTcOnspeed              = 1 << 3,\r
-       kTcStill                = 1 << 4,\r
-       \r
-       kTcSpeedValid           = 1 << 8\r
-}  ASIOTimeCodeFlags;\r
-\r
-typedef struct AsioTimeInfo\r
-{\r
-       double          speed;                  // absolute speed (1. = nominal)\r
-       ASIOTimeStamp   systemTime;             // system time related to samplePosition, in nanoseconds\r
-                                               // on mac, must be derived from Microseconds() (not UpTime()!)\r
-                                               // on windows, must be derived from timeGetTime()\r
-       ASIOSamples     samplePosition;\r
-       ASIOSampleRate  sampleRate;             // current rate\r
-       unsigned long flags;                    // (see below)\r
-       char reserved[12];\r
-} AsioTimeInfo;\r
-\r
-typedef enum AsioTimeInfoFlags\r
-{\r
-       kSystemTimeValid        = 1,            // must always be valid\r
-       kSamplePositionValid    = 1 << 1,       // must always be valid\r
-       kSampleRateValid        = 1 << 2,\r
-       kSpeedValid             = 1 << 3,\r
-       \r
-       kSampleRateChanged      = 1 << 4,\r
-       kClockSourceChanged     = 1 << 5\r
-} AsioTimeInfoFlags;\r
-\r
-typedef struct ASIOTime                          // both input/output\r
-{\r
-       long reserved[4];                       // must be 0\r
-       struct AsioTimeInfo     timeInfo;       // required\r
-       struct ASIOTimeCode     timeCode;       // optional, evaluated if (timeCode.flags & kTcValid)\r
-} ASIOTime;\r
-\r
-/*\r
-\r
-using time info:\r
-it is recommended to use the new method with time info even if the asio\r
-device does not support timecode; continuous calls to ASIOGetSamplePosition\r
-and ASIOGetSampleRate are avoided, and there is a more defined relationship\r
-between callback time and the time info.\r
-\r
-see the example below.\r
-to initiate time info mode, after you have received the callbacks pointer in\r
-ASIOCreateBuffers, you will call the asioMessage callback with kAsioSupportsTimeInfo\r
-as the argument. if this returns 1, host has accepted time info mode.\r
-now host expects the new callback bufferSwitchTimeInfo to be used instead\r
-of the old bufferSwitch method. the ASIOTime structure is assumed to be valid\r
-and accessible until the callback returns.\r
-\r
-using time code:\r
-if the device supports reading time code, it will call host's asioMessage callback\r
-with kAsioSupportsTimeCode as the selector. it may then fill the according\r
-fields and set the kTcValid flag.\r
-host will call the future method with the kAsioEnableTimeCodeRead selector when\r
-it wants to enable or disable tc reading by the device. you should also support\r
-the kAsioCanTimeInfo and kAsioCanTimeCode selectors in ASIOFuture (see example).\r
-\r
-note:\r
-the AsioTimeInfo/ASIOTimeCode pair is supposed to work in both directions.\r
-as a matter of convention, the relationship between the sample\r
-position counter and the time code at buffer switch time is\r
-(ignoring offset between tc and sample pos when tc is running):\r
-\r
-on input:      sample 0 -> input  buffer sample 0 -> time code 0\r
-on output:     sample 0 -> output buffer sample 0 -> time code 0\r
-\r
-this means that for 'real' calculations, one has to take into account\r
-the according latencies.\r
-\r
-example:\r
-\r
-ASIOTime asioTime;\r
-\r
-in createBuffers()\r
-{\r
-       memset(&asioTime, 0, sizeof(ASIOTime));\r
-       AsioTimeInfo* ti = &asioTime.timeInfo;\r
-       ti->sampleRate = theSampleRate;\r
-       ASIOTimeCode* tc = &asioTime.timeCode;\r
-       tc->speed = 1.;\r
-       timeInfoMode = false;\r
-       canTimeCode = false;\r
-       if(callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0) == 1)\r
-       {\r
-               timeInfoMode = true;\r
-#if kCanTimeCode\r
-               if(callbacks->asioMessage(kAsioSupportsTimeCode, 0, 0, 0) == 1)\r
-                       canTimeCode = true;\r
-#endif\r
-       }\r
-}\r
-\r
-void switchBuffers(long doubleBufferIndex, bool processNow)\r
-{\r
-       if(timeInfoMode)\r
-       {\r
-               AsioTimeInfo* ti = &asioTime.timeInfo;\r
-               ti->flags =     kSystemTimeValid | kSamplePositionValid | kSampleRateValid;\r
-               ti->systemTime = theNanoSeconds;\r
-               ti->samplePosition = theSamplePosition;\r
-               if(ti->sampleRate != theSampleRate)\r
-                       ti->flags |= kSampleRateChanged;\r
-               ti->sampleRate = theSampleRate;\r
-\r
-#if kCanTimeCode\r
-               if(canTimeCode && timeCodeEnabled)\r
-               {\r
-                       ASIOTimeCode* tc = &asioTime.timeCode;\r
-                       tc->timeCodeSamples = tcSamples;                                                // tc in samples\r
-                       tc->flags = kTcValid | kTcRunning | kTcOnspeed;                 // if so...\r
-               }\r
-               ASIOTime* bb = callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse);\r
-#else\r
-               callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse);\r
-#endif\r
-       }\r
-       else\r
-               callbacks->bufferSwitch(doubleBufferIndex, ASIOFalse);\r
-}\r
-\r
-ASIOError ASIOFuture(long selector, void *params)\r
-{\r
-       switch(selector)\r
-       {\r
-               case kAsioEnableTimeCodeRead:\r
-                       timeCodeEnabled = true;\r
-                       return ASE_SUCCESS;\r
-               case kAsioDisableTimeCodeRead:\r
-                       timeCodeEnabled = false;\r
-                       return ASE_SUCCESS;\r
-               case kAsioCanTimeInfo:\r
-                       return ASE_SUCCESS;\r
-               #if kCanTimeCode\r
-               case kAsioCanTimeCode:\r
-                       return ASE_SUCCESS;\r
-               #endif\r
-       }\r
-       return ASE_NotPresent;\r
-};\r
-\r
-*/\r
-\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-// application's audio stream handler callbacks\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-\r
-typedef struct ASIOCallbacks\r
-{\r
-       void (*bufferSwitch) (long doubleBufferIndex, ASIOBool directProcess);\r
-               // bufferSwitch indicates that both input and output are to be processed.\r
-               // the current buffer half index (0 for A, 1 for B) determines\r
-               // - the output buffer that the host should start to fill. the other buffer\r
-               //   will be passed to output hardware regardless of whether it got filled\r
-               //   in time or not.\r
-               // - the input buffer that is now filled with incoming data. Note that\r
-               //   because of the synchronicity of i/o, the input always has at\r
-               //   least one buffer latency in relation to the output.\r
-               // directProcess suggests to the host whether it should immedeately\r
-               // start processing (directProcess == ASIOTrue), or whether its process\r
-               // should be deferred because the call comes from a very low level\r
-               // (for instance, a high level priority interrupt), and direct processing\r
-               // would cause timing instabilities for the rest of the system. If in doubt,\r
-               // directProcess should be set to ASIOFalse.\r
-               // Note: bufferSwitch may be called at interrupt time for highest efficiency.\r
-\r
-       void (*sampleRateDidChange) (ASIOSampleRate sRate);\r
-               // gets called when the AudioStreamIO detects a sample rate change\r
-               // If sample rate is unknown, 0 is passed (for instance, clock loss\r
-               // when externally synchronized).\r
-\r
-       long (*asioMessage) (long selector, long value, void* message, double* opt);\r
-               // generic callback for various purposes, see selectors below.\r
-               // note this is only present if the asio version is 2 or higher\r
-\r
-       ASIOTime* (*bufferSwitchTimeInfo) (ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess);\r
-               // new callback with time info. makes ASIOGetSamplePosition() and various\r
-               // calls to ASIOGetSampleRate obsolete,\r
-               // and allows for timecode sync etc. to be preferred; will be used if\r
-               // the driver calls asioMessage with selector kAsioSupportsTimeInfo.\r
-} ASIOCallbacks;\r
-\r
-// asioMessage selectors\r
-enum\r
-{\r
-       kAsioSelectorSupported = 1,     // selector in <value>, returns 1L if supported,\r
-                                                               // 0 otherwise\r
-    kAsioEngineVersion,                        // returns engine (host) asio implementation version,\r
-                                                               // 2 or higher\r
-       kAsioResetRequest,                      // request driver reset. if accepted, this\r
-                                                               // will close the driver (ASIO_Exit() ) and\r
-                                                               // re-open it again (ASIO_Init() etc). some\r
-                                                               // drivers need to reconfigure for instance\r
-                                                               // when the sample rate changes, or some basic\r
-                                                               // changes have been made in ASIO_ControlPanel().\r
-                                                               // returns 1L; note the request is merely passed\r
-                                                               // to the application, there is no way to determine\r
-                                                               // if it gets accepted at this time (but it usually\r
-                                                               // will be).\r
-       kAsioBufferSizeChange,          // not yet supported, will currently always return 0L.\r
-                                                               // for now, use kAsioResetRequest instead.\r
-                                                               // once implemented, the new buffer size is expected\r
-                                                               // in <value>, and on success returns 1L\r
-       kAsioResyncRequest,                     // the driver went out of sync, such that\r
-                                                               // the timestamp is no longer valid. this\r
-                                                               // is a request to re-start the engine and\r
-                                                               // slave devices (sequencer). returns 1 for ok,\r
-                                                               // 0 if not supported.\r
-       kAsioLatenciesChanged,          // the drivers latencies have changed. The engine\r
-                                                               // will refetch the latencies.\r
-       kAsioSupportsTimeInfo,          // if host returns true here, it will expect the\r
-                                                               // callback bufferSwitchTimeInfo to be called instead\r
-                                                               // of bufferSwitch\r
-       kAsioSupportsTimeCode,          // \r
-       kAsioMMCCommand,                        // unused - value: number of commands, message points to mmc commands\r
-       kAsioSupportsInputMonitor,      // kAsioSupportsXXX return 1 if host supports this\r
-       kAsioSupportsInputGain,     // unused and undefined\r
-       kAsioSupportsInputMeter,    // unused and undefined\r
-       kAsioSupportsOutputGain,    // unused and undefined\r
-       kAsioSupportsOutputMeter,   // unused and undefined\r
-       kAsioOverload,              // driver detected an overload\r
-\r
-       kAsioNumMessageSelectors\r
-};\r
-\r
-//---------------------------------------------------------------------------------------------------\r
-//---------------------------------------------------------------------------------------------------\r
-\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-// (De-)Construction\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-\r
-typedef struct ASIODriverInfo\r
-{\r
-       long asioVersion;               // currently, 2\r
-       long driverVersion;             // driver specific\r
-       char name[32];\r
-       char errorMessage[124];\r
-       void *sysRef;                   // on input: system reference\r
-                                                       // (Windows: application main window handle, Mac & SGI: 0)\r
-} ASIODriverInfo;\r
-\r
-ASIOError ASIOInit(ASIODriverInfo *info);\r
-/* Purpose:\r
-         Initialize the AudioStreamIO.\r
-       Parameter:\r
-         info: pointer to an ASIODriver structure:\r
-           - asioVersion:\r
-                       - on input, the host version. *** Note *** this is 0 for earlier asio\r
-                       implementations, and the asioMessage callback is implemeted\r
-                       only if asioVersion is 2 or greater. sorry but due to a design fault\r
-                       the driver doesn't have access to the host version in ASIOInit :-(\r
-                       added selector for host (engine) version in the asioMessage callback\r
-                       so we're ok from now on.\r
-                       - on return, asio implementation version.\r
-                         older versions are 1\r
-                         if you support this version (namely, ASIO_outputReady() )\r
-                         this should be 2 or higher. also see the note in\r
-                         ASIO_getTimeStamp() !\r
-           - version: on return, the driver version (format is driver specific)\r
-           - name: on return, a null-terminated string containing the driver's name\r
-               - error message: on return, should contain a user message describing\r
-                 the type of error that occured during ASIOInit(), if any.\r
-               - sysRef: platform specific\r
-       Returns:\r
-         If neither input nor output is present ASE_NotPresent\r
-         will be returned.\r
-         ASE_NoMemory, ASE_HWMalfunction are other possible error conditions\r
-*/\r
-\r
-ASIOError ASIOExit(void);\r
-/* Purpose:\r
-         Terminates the AudioStreamIO.\r
-       Parameter:\r
-         None.\r
-       Returns:\r
-         If neither input nor output is present ASE_NotPresent\r
-         will be returned.\r
-       Notes: this implies ASIOStop() and ASIODisposeBuffers(),\r
-         meaning that no host callbacks must be accessed after ASIOExit().\r
-*/\r
-\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-// Start/Stop\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-\r
-ASIOError ASIOStart(void);\r
-/* Purpose:\r
-         Start input and output processing synchronously.\r
-         This will\r
-         - reset the sample counter to zero\r
-         - start the hardware (both input and output)\r
-           The first call to the hosts' bufferSwitch(index == 0) then tells\r
-           the host to read from input buffer A (index 0), and start\r
-           processing to output buffer A while output buffer B (which\r
-           has been filled by the host prior to calling ASIOStart())\r
-           is possibly sounding (see also ASIOGetLatencies()) \r
-       Parameter:\r
-         None.\r
-       Returns:\r
-         If neither input nor output is present, ASE_NotPresent\r
-         will be returned.\r
-         If the hardware fails to start, ASE_HWMalfunction will be returned.\r
-       Notes:\r
-         There is no restriction on the time that ASIOStart() takes\r
-         to perform (that is, it is not considered a realtime trigger).\r
-*/\r
-\r
-ASIOError ASIOStop(void);\r
-/* Purpose:\r
-         Stops input and output processing altogether.\r
-       Parameter:\r
-         None.\r
-       Returns:\r
-         If neither input nor output is present ASE_NotPresent\r
-         will be returned.\r
-       Notes:\r
-         On return from ASIOStop(), the driver must in no\r
-         case call the hosts' bufferSwitch() routine.\r
-*/\r
-\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-// Inquiry methods and sample rate\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-\r
-ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels);\r
-/* Purpose:\r
-         Returns number of individual input/output channels.\r
-       Parameter:\r
-         numInputChannels will hold the number of available input channels\r
-         numOutputChannels will hold the number of available output channels\r
-       Returns:\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-         If only inputs, or only outputs are available, the according\r
-         other parameter will be zero, and ASE_OK is returned.\r
-*/\r
-\r
-ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);\r
-/* Purpose:\r
-         Returns the input and output latencies. This includes\r
-         device specific delays, like FIFOs etc.\r
-       Parameter:\r
-         inputLatency will hold the 'age' of the first sample frame\r
-         in the input buffer when the hosts reads it in bufferSwitch()\r
-         (this is theoretical, meaning it does not include the overhead\r
-         and delay between the actual physical switch, and the time\r
-         when bufferSitch() enters).\r
-         This will usually be the size of one block in sample frames, plus\r
-         device specific latencies.\r
-\r
-         outputLatency will specify the time between the buffer switch,\r
-         and the time when the next play buffer will start to sound.\r
-         The next play buffer is defined as the one the host starts\r
-         processing after (or at) bufferSwitch(), indicated by the\r
-         index parameter (0 for buffer A, 1 for buffer B).\r
-         It will usually be either one block, if the host writes directly\r
-         to a dma buffer, or two or more blocks if the buffer is 'latched' by\r
-         the driver. As an example, on ASIOStart(), the host will have filled\r
-         the play buffer at index 1 already; when it gets the callback (with\r
-         the parameter index == 0), this tells it to read from the input\r
-         buffer 0, and start to fill the play buffer 0 (assuming that now\r
-         play buffer 1 is already sounding). In this case, the output\r
-         latency is one block. If the driver decides to copy buffer 1\r
-         at that time, and pass it to the hardware at the next slot (which\r
-         is most commonly done, but should be avoided), the output latency\r
-         becomes two blocks instead, resulting in a total i/o latency of at least\r
-         3 blocks. As memory access is the main bottleneck in native dsp processing,\r
-         and to acheive less latency, it is highly recommended to try to avoid\r
-         copying (this is also why the driver is the owner of the buffers). To\r
-         summarize, the minimum i/o latency can be acheived if the input buffer\r
-         is processed by the host into the output buffer which will physically\r
-         start to sound on the next time slice. Also note that the host expects\r
-         the bufferSwitch() callback to be accessed for each time slice in order\r
-         to retain sync, possibly recursively; if it fails to process a block in\r
-         time, it will suspend its operation for some time in order to recover.\r
-       Returns:\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-*/\r
-\r
-ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);\r
-/* Purpose:\r
-         Returns min, max, and preferred buffer sizes for input/output\r
-       Parameter:\r
-         minSize will hold the minimum buffer size\r
-         maxSize will hold the maxium possible buffer size\r
-         preferredSize will hold the preferred buffer size (a size which\r
-         best fits performance and hardware requirements)\r
-         granularity will hold the granularity at which buffer sizes\r
-         may differ. Usually, the buffer size will be a power of 2;\r
-         in this case, granularity will hold -1 on return, signalling\r
-         possible buffer sizes starting from minSize, increased in\r
-         powers of 2 up to maxSize.\r
-       Returns:\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-       Notes:\r
-         When minimum and maximum buffer size are equal,\r
-         the preferred buffer size has to be the same value as well; granularity\r
-         should be 0 in this case.\r
-*/\r
-\r
-ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate);\r
-/* Purpose:\r
-         Inquires the hardware for the available sample rates.\r
-       Parameter:\r
-         sampleRate is the rate in question.\r
-       Returns:\r
-         If the inquired sample rate is not supported, ASE_NoClock will be returned.\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-*/\r
-ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate);\r
-/* Purpose:\r
-         Get the current sample Rate.\r
-       Parameter:\r
-         currentRate will hold the current sample rate on return.\r
-       Returns:\r
-         If sample rate is unknown, sampleRate will be 0 and ASE_NoClock will be returned.\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-       Notes:\r
-*/\r
-\r
-ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate);\r
-/* Purpose:\r
-         Set the hardware to the requested sample Rate. If sampleRate == 0,\r
-         enable external sync.\r
-       Parameter:\r
-         sampleRate: on input, the requested rate\r
-       Returns:\r
-         If sampleRate is unknown ASE_NoClock will be returned.\r
-         If the current clock is external, and sampleRate is != 0,\r
-         ASE_InvalidMode will be returned\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-       Notes:\r
-*/\r
-\r
-typedef struct ASIOClockSource\r
-{\r
-       long index;                                     // as used for ASIOSetClockSource()\r
-       long associatedChannel;         // for instance, S/PDIF or AES/EBU\r
-       long associatedGroup;           // see channel groups (ASIOGetChannelInfo())\r
-       ASIOBool isCurrentSource;       // ASIOTrue if this is the current clock source\r
-       char name[32];                          // for user selection\r
-} ASIOClockSource;\r
-\r
-ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);\r
-/* Purpose:\r
-         Get the available external audio clock sources\r
-       Parameter:\r
-         clocks points to an array of ASIOClockSource structures:\r
-               - index: this is used to identify the clock source\r
-                 when ASIOSetClockSource() is accessed, should be\r
-                 an index counting from zero\r
-               - associatedInputChannel: the first channel of an associated\r
-                 input group, if any.\r
-               - associatedGroup: the group index of that channel.\r
-                 groups of channels are defined to seperate for\r
-                 instance analog, S/PDIF, AES/EBU, ADAT connectors etc,\r
-                 when present simultaniously. Note that associated channel\r
-                 is enumerated according to numInputs/numOutputs, means it\r
-                 is independant from a group (see also ASIOGetChannelInfo())\r
-                 inputs are associated to a clock if the physical connection\r
-                 transfers both data and clock (like S/PDIF, AES/EBU, or\r
-                 ADAT inputs). if there is no input channel associated with\r
-                 the clock source (like Word Clock, or internal oscillator), both\r
-                 associatedChannel and associatedGroup should be set to -1.\r
-               - isCurrentSource: on exit, ASIOTrue if this is the current clock\r
-                 source, ASIOFalse else\r
-               - name: a null-terminated string for user selection of the available sources.\r
-         numSources:\r
-             on input: the number of allocated array members\r
-             on output: the number of available clock sources, at least\r
-             1 (internal clock generator).\r
-       Returns:\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-       Notes:\r
-*/\r
-\r
-ASIOError ASIOSetClockSource(long index);\r
-/* Purpose:\r
-         Set the audio clock source\r
-       Parameter:\r
-         index as obtained from an inquiry to ASIOGetClockSources()\r
-       Returns:\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-         If the clock can not be selected because an input channel which\r
-         carries the current clock source is active, ASE_InvalidMode\r
-         *may* be returned (this depends on the properties of the driver\r
-         and/or hardware).\r
-       Notes:\r
-         Should *not* return ASE_NoClock if there is no clock signal present\r
-         at the selected source; this will be inquired via ASIOGetSampleRate().\r
-         It should call the host callback procedure sampleRateHasChanged(),\r
-         if the switch causes a sample rate change, or if no external clock\r
-         is present at the selected source.\r
-*/\r
-\r
-ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);\r
-/* Purpose:\r
-         Inquires the sample position/time stamp pair.\r
-       Parameter:\r
-         sPos will hold the sample position on return. The sample\r
-         position is reset to zero when ASIOStart() gets called.\r
-         tStamp will hold the system time when the sample position\r
-         was latched.\r
-       Returns:\r
-         If no input/output is present, ASE_NotPresent will be returned.\r
-         If there is no clock, ASE_SPNotAdvancing will be returned.\r
-       Notes:\r
-\r
-         in order to be able to synchronise properly,\r
-         the sample position / time stamp pair must refer to the current block,\r
-         that is, the engine will call ASIOGetSamplePosition() in its bufferSwitch()\r
-         callback and expect the time for the current block. thus, when requested\r
-         in the very first bufferSwitch after ASIO_Start(), the sample position\r
-         should be zero, and the time stamp should refer to the very time where\r
-         the stream was started. it also means that the sample position must be\r
-         block aligned. the driver must ensure proper interpolation if the system\r
-         time can not be determined for the block position. the driver is responsible\r
-         for precise time stamps as it usually has most direct access to lower\r
-         level resources. proper behaviour of ASIO_GetSamplePosition() and ASIO_GetLatencies()\r
-         are essential for precise media synchronization!\r
-*/\r
-\r
-typedef struct ASIOChannelInfo\r
-{\r
-       long channel;                   // on input, channel index\r
-       ASIOBool isInput;               // on input\r
-       ASIOBool isActive;              // on exit\r
-       long channelGroup;              // dto\r
-       ASIOSampleType type;    // dto\r
-       char name[32];                  // dto\r
-} ASIOChannelInfo;\r
-\r
-ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);\r
-/* Purpose:\r
-         retreive information about the nature of a channel\r
-       Parameter:\r
-         info: pointer to a ASIOChannelInfo structure with\r
-               - channel: on input, the channel index of the channel in question.\r
-               - isInput: on input, ASIOTrue if info for an input channel is\r
-                 requested, else output\r
-               - channelGroup: on return, the channel group that the channel\r
-                 belongs to. For drivers which support different types of\r
-                 channels, like analog, S/PDIF, AES/EBU, ADAT etc interfaces,\r
-                 there should be a reasonable grouping of these types. Groups\r
-                 are always independant form a channel index, that is, a channel\r
-                 index always counts from 0 to numInputs/numOutputs regardless\r
-                 of the group it may belong to.\r
-                 There will always be at least one group (group 0). Please\r
-                 also note that by default, the host may decide to activate\r
-                 channels 0 and 1; thus, these should belong to the most\r
-                 useful type (analog i/o, if present).\r
-               - type: on return, contains the sample type of the channel\r
-               - isActive: on return, ASIOTrue if channel is active as it was\r
-                 installed by ASIOCreateBuffers(), ASIOFalse else\r
-               - name:  describing the type of channel in question. Used to allow\r
-                 for user selection, and enabling of specific channels. examples:\r
-             "Analog In", "SPDIF Out" etc\r
-       Returns:\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-       Notes:\r
-         If possible, the string should be organised such that the first\r
-         characters are most significantly describing the nature of the\r
-         port, to allow for identification even if the view showing the\r
-         port name is too small to display more than 8 characters, for\r
-         instance.\r
-*/\r
-\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-// Buffer preparation\r
-//- - - - - - - - - - - - - - - - - - - - - - - - -\r
-\r
-typedef struct ASIOBufferInfo\r
-{\r
-       ASIOBool isInput;                       // on input:  ASIOTrue: input, else output\r
-       long channelNum;                        // on input:  channel index\r
-       void *buffers[2];                       // on output: double buffer addresses\r
-} ASIOBufferInfo;\r
-\r
-ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
-       long bufferSize, ASIOCallbacks *callbacks);\r
-\r
-/* Purpose:\r
-         Allocates input/output buffers for all input and output channels to be activated.\r
-       Parameter:\r
-         bufferInfos is a pointer to an array of ASIOBufferInfo structures:\r
-           - isInput: on input, ASIOTrue if the buffer is to be allocated\r
-             for an input, output buffer else\r
-           - channelNum: on input, the index of the channel in question\r
-             (counting from 0)\r
-           - buffers: on exit, 2 pointers to the halves of the channels' double-buffer.\r
-             the size of the buffer(s) of course depend on both the ASIOSampleType\r
-             as obtained from ASIOGetChannelInfo(), and bufferSize\r
-         numChannels is the sum of all input and output channels to be created;\r
-         thus bufferInfos is a pointer to an array of numChannels ASIOBufferInfo\r
-         structures.\r
-         bufferSize selects one of the possible buffer sizes as obtained from\r
-         ASIOGetBufferSizes().\r
-         callbacks is a pointer to an ASIOCallbacks structure.\r
-       Returns:\r
-         If not enough memory is available ASE_NoMemory will be returned.\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-         If bufferSize is not supported, or one or more of the bufferInfos elements\r
-         contain invalid settings, ASE_InvalidMode will be returned.\r
-       Notes:\r
-         If individual channel selection is not possible but requested,\r
-         the driver has to handle this. namely, bufferSwitch() will only\r
-         have filled buffers of enabled outputs. If possible, processing\r
-         and buss activities overhead should be avoided for channels which\r
-         were not enabled here.\r
-*/\r
-\r
-ASIOError ASIODisposeBuffers(void);\r
-/* Purpose:\r
-         Releases all buffers for the device.\r
-       Parameter:\r
-         None.\r
-       Returns:\r
-         If no buffer were ever prepared, ASE_InvalidMode will be returned.\r
-         If no input/output is present ASE_NotPresent will be returned.\r
-       Notes:\r
-         This implies ASIOStop().\r
-*/\r
-\r
-ASIOError ASIOControlPanel(void);\r
-/* Purpose:\r
-         request the driver to start a control panel component\r
-         for device specific user settings. This will not be\r
-         accessed on some platforms (where the component is accessed\r
-         instead).\r
-       Parameter:\r
-         None.\r
-       Returns:\r
-         If no panel is available ASE_NotPresent will be returned.\r
-         Actually, the return code is ignored.\r
-       Notes:\r
-         if the user applied settings which require a re-configuration\r
-         of parts or all of the enigine and/or driver (such as a change of\r
-         the block size), the asioMessage callback can be used (see\r
-         ASIO_Callbacks).\r
-*/\r
-\r
-ASIOError ASIOFuture(long selector, void *params);\r
-/* Purpose:\r
-         various\r
-       Parameter:\r
-         selector: operation Code as to be defined. zero is reserved for\r
-         testing purposes.\r
-         params: depends on the selector; usually pointer to a structure\r
-         for passing and retreiving any type and amount of parameters.\r
-       Returns:\r
-         the return value is also selector dependant. if the selector\r
-         is unknown, ASE_InvalidParameter should be returned to prevent\r
-         further calls with this selector. on success, ASE_SUCCESS\r
-         must be returned (note: ASE_OK is *not* sufficient!)\r
-       Notes:\r
-         see selectors defined below.    \r
-*/\r
-\r
-enum\r
-{\r
-       kAsioEnableTimeCodeRead = 1,    // no arguments\r
-       kAsioDisableTimeCodeRead,               // no arguments\r
-       kAsioSetInputMonitor,                   // ASIOInputMonitor* in params\r
-       kAsioTransport,                                 // ASIOTransportParameters* in params\r
-       kAsioSetInputGain,                              // ASIOChannelControls* in params, apply gain\r
-       kAsioGetInputMeter,                             // ASIOChannelControls* in params, fill meter\r
-       kAsioSetOutputGain,                             // ASIOChannelControls* in params, apply gain\r
-       kAsioGetOutputMeter,                    // ASIOChannelControls* in params, fill meter\r
-       kAsioCanInputMonitor,                   // no arguments for kAsioCanXXX selectors\r
-       kAsioCanTimeInfo,\r
-       kAsioCanTimeCode,\r
-       kAsioCanTransport,\r
-       kAsioCanInputGain,\r
-       kAsioCanInputMeter,\r
-       kAsioCanOutputGain,\r
-       kAsioCanOutputMeter,\r
-\r
-       //      DSD support\r
-       //      The following extensions are required to allow switching\r
-       //      and control of the DSD subsystem.\r
-       kAsioSetIoFormat                        = 0x23111961,           /* ASIOIoFormat * in params.                    */\r
-       kAsioGetIoFormat                        = 0x23111983,           /* ASIOIoFormat * in params.                    */\r
-       kAsioCanDoIoFormat                      = 0x23112004,           /* ASIOIoFormat * in params.                    */\r
-};\r
-\r
-typedef struct ASIOInputMonitor\r
-{\r
-       long input;             // this input was set to monitor (or off), -1: all\r
-       long output;    // suggested output for monitoring the input (if so)\r
-       long gain;              // suggested gain, ranging 0 - 0x7fffffffL (-inf to +12 dB)\r
-       ASIOBool state; // ASIOTrue => on, ASIOFalse => off\r
-       long pan;               // suggested pan, 0 => all left, 0x7fffffff => right\r
-} ASIOInputMonitor;\r
-\r
-typedef struct ASIOChannelControls\r
-{\r
-       long channel;                   // on input, channel index\r
-       ASIOBool isInput;               // on input\r
-       long gain;                              // on input,  ranges 0 thru 0x7fffffff\r
-       long meter;                             // on return, ranges 0 thru 0x7fffffff\r
-       char future[32];\r
-} ASIOChannelControls;\r
-\r
-typedef struct ASIOTransportParameters\r
-{\r
-       long command;           // see enum below\r
-       ASIOSamples samplePosition;\r
-       long track;\r
-       long trackSwitches[16];         // 512 tracks on/off\r
-       char future[64];\r
-} ASIOTransportParameters;\r
-\r
-enum\r
-{\r
-       kTransStart = 1,\r
-       kTransStop,\r
-       kTransLocate,           // to samplePosition\r
-       kTransPunchIn,\r
-       kTransPunchOut,\r
-       kTransArmOn,            // track\r
-       kTransArmOff,           // track\r
-       kTransMonitorOn,        // track\r
-       kTransMonitorOff,       // track\r
-       kTransArm,                      // trackSwitches\r
-       kTransMonitor           // trackSwitches\r
-};\r
-\r
-/*\r
-// DSD support\r
-//     Some notes on how to use ASIOIoFormatType.\r
-//\r
-//     The caller will fill the format with the request types.\r
-//     If the board can do the request then it will leave the\r
-//     values unchanged. If the board does not support the\r
-//     request then it will change that entry to Invalid (-1)\r
-//\r
-//     So to request DSD then\r
-//\r
-//     ASIOIoFormat NeedThis={kASIODSDFormat};\r
-//\r
-//     if(ASE_SUCCESS != ASIOFuture(kAsioSetIoFormat,&NeedThis) ){\r
-//             // If the board did not accept one of the parameters then the\r
-//             // whole call will fail and the failing parameter will\r
-//             // have had its value changes to -1.\r
-//     }\r
-//\r
-// Note: Switching between the formats need to be done before the "prepared"\r
-// state (see ASIO 2 documentation) is entered.\r
-*/\r
-typedef long int ASIOIoFormatType;\r
-enum ASIOIoFormatType_e\r
-{\r
-       kASIOFormatInvalid = -1,\r
-       kASIOPCMFormat = 0,\r
-       kASIODSDFormat = 1,\r
-};\r
-\r
-typedef struct ASIOIoFormat_s\r
-{\r
-       ASIOIoFormatType        FormatType;\r
-       char                            future[512-sizeof(ASIOIoFormatType)];\r
-} ASIOIoFormat;\r
-\r
-\r
-ASIOError ASIOOutputReady(void);\r
-/* Purpose:\r
-         this tells the driver that the host has completed processing\r
-         the output buffers. if the data format required by the hardware\r
-         differs from the supported asio formats, but the hardware\r
-         buffers are DMA buffers, the driver will have to convert\r
-         the audio stream data; as the bufferSwitch callback is\r
-         usually issued at dma block switch time, the driver will\r
-         have to convert the *previous* host buffer, which increases\r
-         the output latency by one block.\r
-         when the host finds out that ASIOOutputReady() returns\r
-         true, it will issue this call whenever it completed\r
-         output processing. then the driver can convert the\r
-         host data directly to the dma buffer to be played next,\r
-         reducing output latency by one block.\r
-         another way to look at it is, that the buffer switch is called\r
-         in order to pass the *input* stream to the host, so that it can\r
-         process the input into the output, and the output stream is passed\r
-         to the driver when the host has completed its process.\r
-       Parameter:\r
-               None\r
-       Returns:\r
-         only if the above mentioned scenario is given, and a reduction\r
-         of output latency can be acheived by this mechanism, should\r
-         ASE_OK be returned. otherwise (and usually), ASE_NotPresent\r
-         should be returned in order to prevent further calls to this\r
-         function. note that the host may want to determine if it is\r
-         to use this when the system is not yet fully initialized, so\r
-         ASE_OK should always be returned if the mechanism makes sense.          \r
-       Notes:\r
-         please remeber to adjust ASIOGetLatencies() according to\r
-         whether ASIOOutputReady() was ever called or not, if your\r
-         driver supports this scenario.\r
-         also note that the engine may fail to call ASIO_OutputReady()\r
-         in time in overload cases. as already mentioned, bufferSwitch\r
-      should be called for every block regardless of whether a block\r
-      could be processed in time.\r
-*/\r
-\r
-// restore old alignment\r
-#if defined(_MSC_VER) && !defined(__MWERKS__) \r
-#pragma pack(pop)\r
-#elif PRAGMA_ALIGN_SUPPORTED\r
-#pragma options align = reset\r
-#endif\r
-\r
-#endif\r
-\r
diff --git a/asio/asiodrivers.cpp b/asio/asiodrivers.cpp
deleted file mode 100644 (file)
index 5f56454..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-#include <string.h>\r
-#include "asiodrivers.h"\r
-\r
-AsioDrivers* asioDrivers = 0;\r
-\r
-bool loadAsioDriver(char *name);\r
-\r
-bool loadAsioDriver(char *name)\r
-{\r
-       if(!asioDrivers)\r
-               asioDrivers = new AsioDrivers();\r
-       if(asioDrivers)\r
-               return asioDrivers->loadDriver(name);\r
-       return false;\r
-}\r
-\r
-//------------------------------------------------------------------------------------\r
-\r
-#if MAC\r
-\r
-bool resolveASIO(unsigned long aconnID);\r
-\r
-AsioDrivers::AsioDrivers() : CodeFragments("ASIO Drivers", 'AsDr', 'Asio')\r
-{\r
-       connID = -1;\r
-       curIndex = -1;\r
-}\r
-\r
-AsioDrivers::~AsioDrivers()\r
-{\r
-       removeCurrentDriver();\r
-}\r
-\r
-bool AsioDrivers::getCurrentDriverName(char *name)\r
-{\r
-       if(curIndex >= 0)\r
-               return getName(curIndex, name);\r
-       return false;\r
-}\r
-\r
-long AsioDrivers::getDriverNames(char **names, long maxDrivers)\r
-{\r
-       for(long i = 0; i < getNumFragments() && i < maxDrivers; i++)\r
-               getName(i, names[i]);\r
-       return getNumFragments() < maxDrivers ? getNumFragments() : maxDrivers;\r
-}\r
-\r
-bool AsioDrivers::loadDriver(char *name)\r
-{\r
-       char dname[64];\r
-       unsigned long newID;\r
-\r
-       for(long i = 0; i < getNumFragments(); i++)\r
-       {\r
-               if(getName(i, dname) && !strcmp(name, dname))\r
-               {\r
-                       if(newInstance(i, &newID))\r
-                       {\r
-                               if(resolveASIO(newID))\r
-                               {\r
-                                       if(connID != -1)\r
-                                               removeInstance(curIndex, connID);\r
-                                       curIndex = i;\r
-                                       connID = newID;\r
-                                       return true;\r
-                               }\r
-                       }\r
-                       break;\r
-               }\r
-       }\r
-       return false;\r
-}\r
-\r
-void AsioDrivers::removeCurrentDriver()\r
-{\r
-       if(connID != -1)\r
-               removeInstance(curIndex, connID);\r
-       connID = -1;\r
-       curIndex = -1;\r
-}\r
-\r
-//------------------------------------------------------------------------------------\r
-\r
-#elif WINDOWS\r
-\r
-#include "iasiodrv.h"\r
-\r
-extern IASIO* theAsioDriver;\r
-\r
-AsioDrivers::AsioDrivers() : AsioDriverList()\r
-{\r
-       curIndex = -1;\r
-}\r
-\r
-AsioDrivers::~AsioDrivers()\r
-{\r
-}\r
-\r
-bool AsioDrivers::getCurrentDriverName(char *name)\r
-{\r
-       if(curIndex >= 0)\r
-               return asioGetDriverName(curIndex, name, 32) == 0 ? true : false;\r
-       name[0] = 0;\r
-       return false;\r
-}\r
-\r
-long AsioDrivers::getDriverNames(char **names, long maxDrivers)\r
-{\r
-       for(long i = 0; i < asioGetNumDev() && i < maxDrivers; i++)\r
-               asioGetDriverName(i, names[i], 32);\r
-       return asioGetNumDev() < maxDrivers ? asioGetNumDev() : maxDrivers;\r
-}\r
-\r
-bool AsioDrivers::loadDriver(char *name)\r
-{\r
-       char dname[64];\r
-       char curName[64];\r
-\r
-       for(long i = 0; i < asioGetNumDev(); i++)\r
-       {\r
-               if(!asioGetDriverName(i, dname, 32) && !strcmp(name, dname))\r
-               {\r
-                       curName[0] = 0;\r
-                       getCurrentDriverName(curName);  // in case we fail...\r
-                       removeCurrentDriver();\r
-\r
-                       if(!asioOpenDriver(i, (void **)&theAsioDriver))\r
-                       {\r
-                               curIndex = i;\r
-                               return true;\r
-                       }\r
-                       else\r
-                       {\r
-                               theAsioDriver = 0;\r
-                               if(curName[0] && strcmp(dname, curName))\r
-                                       loadDriver(curName);    // try restore\r
-                       }\r
-                       break;\r
-               }\r
-       }\r
-       return false;\r
-}\r
-\r
-void AsioDrivers::removeCurrentDriver()\r
-{\r
-       if(curIndex != -1)\r
-               asioCloseDriver(curIndex);\r
-       curIndex = -1;\r
-}\r
-\r
-#elif SGI || BEOS\r
-\r
-#include "asiolist.h"\r
-\r
-AsioDrivers::AsioDrivers() \r
-       : AsioDriverList()\r
-{\r
-       curIndex = -1;\r
-}\r
-\r
-AsioDrivers::~AsioDrivers()\r
-{\r
-}\r
-\r
-bool AsioDrivers::getCurrentDriverName(char *name)\r
-{\r
-       return false;\r
-}\r
-\r
-long AsioDrivers::getDriverNames(char **names, long maxDrivers)\r
-{\r
-       return 0;\r
-}\r
-\r
-bool AsioDrivers::loadDriver(char *name)\r
-{\r
-       return false;\r
-}\r
-\r
-void AsioDrivers::removeCurrentDriver()\r
-{\r
-}\r
-\r
-#else\r
-#error implement me\r
-#endif\r
diff --git a/asio/asiodrivers.h b/asio/asiodrivers.h
deleted file mode 100644 (file)
index 2ddf7ad..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __AsioDrivers__\r
-#define __AsioDrivers__\r
-\r
-#include "ginclude.h"\r
-\r
-#if MAC\r
-#include "CodeFragments.hpp"\r
-\r
-class AsioDrivers : public CodeFragments\r
-\r
-#elif WINDOWS\r
-#include <windows.h>\r
-#include "asiolist.h"\r
-\r
-class AsioDrivers : public AsioDriverList\r
-\r
-#elif SGI || BEOS\r
-#include "asiolist.h"\r
-\r
-class AsioDrivers : public AsioDriverList\r
-\r
-#else\r
-#error implement me\r
-#endif\r
-\r
-{\r
-public:\r
-       AsioDrivers();\r
-       ~AsioDrivers();\r
-       \r
-       bool getCurrentDriverName(char *name);\r
-       long getDriverNames(char **names, long maxDrivers);\r
-       bool loadDriver(char *name);\r
-       void removeCurrentDriver();\r
-       long getCurrentDriverIndex() {return curIndex;}\r
-protected:\r
-       unsigned long connID;\r
-       long curIndex;\r
-};\r
-\r
-#endif\r
diff --git a/asio/asiodrvr.h b/asio/asiodrvr.h
deleted file mode 100644 (file)
index 663f75a..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*\r
-       Steinberg Audio Stream I/O API\r
-       (c) 1996, Steinberg Soft- und Hardware GmbH\r
-       charlie (May 1996)\r
-\r
-       asiodrvr.h\r
-       c++ superclass to implement asio functionality. from this,\r
-       you can derive whatever required\r
-*/\r
-\r
-#ifndef _asiodrvr_\r
-#define _asiodrvr_\r
-\r
-// cpu and os system we are running on\r
-#include "asiosys.h"\r
-// basic "C" interface\r
-#include "asio.h"\r
-\r
-class AsioDriver;\r
-extern AsioDriver *getDriver();                // for generic constructor \r
-\r
-#if WINDOWS\r
-#include <windows.h>\r
-#include "combase.h"\r
-#include "iasiodrv.h"\r
-class AsioDriver : public IASIO ,public CUnknown\r
-{\r
-public:\r
-       AsioDriver(LPUNKNOWN pUnk, HRESULT *phr);\r
-\r
-       DECLARE_IUNKNOWN\r
-       // Factory method\r
-       static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);\r
-       // IUnknown\r
-       virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject);\r
-\r
-#else\r
-\r
-class AsioDriver\r
-{\r
-public:\r
-       AsioDriver();\r
-#endif\r
-       virtual ~AsioDriver();\r
-\r
-       virtual ASIOBool init(void* sysRef);\r
-       virtual void getDriverName(char *name); // max 32 bytes incl. terminating zero\r
-       virtual long getDriverVersion();\r
-       virtual void getErrorMessage(char *string);     // max 124 bytes incl.\r
-\r
-       virtual ASIOError start();\r
-       virtual ASIOError stop();\r
-\r
-       virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);\r
-       virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);\r
-       virtual ASIOError getBufferSize(long *minSize, long *maxSize,\r
-               long *preferredSize, long *granularity);\r
-\r
-       virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);\r
-       virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);\r
-       virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);\r
-       virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);\r
-       virtual ASIOError setClockSource(long reference);\r
-\r
-       virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp);\r
-       virtual ASIOError getChannelInfo(ASIOChannelInfo *info);\r
-\r
-       virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
-               long bufferSize, ASIOCallbacks *callbacks);\r
-       virtual ASIOError disposeBuffers();\r
-\r
-       virtual ASIOError controlPanel();\r
-       virtual ASIOError future(long selector, void *opt);\r
-       virtual ASIOError outputReady();\r
-};\r
-#endif\r
diff --git a/asio/asiolist.cpp b/asio/asiolist.cpp
deleted file mode 100644 (file)
index 5a62f5b..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-#include <windows.h>\r
-#include "iasiodrv.h"\r
-#include "asiolist.h"\r
-\r
-#define ASIODRV_DESC           "description"\r
-#define INPROC_SERVER          "InprocServer32"\r
-#define ASIO_PATH                      "software\\asio"\r
-#define COM_CLSID                      "clsid"\r
-\r
-// ******************************************************************\r
-// Local Functions \r
-// ******************************************************************\r
-static LONG findDrvPath (char *clsidstr,char *dllpath,int dllpathsize)\r
-{\r
-       HKEY                    hkEnum,hksub,hkpath;\r
-       char                    databuf[512];\r
-       LONG                    cr,rc = -1;\r
-       DWORD                   datatype,datasize;\r
-       DWORD                   index;\r
-       OFSTRUCT                ofs;\r
-       HFILE                   hfile;\r
-       BOOL                    found = FALSE;\r
-\r
-       CharLowerBuff(clsidstr,strlen(clsidstr));\r
-       if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) {\r
-\r
-               index = 0;\r
-               while (cr == ERROR_SUCCESS && !found) {\r
-                       cr = RegEnumKey(hkEnum,index++,(LPTSTR)databuf,512);\r
-                       if (cr == ERROR_SUCCESS) {\r
-                               CharLowerBuff(databuf,strlen(databuf));\r
-                               if (!(strcmp(databuf,clsidstr))) {\r
-                                       if ((cr = RegOpenKeyEx(hkEnum,(LPCTSTR)databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {\r
-                                               if ((cr = RegOpenKeyEx(hksub,(LPCTSTR)INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) {\r
-                                                       datatype = REG_SZ; datasize = (DWORD)dllpathsize;\r
-                                                       cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize);\r
-                                                       if (cr == ERROR_SUCCESS) {\r
-                                                               memset(&ofs,0,sizeof(OFSTRUCT));\r
-                                                               ofs.cBytes = sizeof(OFSTRUCT); \r
-                                                               hfile = OpenFile(dllpath,&ofs,OF_EXIST);\r
-                                                               if (hfile) rc = 0; \r
-                                                       }\r
-                                                       RegCloseKey(hkpath);\r
-                                               }\r
-                                               RegCloseKey(hksub);\r
-                                       }\r
-                                       found = TRUE;   // break out \r
-                               }\r
-                       }\r
-               }                               \r
-               RegCloseKey(hkEnum);\r
-       }\r
-       return rc;\r
-}\r
-\r
-\r
-static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv)\r
-{\r
-       HKEY    hksub;\r
-       char    databuf[256];\r
-       char    dllpath[MAXPATHLEN];\r
-       WORD    wData[100];\r
-       CLSID   clsid;\r
-       DWORD   datatype,datasize;\r
-       LONG    cr,rc;\r
-\r
-       if (!lpdrv) {\r
-               if ((cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {\r
-\r
-                       datatype = REG_SZ; datasize = 256;\r
-                       cr = RegQueryValueEx(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize);\r
-                       if (cr == ERROR_SUCCESS) {\r
-                               rc = findDrvPath (databuf,dllpath,MAXPATHLEN);\r
-                               if (rc == 0) {\r
-                                       lpdrv = new ASIODRVSTRUCT[1];\r
-                                       if (lpdrv) {\r
-                                               memset(lpdrv,0,sizeof(ASIODRVSTRUCT));\r
-                                               lpdrv->drvID = drvID;\r
-                                               MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100);\r
-                                               if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) {\r
-                                                       memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID));\r
-                                               }\r
-\r
-                                               datatype = REG_SZ; datasize = 256;\r
-                                               cr = RegQueryValueEx(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize);\r
-                                               if (cr == ERROR_SUCCESS) {\r
-                                                       strcpy(lpdrv->drvname,databuf);\r
-                                               }\r
-                                               else strcpy(lpdrv->drvname,keyname);\r
-                                       }\r
-                               }\r
-                       }\r
-                       RegCloseKey(hksub);\r
-               }\r
-       }       \r
-       else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next);\r
-\r
-       return lpdrv;\r
-}\r
-\r
-static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv)\r
-{\r
-       IASIO   *iasio;\r
-\r
-       if (lpdrv != 0) {\r
-               deleteDrvStruct(lpdrv->next);\r
-               if (lpdrv->asiodrv) {\r
-                       iasio = (IASIO *)lpdrv->asiodrv;\r
-                       iasio->Release();\r
-               }\r
-               delete lpdrv;\r
-       }\r
-}\r
-\r
-\r
-static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv)\r
-{\r
-       while (lpdrv) {\r
-               if (lpdrv->drvID == drvID) return lpdrv;\r
-               lpdrv = lpdrv->next;\r
-       }\r
-       return 0;\r
-}\r
-// ******************************************************************\r
-\r
-\r
-// ******************************************************************\r
-//     AsioDriverList\r
-// ******************************************************************\r
-AsioDriverList::AsioDriverList ()\r
-{\r
-       HKEY                    hkEnum = 0;\r
-       char                    keyname[MAXDRVNAMELEN];\r
-       LPASIODRVSTRUCT pdl;\r
-       LONG                    cr;\r
-       DWORD                   index = 0;\r
-       BOOL                    fin = FALSE;\r
-\r
-       numdrv          = 0;\r
-       lpdrvlist       = 0;\r
-\r
-       cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum);\r
-       while (cr == ERROR_SUCCESS) {\r
-               if ((cr = RegEnumKey(hkEnum,index++,(LPTSTR)keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) {\r
-                       lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist);\r
-               }\r
-               else fin = TRUE;\r
-       }\r
-       if (hkEnum) RegCloseKey(hkEnum);\r
-\r
-       pdl = lpdrvlist;\r
-       while (pdl) {\r
-               numdrv++;\r
-               pdl = pdl->next;\r
-       }\r
-\r
-       if (numdrv) CoInitialize(0);    // initialize COM\r
-}\r
-\r
-AsioDriverList::~AsioDriverList ()\r
-{\r
-       if (numdrv) {\r
-               deleteDrvStruct(lpdrvlist);\r
-               CoUninitialize();\r
-       }\r
-}\r
-\r
-\r
-LONG AsioDriverList::asioGetNumDev (VOID)\r
-{\r
-       return (LONG)numdrv;\r
-}\r
-\r
-\r
-LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv)\r
-{\r
-       LPASIODRVSTRUCT lpdrv = 0;\r
-       long                    rc;\r
-\r
-       if (!asiodrv) return DRVERR_INVALID_PARAM;\r
-\r
-       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {\r
-               if (!lpdrv->asiodrv) {\r
-                       rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv);\r
-                       if (rc == S_OK) {\r
-                               lpdrv->asiodrv = *asiodrv;\r
-                               return 0;\r
-                       }\r
-                       // else if (rc == REGDB_E_CLASSNOTREG)\r
-                       //      strcpy (info->messageText, "Driver not registered in the Registration Database!");\r
-               }\r
-               else rc = DRVERR_DEVICE_ALREADY_OPEN;\r
-       }\r
-       else rc = DRVERR_DEVICE_NOT_FOUND;\r
-       \r
-       return rc;\r
-}\r
-\r
-\r
-LONG AsioDriverList::asioCloseDriver (int drvID)\r
-{\r
-       LPASIODRVSTRUCT lpdrv = 0;\r
-       IASIO                   *iasio;\r
-\r
-       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {\r
-               if (lpdrv->asiodrv) {\r
-                       iasio = (IASIO *)lpdrv->asiodrv;\r
-                       iasio->Release();\r
-                       lpdrv->asiodrv = 0;\r
-               }\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
-LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize)\r
-{      \r
-       LPASIODRVSTRUCT                 lpdrv = 0;\r
-\r
-       if (!drvname) return DRVERR_INVALID_PARAM;\r
-\r
-       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {\r
-               if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) {\r
-                       strcpy(drvname,lpdrv->drvname);\r
-               }\r
-               else {\r
-                       memcpy(drvname,lpdrv->drvname,drvnamesize-4);\r
-                       drvname[drvnamesize-4] = '.';\r
-                       drvname[drvnamesize-3] = '.';\r
-                       drvname[drvnamesize-2] = '.';\r
-                       drvname[drvnamesize-1] = 0;\r
-               }\r
-               return 0;\r
-       }\r
-       return DRVERR_DEVICE_NOT_FOUND;\r
-}\r
-\r
-LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize)\r
-{\r
-       LPASIODRVSTRUCT                 lpdrv = 0;\r
-\r
-       if (!dllpath) return DRVERR_INVALID_PARAM;\r
-\r
-       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {\r
-               if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) {\r
-                       strcpy(dllpath,lpdrv->dllpath);\r
-                       return 0;\r
-               }\r
-               dllpath[0] = 0;\r
-               return DRVERR_INVALID_PARAM;\r
-       }\r
-       return DRVERR_DEVICE_NOT_FOUND;\r
-}\r
-\r
-LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid)\r
-{\r
-       LPASIODRVSTRUCT                 lpdrv = 0;\r
-\r
-       if (!clsid) return DRVERR_INVALID_PARAM;\r
-\r
-       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {\r
-               memcpy(clsid,&lpdrv->clsid,sizeof(CLSID));\r
-               return 0;\r
-       }\r
-       return DRVERR_DEVICE_NOT_FOUND;\r
-}\r
-\r
-\r
diff --git a/asio/asiolist.h b/asio/asiolist.h
deleted file mode 100644 (file)
index 01c64f0..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __asiolist__\r
-#define __asiolist__\r
-\r
-#define DRVERR                 -5000\r
-#define DRVERR_INVALID_PARAM           DRVERR-1\r
-#define DRVERR_DEVICE_ALREADY_OPEN     DRVERR-2\r
-#define DRVERR_DEVICE_NOT_FOUND                DRVERR-3\r
-\r
-#define MAXPATHLEN                     512\r
-#define MAXDRVNAMELEN          128\r
-\r
-struct asiodrvstruct\r
-{\r
-       int                                             drvID;\r
-       CLSID                                   clsid;\r
-       char                                    dllpath[MAXPATHLEN];\r
-       char                                    drvname[MAXDRVNAMELEN];\r
-       LPVOID                                  asiodrv;\r
-       struct asiodrvstruct    *next;\r
-};\r
-\r
-typedef struct asiodrvstruct ASIODRVSTRUCT;\r
-typedef ASIODRVSTRUCT  *LPASIODRVSTRUCT;\r
-\r
-class AsioDriverList {\r
-public:\r
-       AsioDriverList();\r
-       ~AsioDriverList();\r
-       \r
-       LONG asioOpenDriver (int,VOID **);\r
-       LONG asioCloseDriver (int);\r
-\r
-       // nice to have\r
-       LONG asioGetNumDev (VOID);\r
-       LONG asioGetDriverName (int,char *,int);                \r
-       LONG asioGetDriverPath (int,char *,int);\r
-       LONG asioGetDriverCLSID (int,CLSID *);\r
-\r
-       // or use directly access\r
-       LPASIODRVSTRUCT lpdrvlist;\r
-       int                             numdrv;\r
-};\r
-\r
-typedef class AsioDriverList *LPASIODRIVERLIST;\r
-\r
-#endif\r
diff --git a/asio/asiosys.h b/asio/asiosys.h
deleted file mode 100644 (file)
index 37f7a48..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef __asiosys__\r
-       #define __asiosys__\r
-\r
-       #ifdef WIN32\r
-               #undef MAC \r
-               #define PPC 0\r
-               #define WINDOWS 1\r
-               #define SGI 0\r
-               #define SUN 0\r
-               #define LINUX 0\r
-               #define BEOS 0\r
-\r
-               #define NATIVE_INT64 0\r
-               #define IEEE754_64FLOAT 1\r
-       \r
-       #elif BEOS\r
-               #define MAC 0\r
-               #define PPC 0\r
-               #define WINDOWS 0\r
-               #define PC 0\r
-               #define SGI 0\r
-               #define SUN 0\r
-               #define LINUX 0\r
-               \r
-               #define NATIVE_INT64 0\r
-               #define IEEE754_64FLOAT 1\r
-               \r
-               #ifndef DEBUG\r
-                       #define DEBUG 0\r
-                       #if DEBUG\r
-                               void DEBUGGERMESSAGE(char *string);\r
-                       #else\r
-                               #define DEBUGGERMESSAGE(a)\r
-                       #endif\r
-               #endif\r
-\r
-       #elif SGI\r
-               #define MAC 0\r
-               #define PPC 0\r
-               #define WINDOWS 0\r
-               #define PC 0\r
-               #define SUN 0\r
-               #define LINUX 0\r
-               #define BEOS 0\r
-               \r
-               #define NATIVE_INT64 0\r
-               #define IEEE754_64FLOAT 1\r
-               \r
-               #ifndef DEBUG\r
-                       #define DEBUG 0\r
-                       #if DEBUG\r
-                               void DEBUGGERMESSAGE(char *string);\r
-                       #else\r
-                               #define DEBUGGERMESSAGE(a)\r
-                       #endif\r
-               #endif\r
-\r
-       #else   // MAC\r
-\r
-               #define MAC 1\r
-               #define PPC 1\r
-               #define WINDOWS 0\r
-               #define PC 0\r
-               #define SGI 0\r
-               #define SUN 0\r
-               #define LINUX 0\r
-               #define BEOS 0\r
-\r
-               #define NATIVE_INT64 0\r
-               #define IEEE754_64FLOAT 1\r
-\r
-               #ifndef DEBUG\r
-                       #define DEBUG 0\r
-                       #if DEBUG\r
-                               void DEBUGGERMESSAGE(char *string);\r
-                       #else\r
-                               #define DEBUGGERMESSAGE(a)\r
-                       #endif\r
-               #endif\r
-       #endif\r
-\r
-#endif\r
diff --git a/asio/ginclude.h b/asio/ginclude.h
deleted file mode 100644 (file)
index b627dc2..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef __gInclude__\r
-#define __gInclude__\r
-\r
-#if SGI \r
-       #undef BEOS \r
-       #undef MAC \r
-       #undef WINDOWS\r
-       //\r
-       #define ASIO_BIG_ENDIAN 1\r
-       #define ASIO_CPU_MIPS 1\r
-#elif defined WIN32\r
-       #undef BEOS \r
-       #undef MAC \r
-       #undef SGI\r
-       #define WINDOWS 1\r
-       #define ASIO_LITTLE_ENDIAN 1\r
-       #define ASIO_CPU_X86 1\r
-#elif BEOS\r
-       #undef MAC \r
-       #undef SGI\r
-       #undef WINDOWS\r
-       #define ASIO_LITTLE_ENDIAN 1\r
-       #define ASIO_CPU_X86 1\r
-       //\r
-#else\r
-       #define MAC 1\r
-       #undef BEOS \r
-       #undef WINDOWS\r
-       #undef SGI\r
-       #define ASIO_BIG_ENDIAN 1\r
-       #define ASIO_CPU_PPC 1\r
-#endif\r
-\r
-// always\r
-#define NATIVE_INT64 0\r
-#define IEEE754_64FLOAT 1\r
-\r
-#endif // __gInclude__\r
diff --git a/asio/iasiodrv.h b/asio/iasiodrv.h
deleted file mode 100644 (file)
index 64d2dbb..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "asiosys.h"\r
-#include "asio.h"\r
-\r
-/* Forward Declarations */ \r
-\r
-#ifndef __ASIODRIVER_FWD_DEFINED__\r
-#define __ASIODRIVER_FWD_DEFINED__\r
-typedef interface IASIO IASIO;\r
-#endif         /* __ASIODRIVER_FWD_DEFINED__ */\r
-\r
-interface IASIO : public IUnknown\r
-{\r
-\r
-       virtual ASIOBool init(void *sysHandle) = 0;\r
-       virtual void getDriverName(char *name) = 0;     \r
-       virtual long getDriverVersion() = 0;\r
-       virtual void getErrorMessage(char *string) = 0; \r
-       virtual ASIOError start() = 0;\r
-       virtual ASIOError stop() = 0;\r
-       virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0;\r
-       virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0;\r
-       virtual ASIOError getBufferSize(long *minSize, long *maxSize,\r
-               long *preferredSize, long *granularity) = 0;\r
-       virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0;\r
-       virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0;\r
-       virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0;\r
-       virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0;\r
-       virtual ASIOError setClockSource(long reference) = 0;\r
-       virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;\r
-       virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0;\r
-       virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
-               long bufferSize, ASIOCallbacks *callbacks) = 0;\r
-       virtual ASIOError disposeBuffers() = 0;\r
-       virtual ASIOError controlPanel() = 0;\r
-       virtual ASIOError future(long selector,void *opt) = 0;\r
-       virtual ASIOError outputReady() = 0;\r
-};\r
diff --git a/asio/iasiothiscallresolver.cpp b/asio/iasiothiscallresolver.cpp
deleted file mode 100644 (file)
index 38c39d2..0000000
+++ /dev/null
@@ -1,563 +0,0 @@
-/*\r
-       IASIOThiscallResolver.cpp see the comments in iasiothiscallresolver.h for\r
-    the top level description - this comment describes the technical details of\r
-    the implementation.\r
-\r
-    The latest version of this file is available from:\r
-    http://www.audiomulch.com/~rossb/code/calliasio\r
-\r
-    please email comments to Ross Bencina <rossb@audiomulch.com>\r
-\r
-    BACKGROUND\r
-\r
-    The IASIO interface declared in the Steinberg ASIO 2 SDK declares\r
-    functions with no explicit calling convention. This causes MSVC++ to default\r
-    to using the thiscall convention, which is a proprietary convention not\r
-    implemented by some non-microsoft compilers - notably borland BCC,\r
-    C++Builder, and gcc. MSVC++ is the defacto standard compiler used by\r
-    Steinberg. As a result of this situation, the ASIO sdk will compile with\r
-    any compiler, however attempting to execute the compiled code will cause a\r
-    crash due to different default calling conventions on non-Microsoft\r
-    compilers.\r
-\r
-    IASIOThiscallResolver solves the problem by providing an adapter class that\r
-    delegates to the IASIO interface using the correct calling convention\r
-    (thiscall). Due to the lack of support for thiscall in the Borland and GCC\r
-    compilers, the calls have been implemented in assembly language.\r
-\r
-    A number of macros are defined for thiscall function calls with different\r
-    numbers of parameters, with and without return values - it may be possible\r
-    to modify the format of these macros to make them work with other inline\r
-    assemblers.\r
-\r
-\r
-    THISCALL DEFINITION\r
-\r
-    A number of definitions of the thiscall calling convention are floating\r
-    around the internet. The following definition has been validated against\r
-    output from the MSVC++ compiler:\r
-\r
-    For non-vararg functions, thiscall works as follows: the object (this)\r
-    pointer is passed in ECX. All arguments are passed on the stack in\r
-    right to left order. The return value is placed in EAX. The callee\r
-    clears the passed arguments from the stack.\r
-\r
-\r
-    FINDING FUNCTION POINTERS FROM AN IASIO POINTER\r
-\r
-    The first field of a COM object is a pointer to its vtble. Thus a pointer\r
-    to an object implementing the IASIO interface also points to a pointer to\r
-    that object's vtbl. The vtble is a table of function pointers for all of\r
-    the virtual functions exposed by the implemented interfaces.\r
-\r
-    If we consider a variable declared as a pointer to IASO:\r
-\r
-    IASIO *theAsioDriver\r
-\r
-    theAsioDriver points to:\r
-\r
-    object implementing IASIO\r
-    {\r
-        IASIOvtbl *vtbl\r
-        other data\r
-    }\r
-\r
-    in other words, theAsioDriver points to a pointer to an IASIOvtbl\r
-\r
-    vtbl points to a table of function pointers:\r
-\r
-    IASIOvtbl ( interface IASIO : public IUnknown )\r
-    {\r
-    (IUnknown functions)\r
-    0   virtual HRESULT STDMETHODCALLTYPE (*QueryInterface)(REFIID riid, void **ppv) = 0;\r
-    4   virtual ULONG STDMETHODCALLTYPE (*AddRef)() = 0;\r
-    8   virtual ULONG STDMETHODCALLTYPE (*Release)() = 0;      \r
-\r
-    (IASIO functions)\r
-    12 virtual ASIOBool (*init)(void *sysHandle) = 0;\r
-    16 virtual void (*getDriverName)(char *name) = 0;\r
-    20 virtual long (*getDriverVersion)() = 0;\r
-    24 virtual void (*getErrorMessage)(char *string) = 0;\r
-    28 virtual ASIOError (*start)() = 0;\r
-    32 virtual ASIOError (*stop)() = 0;\r
-    36 virtual ASIOError (*getChannels)(long *numInputChannels, long *numOutputChannels) = 0;\r
-    40 virtual ASIOError (*getLatencies)(long *inputLatency, long *outputLatency) = 0;\r
-    44 virtual ASIOError (*getBufferSize)(long *minSize, long *maxSize,\r
-            long *preferredSize, long *granularity) = 0;\r
-    48 virtual ASIOError (*canSampleRate)(ASIOSampleRate sampleRate) = 0;\r
-    52 virtual ASIOError (*getSampleRate)(ASIOSampleRate *sampleRate) = 0;\r
-    56 virtual ASIOError (*setSampleRate)(ASIOSampleRate sampleRate) = 0;\r
-    60 virtual ASIOError (*getClockSources)(ASIOClockSource *clocks, long *numSources) = 0;\r
-    64 virtual ASIOError (*setClockSource)(long reference) = 0;\r
-    68 virtual ASIOError (*getSamplePosition)(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;\r
-    72 virtual ASIOError (*getChannelInfo)(ASIOChannelInfo *info) = 0;\r
-    76 virtual ASIOError (*createBuffers)(ASIOBufferInfo *bufferInfos, long numChannels,\r
-            long bufferSize, ASIOCallbacks *callbacks) = 0;\r
-    80 virtual ASIOError (*disposeBuffers)() = 0;\r
-    84 virtual ASIOError (*controlPanel)() = 0;\r
-    88 virtual ASIOError (*future)(long selector,void *opt) = 0;\r
-    92 virtual ASIOError (*outputReady)() = 0;\r
-    };\r
-\r
-    The numbers in the left column show the byte offset of each function ptr\r
-    from the beginning of the vtbl. These numbers are used in the code below\r
-    to select different functions.\r
-\r
-    In order to find the address of a particular function, theAsioDriver\r
-    must first be dereferenced to find the value of the vtbl pointer:\r
-\r
-    mov     eax, theAsioDriver\r
-    mov     edx, [theAsioDriver]  // edx now points to vtbl[0]\r
-\r
-    Then an offset must be added to the vtbl pointer to select a\r
-    particular function, for example vtbl+44 points to the slot containing\r
-    a pointer to the getBufferSize function.\r
-\r
-    Finally vtbl+x must be dereferenced to obtain the value of the function\r
-    pointer stored in that address:\r
-\r
-    call    [edx+44]    // call the function pointed to by\r
-                        // the value in the getBufferSize field of the vtbl\r
-\r
-\r
-    SEE ALSO\r
-\r
-    Martin Fay's OpenASIO DLL at http://www.martinfay.com solves the same\r
-    problem by providing a new COM interface which wraps IASIO with an\r
-    interface that uses portable calling conventions. OpenASIO must be compiled\r
-    with MSVC, and requires that you ship the OpenASIO DLL with your\r
-    application.\r
-\r
-    \r
-    ACKNOWLEDGEMENTS\r
-\r
-    Ross Bencina: worked out the thiscall details above, wrote the original\r
-    Borland asm macros, and a patch for asio.cpp (which is no longer needed).\r
-    Thanks to Martin Fay for introducing me to the issues discussed here,\r
-    and to Rene G. Ceballos for assisting with asm dumps from MSVC++.\r
-\r
-    Antti Silvast: converted the original calliasio to work with gcc and NASM\r
-    by implementing the asm code in a separate file.\r
-\r
-       Fraser Adams: modified the original calliasio containing the Borland inline\r
-    asm to add inline asm for gcc i.e. Intel syntax for Borland and AT&T syntax\r
-    for gcc. This seems a neater approach for gcc than to have a separate .asm\r
-    file and it means that we only need one version of the thiscall patch.\r
-\r
-    Fraser Adams: rewrote the original calliasio patch in the form of the\r
-    IASIOThiscallResolver class in order to avoid modifications to files from\r
-    the Steinberg SDK, which may have had potential licence issues.\r
-\r
-    Andrew Baldwin: contributed fixes for compatibility problems with more\r
-    recent versions of the gcc assembler.\r
-*/\r
-\r
-\r
-// We only need IASIOThiscallResolver at all if we are on Win32. For other\r
-// platforms we simply bypass the IASIOThiscallResolver definition to allow us\r
-// to be safely #include'd whatever the platform to keep client code portable\r
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)\r
-\r
-\r
-// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver\r
-// is not used.\r
-#if !defined(_MSC_VER)\r
-\r
-\r
-#include <new>\r
-#include <assert.h>\r
-\r
-// We have a mechanism in iasiothiscallresolver.h to ensure that asio.h is\r
-// #include'd before it in client code, we do NOT want to do this test here.\r
-#define iasiothiscallresolver_sourcefile 1\r
-#include "iasiothiscallresolver.h"\r
-#undef iasiothiscallresolver_sourcefile\r
-\r
-// iasiothiscallresolver.h redefines ASIOInit for clients, but we don't want\r
-// this macro defined in this translation unit.\r
-#undef ASIOInit\r
-\r
-\r
-// theAsioDriver is a global pointer to the current IASIO instance which the\r
-// ASIO SDK uses to perform all actions on the IASIO interface. We substitute\r
-// our own forwarding interface into this pointer.\r
-extern IASIO* theAsioDriver;\r
-\r
-\r
-// The following macros define the inline assembler for BORLAND first then gcc\r
-\r
-#if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)          \r
-\r
-\r
-#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )\\r
-    void *this_ = (thisPtr);                                                \\r
-    __asm {                                                                 \\r
-        mov     ecx, this_            ;                                     \\r
-        mov     eax, [ecx]            ;                                     \\r
-        call    [eax+funcOffset]      ;                                     \\r
-        mov     resultName, eax       ;                                     \\r
-    }\r
-\r
-\r
-#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )\\r
-    void *this_ = (thisPtr);                                                \\r
-    __asm {                                                                 \\r
-        mov     eax, param1           ;                                     \\r
-        push    eax                   ;                                     \\r
-        mov     ecx, this_            ;                                     \\r
-        mov     eax, [ecx]            ;                                     \\r
-        call    [eax+funcOffset]      ;                                     \\r
-    }\r
-\r
-\r
-#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )\\r
-    void *this_ = (thisPtr);                                                \\r
-    __asm {                                                                 \\r
-        mov     eax, param1           ;                                     \\r
-        push    eax                   ;                                     \\r
-        mov     ecx, this_            ;                                     \\r
-        mov     eax, [ecx]            ;                                     \\r
-        call    [eax+funcOffset]      ;                                     \\r
-        mov     resultName, eax       ;                                     \\r
-    }\r
-\r
-\r
-#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )\\r
-    void *this_ = (thisPtr);                                                \\r
-    void *doubleParamPtr_ (&param1);                                        \\r
-    __asm {                                                                 \\r
-        mov     eax, doubleParamPtr_  ;                                     \\r
-        push    [eax+4]               ;                                     \\r
-        push    [eax]                 ;                                     \\r
-        mov     ecx, this_            ;                                     \\r
-        mov     eax, [ecx]            ;                                     \\r
-        call    [eax+funcOffset]      ;                                     \\r
-        mov     resultName, eax       ;                                     \\r
-    }\r
-\r
-\r
-#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )\\r
-    void *this_ = (thisPtr);                                                \\r
-    __asm {                                                                 \\r
-        mov     eax, param2           ;                                     \\r
-        push    eax                   ;                                     \\r
-        mov     eax, param1           ;                                     \\r
-        push    eax                   ;                                     \\r
-        mov     ecx, this_            ;                                     \\r
-        mov     eax, [ecx]            ;                                     \\r
-        call    [eax+funcOffset]      ;                                     \\r
-        mov     resultName, eax       ;                                     \\r
-    }\r
-\r
-\r
-#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\\r
-    void *this_ = (thisPtr);                                                \\r
-    __asm {                                                                 \\r
-        mov     eax, param4           ;                                     \\r
-        push    eax                   ;                                     \\r
-        mov     eax, param3           ;                                     \\r
-        push    eax                   ;                                     \\r
-        mov     eax, param2           ;                                     \\r
-        push    eax                   ;                                     \\r
-        mov     eax, param1           ;                                     \\r
-        push    eax                   ;                                     \\r
-        mov     ecx, this_            ;                                     \\r
-        mov     eax, [ecx]            ;                                     \\r
-        call    [eax+funcOffset]      ;                                     \\r
-        mov     resultName, eax       ;                                     \\r
-    }\r
-\r
-\r
-#elif defined(__GNUC__)\r
-\r
-\r
-#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )                  \\r
-    __asm__ __volatile__ ("movl (%1), %%edx\n\t"                            \\r
-                          "call *"#funcOffset"(%%edx)\n\t"                  \\r
-                          :"=a"(resultName) /* Output Operands */           \\r
-                          :"c"(thisPtr)     /* Input Operands */            \\r
-                         );                                                 \\r
-\r
-\r
-#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )                 \\r
-    __asm__ __volatile__ ("pushl %0\n\t"                                    \\r
-                          "movl (%1), %%edx\n\t"                            \\r
-                          "call *"#funcOffset"(%%edx)\n\t"                  \\r
-                          :                 /* Output Operands */           \\r
-                          :"r"(param1),     /* Input Operands */            \\r
-                           "c"(thisPtr)                                     \\r
-                         );                                                 \\r
-\r
-\r
-#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )          \\r
-    __asm__ __volatile__ ("pushl %1\n\t"                                    \\r
-                          "movl (%2), %%edx\n\t"                            \\r
-                          "call *"#funcOffset"(%%edx)\n\t"                  \\r
-                          :"=a"(resultName) /* Output Operands */           \\r
-                          :"r"(param1),     /* Input Operands */            \\r
-                           "c"(thisPtr)                                     \\r
-                          );                                                \\r
-\r
-\r
-#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )   \\r
-    __asm__ __volatile__ ("pushl 4(%1)\n\t"                                 \\r
-                          "pushl (%1)\n\t"                                  \\r
-                          "movl (%2), %%edx\n\t"                            \\r
-                          "call *"#funcOffset"(%%edx);\n\t"                 \\r
-                          :"=a"(resultName) /* Output Operands */           \\r
-                          :"a"(&param1),    /* Input Operands */            \\r
-                           /* Note: Using "r" above instead of "a" fails */ \\r
-                           /* when using GCC 3.3.3, and maybe later versions*/\\r
-                           "c"(thisPtr)                                     \\r
-                          );                                                \\r
-\r
-\r
-#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )  \\r
-    __asm__ __volatile__ ("pushl %1\n\t"                                    \\r
-                          "pushl %2\n\t"                                    \\r
-                          "movl (%3), %%edx\n\t"                            \\r
-                          "call *"#funcOffset"(%%edx)\n\t"                  \\r
-                          :"=a"(resultName) /* Output Operands */           \\r
-                          :"r"(param2),     /* Input Operands */            \\r
-                           "r"(param1),                                     \\r
-                           "c"(thisPtr)                                     \\r
-                          );                                                \\r
-\r
-\r
-#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\\r
-    __asm__ __volatile__ ("pushl %1\n\t"                                    \\r
-                          "pushl %2\n\t"                                    \\r
-                          "pushl %3\n\t"                                    \\r
-                          "pushl %4\n\t"                                    \\r
-                          "movl (%5), %%edx\n\t"                            \\r
-                          "call *"#funcOffset"(%%edx)\n\t"                  \\r
-                          :"=a"(resultName) /* Output Operands */           \\r
-                          :"r"(param4),     /* Input Operands  */           \\r
-                           "r"(param3),                                     \\r
-                           "r"(param2),                                     \\r
-                           "r"(param1),                                     \\r
-                           "c"(thisPtr)                                     \\r
-                          );                                                \\r
-\r
-#endif\r
-\r
-\r
-\r
-// Our static singleton instance.\r
-IASIOThiscallResolver IASIOThiscallResolver::instance;\r
-\r
-// Constructor called to initialize static Singleton instance above. Note that\r
-// it is important not to clear that_ incase it has already been set by the call\r
-// to placement new in ASIOInit().\r
-IASIOThiscallResolver::IASIOThiscallResolver()\r
-{\r
-}\r
-\r
-// Constructor called from ASIOInit() below\r
-IASIOThiscallResolver::IASIOThiscallResolver(IASIO* that)\r
-: that_( that )\r
-{\r
-}\r
-\r
-// Implement IUnknown methods as assert(false). IASIOThiscallResolver is not\r
-// really a COM object, just a wrapper which will work with the ASIO SDK.\r
-// If you wanted to use ASIO without the SDK you might want to implement COM\r
-// aggregation in these methods.\r
-HRESULT STDMETHODCALLTYPE IASIOThiscallResolver::QueryInterface(REFIID riid, void **ppv)\r
-{\r
-    (void)riid;     // suppress unused variable warning\r
-\r
-    assert( false ); // this function should never be called by the ASIO SDK.\r
-\r
-    *ppv = NULL;\r
-    return E_NOINTERFACE;\r
-}\r
-\r
-ULONG STDMETHODCALLTYPE IASIOThiscallResolver::AddRef()\r
-{\r
-    assert( false ); // this function should never be called by the ASIO SDK.\r
-\r
-    return 1;\r
-}\r
-\r
-ULONG STDMETHODCALLTYPE IASIOThiscallResolver::Release()\r
-{\r
-    assert( false ); // this function should never be called by the ASIO SDK.\r
-    \r
-    return 1;\r
-}\r
-\r
-\r
-// Implement the IASIO interface methods by performing the vptr manipulation\r
-// described above then delegating to the real implementation.\r
-ASIOBool IASIOThiscallResolver::init(void *sysHandle)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_1( result, that_, 12, sysHandle );\r
-    return result;\r
-}\r
-\r
-void IASIOThiscallResolver::getDriverName(char *name)\r
-{\r
-    CALL_VOID_THISCALL_1( that_, 16, name );\r
-}\r
-\r
-long IASIOThiscallResolver::getDriverVersion()\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_0( result, that_, 20 );\r
-    return result;\r
-}\r
-\r
-void IASIOThiscallResolver::getErrorMessage(char *string)\r
-{\r
-     CALL_VOID_THISCALL_1( that_, 24, string );\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::start()\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_0( result, that_, 28 );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::stop()\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_0( result, that_, 32 );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::getChannels(long *numInputChannels, long *numOutputChannels)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_2( result, that_, 36, numInputChannels, numOutputChannels );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::getLatencies(long *inputLatency, long *outputLatency)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_2( result, that_, 40, inputLatency, outputLatency );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::getBufferSize(long *minSize, long *maxSize,\r
-        long *preferredSize, long *granularity)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_4( result, that_, 44, minSize, maxSize, preferredSize, granularity );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::canSampleRate(ASIOSampleRate sampleRate)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_1_DOUBLE( result, that_, 48, sampleRate );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::getSampleRate(ASIOSampleRate *sampleRate)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_1( result, that_, 52, sampleRate );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::setSampleRate(ASIOSampleRate sampleRate)\r
-{    \r
-    ASIOBool result;\r
-    CALL_THISCALL_1_DOUBLE( result, that_, 56, sampleRate );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::getClockSources(ASIOClockSource *clocks, long *numSources)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_2( result, that_, 60, clocks, numSources );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::setClockSource(long reference)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_1( result, that_, 64, reference );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_2( result, that_, 68, sPos, tStamp );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::getChannelInfo(ASIOChannelInfo *info)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_1( result, that_, 72, info );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::createBuffers(ASIOBufferInfo *bufferInfos,\r
-        long numChannels, long bufferSize, ASIOCallbacks *callbacks)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_4( result, that_, 76, bufferInfos, numChannels, bufferSize, callbacks );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::disposeBuffers()\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_0( result, that_, 80 );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::controlPanel()\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_0( result, that_, 84 );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::future(long selector,void *opt)\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_2( result, that_, 88, selector, opt );\r
-    return result;\r
-}\r
-\r
-ASIOError IASIOThiscallResolver::outputReady()\r
-{\r
-    ASIOBool result;\r
-    CALL_THISCALL_0( result, that_, 92 );\r
-    return result;\r
-}\r
-\r
-\r
-// Implement our substitute ASIOInit() method\r
-ASIOError IASIOThiscallResolver::ASIOInit(ASIODriverInfo *info)\r
-{\r
-    // To ensure that our instance's vptr is correctly constructed, even if\r
-    // ASIOInit is called prior to main(), we explicitly call its constructor\r
-    // (potentially over the top of an existing instance). Note that this is\r
-    // pretty ugly, and is only safe because IASIOThiscallResolver has no\r
-    // destructor and contains no objects with destructors.\r
-    new((void*)&instance) IASIOThiscallResolver( theAsioDriver );\r
-\r
-    // Interpose between ASIO client code and the real driver.\r
-    theAsioDriver = &instance;\r
-\r
-    // Note that we never need to switch theAsioDriver back to point to the\r
-    // real driver because theAsioDriver is reset to zero in ASIOExit().\r
-\r
-    // Delegate to the real ASIOInit\r
-       return ::ASIOInit(info);\r
-}\r
-\r
-\r
-#endif /* !defined(_MSC_VER) */\r
-\r
-#endif /* Win32 */\r
-\r
diff --git a/asio/iasiothiscallresolver.h b/asio/iasiothiscallresolver.h
deleted file mode 100644 (file)
index b59d910..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-// ****************************************************************************\r
-//\r
-// Changed:         I have modified this file slightly (includes) to work  with\r
-//                  RtAudio. RtAudio.cpp must include this file after asio.h.                                                    \r
-//\r
-// File:                       IASIOThiscallResolver.h\r
-// Description:     The IASIOThiscallResolver class implements the IASIO\r
-//                                     interface and acts as a proxy to the real IASIO interface by\r
-//                  calling through its vptr table using the thiscall calling\r
-//                  convention. To put it another way, we interpose\r
-//                  IASIOThiscallResolver between ASIO SDK code and the driver.\r
-//                  This is necessary because most non-Microsoft compilers don't\r
-//                  implement the thiscall calling convention used by IASIO.\r
-//\r
-//                                     iasiothiscallresolver.cpp contains the background of this\r
-//                                     problem plus a technical description of the vptr\r
-//                  manipulations.\r
-//\r
-//                                     In order to use this mechanism one simply has to add\r
-//                                     iasiothiscallresolver.cpp to the list of files to compile\r
-//                  and #include <iasiothiscallresolver.h>\r
-//\r
-//                                     Note that this #include must come after the other ASIO SDK\r
-//                  #includes, for example:\r
-//\r
-//                                     #include <windows.h>\r
-//                                     #include <asiosys.h>\r
-//                                     #include <asio.h>\r
-//                                     #include <asiodrivers.h>\r
-//                                     #include <iasiothiscallresolver.h>\r
-//\r
-//                                     Actually the important thing is to #include\r
-//                  <iasiothiscallresolver.h> after <asio.h>. We have\r
-//                  incorporated a test to enforce this ordering.\r
-//\r
-//                                     The code transparently takes care of the interposition by\r
-//                  using macro substitution to intercept calls to ASIOInit()\r
-//                  and ASIOExit(). We save the original ASIO global\r
-//                  "theAsioDriver" in our "that" variable, and then set\r
-//                  "theAsioDriver" to equal our IASIOThiscallResolver instance.\r
-//\r
-//                                     Whilst this method of resolving the thiscall problem requires\r
-//                                     the addition of #include <iasiothiscallresolver.h> to client\r
-//                  code it has the advantage that it does not break the terms\r
-//                  of the ASIO licence by publishing it. We are NOT modifying\r
-//                  any Steinberg code here, we are merely implementing the IASIO\r
-//                                     interface in the same way that we would need to do if we\r
-//                                     wished to provide an open source ASIO driver.\r
-//\r
-//                                     For compilation with MinGW -lole32 needs to be added to the\r
-//                  linker options. For BORLAND, linking with Import32.lib is\r
-//                  sufficient.\r
-//\r
-//                                     The dependencies are with: CoInitialize, CoUninitialize,\r
-//                                     CoCreateInstance, CLSIDFromString - used by asiolist.cpp\r
-//                                     and are required on Windows whether ThiscallResolver is used\r
-//                                     or not.\r
-//\r
-//                                     Searching for the above strings in the root library path\r
-//                                     of your compiler should enable the correct libraries to be\r
-//                                     identified if they aren't immediately obvious.\r
-//\r
-//                  Note that the current implementation of IASIOThiscallResolver\r
-//                  is not COM compliant - it does not correctly implement the\r
-//                  IUnknown interface. Implementing it is not necessary because\r
-//                  it is not called by parts of the ASIO SDK which call through\r
-//                  theAsioDriver ptr. The IUnknown methods are implemented as\r
-//                  assert(false) to ensure that the code fails if they are\r
-//                  ever called.\r
-// Restrictions:       None. Public Domain & Open Source distribute freely\r
-//                                     You may use IASIOThiscallResolver commercially as well as\r
-//                  privately.\r
-//                                     You the user assume the responsibility for the use of the\r
-//                                     files, binary or text, and there is no guarantee or warranty,\r
-//                                     expressed or implied, including but not limited to the\r
-//                                     implied warranties of merchantability and fitness for a\r
-//                                     particular purpose. You assume all responsibility and agree\r
-//                                     to hold no entity, copyright holder or distributors liable\r
-//                                     for any loss of data or inaccurate representations of data\r
-//                                     as a result of using IASIOThiscallResolver.\r
-// Version:         1.4 Added separate macro CALL_THISCALL_1_DOUBLE from\r
-//                  Andrew Baldwin, and volatile for whole gcc asm blocks,\r
-//                  both for compatibility with newer gcc versions. Cleaned up\r
-//                  Borland asm to use one less register.\r
-//                  1.3 Switched to including assert.h for better compatibility.\r
-//                  Wrapped entire .h and .cpp contents with a check for\r
-//                  _MSC_VER to provide better compatibility with MS compilers.\r
-//                  Changed Singleton implementation to use static instance\r
-//                  instead of freestore allocated instance. Removed ASIOExit\r
-//                  macro as it is no longer needed.\r
-//                  1.2 Removed semicolons from ASIOInit and ASIOExit macros to\r
-//                  allow them to be embedded in expressions (if statements).\r
-//                  Cleaned up some comments. Removed combase.c dependency (it\r
-//                  doesn't compile with BCB anyway) by stubbing IUnknown.\r
-//                  1.1 Incorporated comments from Ross Bencina including things\r
-//                                     such as changing name from ThiscallResolver to\r
-//                                     IASIOThiscallResolver, tidying up the constructor, fixing\r
-//                                     a bug in IASIOThiscallResolver::ASIOExit() and improving\r
-//                                     portability through the use of conditional compilation\r
-//                                     1.0 Initial working version.\r
-// Created:                    6/09/2003\r
-// Authors:         Fraser Adams\r
-//                  Ross Bencina\r
-//                  Rene G. Ceballos\r
-//                  Martin Fay\r
-//                  Antti Silvast\r
-//                  Andrew Baldwin\r
-//\r
-// ****************************************************************************\r
-\r
-\r
-#ifndef included_iasiothiscallresolver_h\r
-#define included_iasiothiscallresolver_h\r
-\r
-// We only need IASIOThiscallResolver at all if we are on Win32. For other\r
-// platforms we simply bypass the IASIOThiscallResolver definition to allow us\r
-// to be safely #include'd whatever the platform to keep client code portable\r
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)\r
-\r
-\r
-// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver\r
-// is not used.\r
-#if !defined(_MSC_VER)\r
-\r
-\r
-// The following is in order to ensure that this header is only included after\r
-// the other ASIO headers (except for the case of iasiothiscallresolver.cpp).\r
-// We need to do this because IASIOThiscallResolver works by eclipsing the\r
-// original definition of ASIOInit() with a macro (see below).\r
-#if !defined(iasiothiscallresolver_sourcefile)\r
-       #if !defined(__ASIO_H)\r
-       #error iasiothiscallresolver.h must be included AFTER asio.h\r
-       #endif\r
-#endif\r
-\r
-#include <windows.h>\r
-#include "iasiodrv.h" /* From ASIO SDK */\r
-\r
-\r
-class IASIOThiscallResolver : public IASIO {\r
-private:\r
-       IASIO* that_; // Points to the real IASIO\r
-\r
-       static IASIOThiscallResolver instance; // Singleton instance\r
-\r
-       // Constructors - declared private so construction is limited to\r
-    // our Singleton instance\r
-    IASIOThiscallResolver();\r
-       IASIOThiscallResolver(IASIO* that);\r
-public:\r
-\r
-    // Methods from the IUnknown interface. We don't fully implement IUnknown\r
-    // because the ASIO SDK never calls these methods through theAsioDriver ptr.\r
-    // These methods are implemented as assert(false).\r
-    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv);\r
-    virtual ULONG STDMETHODCALLTYPE AddRef();\r
-    virtual ULONG STDMETHODCALLTYPE Release();\r
-\r
-    // Methods from the IASIO interface, implemented as forwarning calls to that.\r
-       virtual ASIOBool init(void *sysHandle);\r
-       virtual void getDriverName(char *name);\r
-       virtual long getDriverVersion();\r
-       virtual void getErrorMessage(char *string);\r
-       virtual ASIOError start();\r
-       virtual ASIOError stop();\r
-       virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);\r
-       virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);\r
-       virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);\r
-       virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);\r
-       virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);\r
-       virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);\r
-       virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);\r
-       virtual ASIOError setClockSource(long reference);\r
-       virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp);\r
-       virtual ASIOError getChannelInfo(ASIOChannelInfo *info);\r
-       virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks);\r
-       virtual ASIOError disposeBuffers();\r
-       virtual ASIOError controlPanel();\r
-       virtual ASIOError future(long selector,void *opt);\r
-       virtual ASIOError outputReady();\r
-\r
-    // Class method, see ASIOInit() macro below.\r
-    static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit\r
-};\r
-\r
-\r
-// Replace calls to ASIOInit with our interposing version.\r
-// This macro enables us to perform thiscall resolution simply by #including\r
-// <iasiothiscallresolver.h> after the asio #includes (this file _must_ be\r
-// included _after_ the asio #includes)\r
-\r
-#define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name))\r
-\r
-\r
-#endif /* !defined(_MSC_VER) */\r
-\r
-#endif /* Win32 */\r
-\r
-#endif /* included_iasiothiscallresolver_h */\r
-\r
-\r
index e0fac8b2b82eff2fb9946a9a74888da4ec3162fe..5949a5e0884a901d32f1f76863e737be0af59264 100644 (file)
@@ -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 (file)
index 0000000..b241663
--- /dev/null
@@ -0,0 +1,257 @@
+/*\r
+       Steinberg Audio Stream I/O API\r
+       (c) 1996, Steinberg Soft- und Hardware GmbH\r
+\r
+       asio.cpp\r
+       \r
+       asio functions entries which translate the\r
+       asio interface to the asiodrvr class methods\r
+*/ \r
+       \r
+#include <string.h>\r
+#include "asiosys.h"           // platform definition\r
+#include "asio.h"\r
+\r
+#if MAC\r
+#include "asiodrvr.h"\r
+\r
+#pragma export on\r
+\r
+AsioDriver *theAsioDriver = 0;\r
+\r
+extern "C"\r
+{\r
+\r
+long main()\r
+{\r
+       return 'ASIO';\r
+}\r
+\r
+#elif WINDOWS\r
+\r
+#include "windows.h"\r
+#include "iasiodrv.h"\r
+#include "asiodrivers.h"\r
+\r
+IASIO *theAsioDriver = 0;\r
+extern AsioDrivers *asioDrivers;\r
+\r
+#elif SGI || SUN || BEOS || LINUX\r
+#include "asiodrvr.h"\r
+static AsioDriver *theAsioDriver = 0;\r
+#endif\r
+\r
+//-----------------------------------------------------------------------------------------------------\r
+ASIOError ASIOInit(ASIODriverInfo *info)\r
+{\r
+#if MAC || SGI || SUN || BEOS || LINUX\r
+       if(theAsioDriver)\r
+       {\r
+               delete theAsioDriver;\r
+               theAsioDriver = 0;\r
+       }               \r
+       info->driverVersion = 0;\r
+       strcpy(info->name, "No ASIO Driver");\r
+       theAsioDriver = getDriver();\r
+       if(!theAsioDriver)\r
+       {\r
+               strcpy(info->errorMessage, "Not enough memory for the ASIO driver!"); \r
+               return ASE_NotPresent;\r
+       }\r
+       if(!theAsioDriver->init(info->sysRef))\r
+       {\r
+               theAsioDriver->getErrorMessage(info->errorMessage);\r
+               delete theAsioDriver;\r
+               theAsioDriver = 0;\r
+               return ASE_NotPresent;\r
+       }\r
+       strcpy(info->errorMessage, "No ASIO Driver Error");\r
+       theAsioDriver->getDriverName(info->name);\r
+       info->driverVersion = theAsioDriver->getDriverVersion();\r
+       return ASE_OK;\r
+\r
+#else\r
+\r
+       info->driverVersion = 0;\r
+       strcpy(info->name, "No ASIO Driver");\r
+       if(theAsioDriver)       // must be loaded!\r
+       {\r
+               if(!theAsioDriver->init(info->sysRef))\r
+               {\r
+                       theAsioDriver->getErrorMessage(info->errorMessage);\r
+                       theAsioDriver = 0;\r
+                       return ASE_NotPresent;\r
+               }               \r
+\r
+               strcpy(info->errorMessage, "No ASIO Driver Error");\r
+               theAsioDriver->getDriverName(info->name);\r
+               info->driverVersion = theAsioDriver->getDriverVersion();\r
+               return ASE_OK;\r
+       }\r
+       return ASE_NotPresent;\r
+\r
+#endif // !MAC\r
+}\r
+\r
+ASIOError ASIOExit(void)\r
+{\r
+       if(theAsioDriver)\r
+       {\r
+#if WINDOWS\r
+               asioDrivers->removeCurrentDriver();\r
+#else\r
+               delete theAsioDriver;\r
+#endif\r
+       }               \r
+       theAsioDriver = 0;\r
+       return ASE_OK;\r
+}\r
+\r
+ASIOError ASIOStart(void)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->start();\r
+}\r
+\r
+ASIOError ASIOStop(void)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->stop();\r
+}\r
+\r
+ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels)\r
+{\r
+       if(!theAsioDriver)\r
+       {\r
+               *numInputChannels = *numOutputChannels = 0;\r
+               return ASE_NotPresent;\r
+       }\r
+       return theAsioDriver->getChannels(numInputChannels, numOutputChannels);\r
+}\r
+\r
+ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency)\r
+{\r
+       if(!theAsioDriver)\r
+       {\r
+               *inputLatency = *outputLatency = 0;\r
+               return ASE_NotPresent;\r
+       }\r
+       return theAsioDriver->getLatencies(inputLatency, outputLatency);\r
+}\r
+\r
+ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity)\r
+{\r
+       if(!theAsioDriver)\r
+       {\r
+               *minSize = *maxSize = *preferredSize = *granularity = 0;\r
+               return ASE_NotPresent;\r
+       }\r
+       return theAsioDriver->getBufferSize(minSize, maxSize, preferredSize, granularity);\r
+}\r
+\r
+ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->canSampleRate(sampleRate);\r
+}\r
+\r
+ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->getSampleRate(currentRate);\r
+}\r
+\r
+ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->setSampleRate(sampleRate);\r
+}\r
+\r
+ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources)\r
+{\r
+       if(!theAsioDriver)\r
+       {\r
+               *numSources = 0;\r
+               return ASE_NotPresent;\r
+       }\r
+       return theAsioDriver->getClockSources(clocks, numSources);\r
+}\r
+\r
+ASIOError ASIOSetClockSource(long reference)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->setClockSource(reference);\r
+}\r
+\r
+ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->getSamplePosition(sPos, tStamp);\r
+}\r
+\r
+ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info)\r
+{\r
+       if(!theAsioDriver)\r
+       {\r
+               info->channelGroup = -1;\r
+               info->type = ASIOSTInt16MSB;\r
+               strcpy(info->name, "None");\r
+               return ASE_NotPresent;\r
+       }\r
+       return theAsioDriver->getChannelInfo(info);\r
+}\r
+\r
+ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
+       long bufferSize, ASIOCallbacks *callbacks)\r
+{\r
+       if(!theAsioDriver)\r
+       {\r
+               ASIOBufferInfo *info = bufferInfos;\r
+               for(long i = 0; i < numChannels; i++, info++)\r
+                       info->buffers[0] = info->buffers[1] = 0;\r
+               return ASE_NotPresent;\r
+       }\r
+       return theAsioDriver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks);\r
+}\r
+\r
+ASIOError ASIODisposeBuffers(void)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->disposeBuffers();\r
+}\r
+\r
+ASIOError ASIOControlPanel(void)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->controlPanel();\r
+}\r
+\r
+ASIOError ASIOFuture(long selector, void *opt)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->future(selector, opt);\r
+}\r
+\r
+ASIOError ASIOOutputReady(void)\r
+{\r
+       if(!theAsioDriver)\r
+               return ASE_NotPresent;\r
+       return theAsioDriver->outputReady();\r
+}\r
+\r
+#if MAC\r
+}      // extern "C"\r
+#pragma export off\r
+#endif\r
+\r
+\r
diff --git a/include/asio.h b/include/asio.h
new file mode 100644 (file)
index 0000000..8ec811f
--- /dev/null
@@ -0,0 +1,1054 @@
+//---------------------------------------------------------------------------------------------------\r
+//---------------------------------------------------------------------------------------------------\r
+\r
+/*\r
+       Steinberg Audio Stream I/O API\r
+       (c) 1997 - 2005, Steinberg Media Technologies GmbH\r
+\r
+       ASIO Interface Specification v 2.1\r
+\r
+       2005 - Added support for DSD sample data (in cooperation with Sony)\r
+\r
+\r
+       basic concept is an i/o synchronous double-buffer scheme:\r
+       \r
+       on bufferSwitch(index == 0), host will read/write:\r
+\r
+               after ASIOStart(), the\r
+  read  first input buffer A (index 0)\r
+       |   will be invalid (empty)\r
+       *   ------------------------\r
+       |------------------------|-----------------------|\r
+       |                        |                       |\r
+       |  Input Buffer A (0)    |   Input Buffer B (1)  |\r
+       |                        |                       |\r
+       |------------------------|-----------------------|\r
+       |                        |                       |\r
+       |  Output Buffer A (0)   |   Output Buffer B (1) |\r
+       |                        |                       |\r
+       |------------------------|-----------------------|\r
+       *                        -------------------------\r
+       |                        before calling ASIOStart(),\r
+  write                      host will have filled output\r
+                             buffer B (index 1) already\r
+\r
+  *please* take special care of proper statement of input\r
+  and output latencies (see ASIOGetLatencies()), these\r
+  control sequencer sync accuracy\r
+\r
+*/\r
+\r
+//---------------------------------------------------------------------------------------------------\r
+//---------------------------------------------------------------------------------------------------\r
+\r
+/*\r
+\r
+prototypes summary:\r
+\r
+ASIOError ASIOInit(ASIODriverInfo *info);\r
+ASIOError ASIOExit(void);\r
+ASIOError ASIOStart(void);\r
+ASIOError ASIOStop(void);\r
+ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels);\r
+ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);\r
+ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);\r
+ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate);\r
+ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate);\r
+ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate);\r
+ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);\r
+ASIOError ASIOSetClockSource(long reference);\r
+ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);\r
+ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);\r
+ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
+       long bufferSize, ASIOCallbacks *callbacks);\r
+ASIOError ASIODisposeBuffers(void);\r
+ASIOError ASIOControlPanel(void);\r
+void *ASIOFuture(long selector, void *params);\r
+ASIOError ASIOOutputReady(void);\r
+\r
+*/\r
+\r
+//---------------------------------------------------------------------------------------------------\r
+//---------------------------------------------------------------------------------------------------\r
+\r
+#ifndef __ASIO_H\r
+#define __ASIO_H\r
+\r
+// force 4 byte alignment\r
+#if defined(_MSC_VER) && !defined(__MWERKS__) \r
+#pragma pack(push,4)\r
+#elif PRAGMA_ALIGN_SUPPORTED\r
+#pragma options align = native\r
+#endif\r
+\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+// Type definitions\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+\r
+// number of samples data type is 64 bit integer\r
+#if NATIVE_INT64\r
+       typedef long long int ASIOSamples;\r
+#else\r
+       typedef struct ASIOSamples {\r
+               unsigned long hi;\r
+               unsigned long lo;\r
+       } ASIOSamples;\r
+#endif\r
+\r
+// Timestamp data type is 64 bit integer,\r
+// Time format is Nanoseconds.\r
+#if NATIVE_INT64\r
+       typedef long long int ASIOTimeStamp ;\r
+#else\r
+       typedef struct ASIOTimeStamp {\r
+               unsigned long hi;\r
+               unsigned long lo;\r
+       } ASIOTimeStamp;\r
+#endif\r
+\r
+// Samplerates are expressed in IEEE 754 64 bit double float,\r
+// native format as host computer\r
+#if IEEE754_64FLOAT\r
+       typedef double ASIOSampleRate;\r
+#else\r
+       typedef struct ASIOSampleRate {\r
+               char ieee[8];\r
+       } ASIOSampleRate;\r
+#endif\r
+\r
+// Boolean values are expressed as long\r
+typedef long ASIOBool;\r
+enum {\r
+       ASIOFalse = 0,\r
+       ASIOTrue = 1\r
+};\r
+\r
+// Sample Types are expressed as long\r
+typedef long ASIOSampleType;\r
+enum {\r
+       ASIOSTInt16MSB   = 0,\r
+       ASIOSTInt24MSB   = 1,           // used for 20 bits as well\r
+       ASIOSTInt32MSB   = 2,\r
+       ASIOSTFloat32MSB = 3,           // IEEE 754 32 bit float\r
+       ASIOSTFloat64MSB = 4,           // IEEE 754 64 bit double float\r
+\r
+       // these are used for 32 bit data buffer, with different alignment of the data inside\r
+       // 32 bit PCI bus systems can be more easily used with these\r
+       ASIOSTInt32MSB16 = 8,           // 32 bit data with 16 bit alignment\r
+       ASIOSTInt32MSB18 = 9,           // 32 bit data with 18 bit alignment\r
+       ASIOSTInt32MSB20 = 10,          // 32 bit data with 20 bit alignment\r
+       ASIOSTInt32MSB24 = 11,          // 32 bit data with 24 bit alignment\r
+       \r
+       ASIOSTInt16LSB   = 16,\r
+       ASIOSTInt24LSB   = 17,          // used for 20 bits as well\r
+       ASIOSTInt32LSB   = 18,\r
+       ASIOSTFloat32LSB = 19,          // IEEE 754 32 bit float, as found on Intel x86 architecture\r
+       ASIOSTFloat64LSB = 20,          // IEEE 754 64 bit double float, as found on Intel x86 architecture\r
+\r
+       // these are used for 32 bit data buffer, with different alignment of the data inside\r
+       // 32 bit PCI bus systems can more easily used with these\r
+       ASIOSTInt32LSB16 = 24,          // 32 bit data with 18 bit alignment\r
+       ASIOSTInt32LSB18 = 25,          // 32 bit data with 18 bit alignment\r
+       ASIOSTInt32LSB20 = 26,          // 32 bit data with 20 bit alignment\r
+       ASIOSTInt32LSB24 = 27,          // 32 bit data with 24 bit alignment\r
+\r
+       //      ASIO DSD format.\r
+       ASIOSTDSDInt8LSB1   = 32,               // DSD 1 bit data, 8 samples per byte. First sample in Least significant bit.\r
+       ASIOSTDSDInt8MSB1   = 33,               // DSD 1 bit data, 8 samples per byte. First sample in Most significant bit.\r
+       ASIOSTDSDInt8NER8       = 40,           // DSD 8 bit data, 1 sample per byte. No Endianness required.\r
+\r
+       ASIOSTLastEntry\r
+};\r
+\r
+/*-----------------------------------------------------------------------------\r
+// DSD operation and buffer layout\r
+// Definition by Steinberg/Sony Oxford.\r
+//\r
+// We have tried to treat DSD as PCM and so keep a consistant structure across\r
+// the ASIO interface.\r
+//\r
+// DSD's sample rate is normally referenced as a multiple of 44.1Khz, so\r
+// the standard sample rate is refered to as 64Fs (or 2.8224Mhz). We looked\r
+// at making a special case for DSD and adding a field to the ASIOFuture that\r
+// would allow the user to select the Over Sampleing Rate (OSR) as a seperate\r
+// entity but decided in the end just to treat it as a simple value of\r
+// 2.8224Mhz and use the standard interface to set it.\r
+//\r
+// The second problem was the "word" size, in PCM the word size is always a\r
+// greater than or equal to 8 bits (a byte). This makes life easy as we can\r
+// then pack the samples into the "natural" size for the machine.\r
+// In DSD the "word" size is 1 bit. This is not a major problem and can easily\r
+// be dealt with if we ensure that we always deal with a multiple of 8 samples.\r
+//\r
+// DSD brings with it another twist to the Endianness religion. How are the\r
+// samples packed into the byte. It would be nice to just say the most significant\r
+// bit is always the first sample, however there would then be a performance hit\r
+// on little endian machines. Looking at how some of the processing goes...\r
+// Little endian machines like the first sample to be in the Least Significant Bit,\r
+//   this is because when you write it to memory the data is in the correct format\r
+//   to be shifted in and out of the words.\r
+// Big endian machine prefer the first sample to be in the Most Significant Bit,\r
+//   again for the same reasion.\r
+//\r
+// And just when things were looking really muddy there is a proposed extension to\r
+// DSD that uses 8 bit word sizes. It does not care what endianness you use.\r
+//\r
+// Switching the driver between DSD and PCM mode\r
+// ASIOFuture allows for extending the ASIO API quite transparently.\r
+// See kAsioSetIoFormat, kAsioGetIoFormat, kAsioCanDoIoFormat\r
+//\r
+//-----------------------------------------------------------------------------*/\r
+\r
+\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+// Error codes\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+\r
+typedef long ASIOError;\r
+enum {\r
+       ASE_OK = 0,             // This value will be returned whenever the call succeeded\r
+       ASE_SUCCESS = 0x3f4847a0,       // unique success return value for ASIOFuture calls\r
+       ASE_NotPresent = -1000, // hardware input or output is not present or available\r
+       ASE_HWMalfunction,      // hardware is malfunctioning (can be returned by any ASIO function)\r
+       ASE_InvalidParameter,   // input parameter invalid\r
+       ASE_InvalidMode,        // hardware is in a bad mode or used in a bad mode\r
+       ASE_SPNotAdvancing,     // hardware is not running when sample position is inquired\r
+       ASE_NoClock,            // sample clock or rate cannot be determined or is not present\r
+       ASE_NoMemory            // not enough memory for completing the request\r
+};\r
+\r
+//---------------------------------------------------------------------------------------------------\r
+//---------------------------------------------------------------------------------------------------\r
+\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+// Time Info support\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+\r
+typedef struct ASIOTimeCode\r
+{       \r
+       double          speed;                  // speed relation (fraction of nominal speed)\r
+                                               // optional; set to 0. or 1. if not supported\r
+       ASIOSamples     timeCodeSamples;        // time in samples\r
+       unsigned long   flags;                  // some information flags (see below)\r
+       char future[64];\r
+} ASIOTimeCode;\r
+\r
+typedef enum ASIOTimeCodeFlags\r
+{\r
+       kTcValid                = 1,\r
+       kTcRunning              = 1 << 1,\r
+       kTcReverse              = 1 << 2,\r
+       kTcOnspeed              = 1 << 3,\r
+       kTcStill                = 1 << 4,\r
+       \r
+       kTcSpeedValid           = 1 << 8\r
+}  ASIOTimeCodeFlags;\r
+\r
+typedef struct AsioTimeInfo\r
+{\r
+       double          speed;                  // absolute speed (1. = nominal)\r
+       ASIOTimeStamp   systemTime;             // system time related to samplePosition, in nanoseconds\r
+                                               // on mac, must be derived from Microseconds() (not UpTime()!)\r
+                                               // on windows, must be derived from timeGetTime()\r
+       ASIOSamples     samplePosition;\r
+       ASIOSampleRate  sampleRate;             // current rate\r
+       unsigned long flags;                    // (see below)\r
+       char reserved[12];\r
+} AsioTimeInfo;\r
+\r
+typedef enum AsioTimeInfoFlags\r
+{\r
+       kSystemTimeValid        = 1,            // must always be valid\r
+       kSamplePositionValid    = 1 << 1,       // must always be valid\r
+       kSampleRateValid        = 1 << 2,\r
+       kSpeedValid             = 1 << 3,\r
+       \r
+       kSampleRateChanged      = 1 << 4,\r
+       kClockSourceChanged     = 1 << 5\r
+} AsioTimeInfoFlags;\r
+\r
+typedef struct ASIOTime                          // both input/output\r
+{\r
+       long reserved[4];                       // must be 0\r
+       struct AsioTimeInfo     timeInfo;       // required\r
+       struct ASIOTimeCode     timeCode;       // optional, evaluated if (timeCode.flags & kTcValid)\r
+} ASIOTime;\r
+\r
+/*\r
+\r
+using time info:\r
+it is recommended to use the new method with time info even if the asio\r
+device does not support timecode; continuous calls to ASIOGetSamplePosition\r
+and ASIOGetSampleRate are avoided, and there is a more defined relationship\r
+between callback time and the time info.\r
+\r
+see the example below.\r
+to initiate time info mode, after you have received the callbacks pointer in\r
+ASIOCreateBuffers, you will call the asioMessage callback with kAsioSupportsTimeInfo\r
+as the argument. if this returns 1, host has accepted time info mode.\r
+now host expects the new callback bufferSwitchTimeInfo to be used instead\r
+of the old bufferSwitch method. the ASIOTime structure is assumed to be valid\r
+and accessible until the callback returns.\r
+\r
+using time code:\r
+if the device supports reading time code, it will call host's asioMessage callback\r
+with kAsioSupportsTimeCode as the selector. it may then fill the according\r
+fields and set the kTcValid flag.\r
+host will call the future method with the kAsioEnableTimeCodeRead selector when\r
+it wants to enable or disable tc reading by the device. you should also support\r
+the kAsioCanTimeInfo and kAsioCanTimeCode selectors in ASIOFuture (see example).\r
+\r
+note:\r
+the AsioTimeInfo/ASIOTimeCode pair is supposed to work in both directions.\r
+as a matter of convention, the relationship between the sample\r
+position counter and the time code at buffer switch time is\r
+(ignoring offset between tc and sample pos when tc is running):\r
+\r
+on input:      sample 0 -> input  buffer sample 0 -> time code 0\r
+on output:     sample 0 -> output buffer sample 0 -> time code 0\r
+\r
+this means that for 'real' calculations, one has to take into account\r
+the according latencies.\r
+\r
+example:\r
+\r
+ASIOTime asioTime;\r
+\r
+in createBuffers()\r
+{\r
+       memset(&asioTime, 0, sizeof(ASIOTime));\r
+       AsioTimeInfo* ti = &asioTime.timeInfo;\r
+       ti->sampleRate = theSampleRate;\r
+       ASIOTimeCode* tc = &asioTime.timeCode;\r
+       tc->speed = 1.;\r
+       timeInfoMode = false;\r
+       canTimeCode = false;\r
+       if(callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0) == 1)\r
+       {\r
+               timeInfoMode = true;\r
+#if kCanTimeCode\r
+               if(callbacks->asioMessage(kAsioSupportsTimeCode, 0, 0, 0) == 1)\r
+                       canTimeCode = true;\r
+#endif\r
+       }\r
+}\r
+\r
+void switchBuffers(long doubleBufferIndex, bool processNow)\r
+{\r
+       if(timeInfoMode)\r
+       {\r
+               AsioTimeInfo* ti = &asioTime.timeInfo;\r
+               ti->flags =     kSystemTimeValid | kSamplePositionValid | kSampleRateValid;\r
+               ti->systemTime = theNanoSeconds;\r
+               ti->samplePosition = theSamplePosition;\r
+               if(ti->sampleRate != theSampleRate)\r
+                       ti->flags |= kSampleRateChanged;\r
+               ti->sampleRate = theSampleRate;\r
+\r
+#if kCanTimeCode\r
+               if(canTimeCode && timeCodeEnabled)\r
+               {\r
+                       ASIOTimeCode* tc = &asioTime.timeCode;\r
+                       tc->timeCodeSamples = tcSamples;                                                // tc in samples\r
+                       tc->flags = kTcValid | kTcRunning | kTcOnspeed;                 // if so...\r
+               }\r
+               ASIOTime* bb = callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse);\r
+#else\r
+               callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse);\r
+#endif\r
+       }\r
+       else\r
+               callbacks->bufferSwitch(doubleBufferIndex, ASIOFalse);\r
+}\r
+\r
+ASIOError ASIOFuture(long selector, void *params)\r
+{\r
+       switch(selector)\r
+       {\r
+               case kAsioEnableTimeCodeRead:\r
+                       timeCodeEnabled = true;\r
+                       return ASE_SUCCESS;\r
+               case kAsioDisableTimeCodeRead:\r
+                       timeCodeEnabled = false;\r
+                       return ASE_SUCCESS;\r
+               case kAsioCanTimeInfo:\r
+                       return ASE_SUCCESS;\r
+               #if kCanTimeCode\r
+               case kAsioCanTimeCode:\r
+                       return ASE_SUCCESS;\r
+               #endif\r
+       }\r
+       return ASE_NotPresent;\r
+};\r
+\r
+*/\r
+\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+// application's audio stream handler callbacks\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+\r
+typedef struct ASIOCallbacks\r
+{\r
+       void (*bufferSwitch) (long doubleBufferIndex, ASIOBool directProcess);\r
+               // bufferSwitch indicates that both input and output are to be processed.\r
+               // the current buffer half index (0 for A, 1 for B) determines\r
+               // - the output buffer that the host should start to fill. the other buffer\r
+               //   will be passed to output hardware regardless of whether it got filled\r
+               //   in time or not.\r
+               // - the input buffer that is now filled with incoming data. Note that\r
+               //   because of the synchronicity of i/o, the input always has at\r
+               //   least one buffer latency in relation to the output.\r
+               // directProcess suggests to the host whether it should immedeately\r
+               // start processing (directProcess == ASIOTrue), or whether its process\r
+               // should be deferred because the call comes from a very low level\r
+               // (for instance, a high level priority interrupt), and direct processing\r
+               // would cause timing instabilities for the rest of the system. If in doubt,\r
+               // directProcess should be set to ASIOFalse.\r
+               // Note: bufferSwitch may be called at interrupt time for highest efficiency.\r
+\r
+       void (*sampleRateDidChange) (ASIOSampleRate sRate);\r
+               // gets called when the AudioStreamIO detects a sample rate change\r
+               // If sample rate is unknown, 0 is passed (for instance, clock loss\r
+               // when externally synchronized).\r
+\r
+       long (*asioMessage) (long selector, long value, void* message, double* opt);\r
+               // generic callback for various purposes, see selectors below.\r
+               // note this is only present if the asio version is 2 or higher\r
+\r
+       ASIOTime* (*bufferSwitchTimeInfo) (ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess);\r
+               // new callback with time info. makes ASIOGetSamplePosition() and various\r
+               // calls to ASIOGetSampleRate obsolete,\r
+               // and allows for timecode sync etc. to be preferred; will be used if\r
+               // the driver calls asioMessage with selector kAsioSupportsTimeInfo.\r
+} ASIOCallbacks;\r
+\r
+// asioMessage selectors\r
+enum\r
+{\r
+       kAsioSelectorSupported = 1,     // selector in <value>, returns 1L if supported,\r
+                                                               // 0 otherwise\r
+    kAsioEngineVersion,                        // returns engine (host) asio implementation version,\r
+                                                               // 2 or higher\r
+       kAsioResetRequest,                      // request driver reset. if accepted, this\r
+                                                               // will close the driver (ASIO_Exit() ) and\r
+                                                               // re-open it again (ASIO_Init() etc). some\r
+                                                               // drivers need to reconfigure for instance\r
+                                                               // when the sample rate changes, or some basic\r
+                                                               // changes have been made in ASIO_ControlPanel().\r
+                                                               // returns 1L; note the request is merely passed\r
+                                                               // to the application, there is no way to determine\r
+                                                               // if it gets accepted at this time (but it usually\r
+                                                               // will be).\r
+       kAsioBufferSizeChange,          // not yet supported, will currently always return 0L.\r
+                                                               // for now, use kAsioResetRequest instead.\r
+                                                               // once implemented, the new buffer size is expected\r
+                                                               // in <value>, and on success returns 1L\r
+       kAsioResyncRequest,                     // the driver went out of sync, such that\r
+                                                               // the timestamp is no longer valid. this\r
+                                                               // is a request to re-start the engine and\r
+                                                               // slave devices (sequencer). returns 1 for ok,\r
+                                                               // 0 if not supported.\r
+       kAsioLatenciesChanged,          // the drivers latencies have changed. The engine\r
+                                                               // will refetch the latencies.\r
+       kAsioSupportsTimeInfo,          // if host returns true here, it will expect the\r
+                                                               // callback bufferSwitchTimeInfo to be called instead\r
+                                                               // of bufferSwitch\r
+       kAsioSupportsTimeCode,          // \r
+       kAsioMMCCommand,                        // unused - value: number of commands, message points to mmc commands\r
+       kAsioSupportsInputMonitor,      // kAsioSupportsXXX return 1 if host supports this\r
+       kAsioSupportsInputGain,     // unused and undefined\r
+       kAsioSupportsInputMeter,    // unused and undefined\r
+       kAsioSupportsOutputGain,    // unused and undefined\r
+       kAsioSupportsOutputMeter,   // unused and undefined\r
+       kAsioOverload,              // driver detected an overload\r
+\r
+       kAsioNumMessageSelectors\r
+};\r
+\r
+//---------------------------------------------------------------------------------------------------\r
+//---------------------------------------------------------------------------------------------------\r
+\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+// (De-)Construction\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+\r
+typedef struct ASIODriverInfo\r
+{\r
+       long asioVersion;               // currently, 2\r
+       long driverVersion;             // driver specific\r
+       char name[32];\r
+       char errorMessage[124];\r
+       void *sysRef;                   // on input: system reference\r
+                                                       // (Windows: application main window handle, Mac & SGI: 0)\r
+} ASIODriverInfo;\r
+\r
+ASIOError ASIOInit(ASIODriverInfo *info);\r
+/* Purpose:\r
+         Initialize the AudioStreamIO.\r
+       Parameter:\r
+         info: pointer to an ASIODriver structure:\r
+           - asioVersion:\r
+                       - on input, the host version. *** Note *** this is 0 for earlier asio\r
+                       implementations, and the asioMessage callback is implemeted\r
+                       only if asioVersion is 2 or greater. sorry but due to a design fault\r
+                       the driver doesn't have access to the host version in ASIOInit :-(\r
+                       added selector for host (engine) version in the asioMessage callback\r
+                       so we're ok from now on.\r
+                       - on return, asio implementation version.\r
+                         older versions are 1\r
+                         if you support this version (namely, ASIO_outputReady() )\r
+                         this should be 2 or higher. also see the note in\r
+                         ASIO_getTimeStamp() !\r
+           - version: on return, the driver version (format is driver specific)\r
+           - name: on return, a null-terminated string containing the driver's name\r
+               - error message: on return, should contain a user message describing\r
+                 the type of error that occured during ASIOInit(), if any.\r
+               - sysRef: platform specific\r
+       Returns:\r
+         If neither input nor output is present ASE_NotPresent\r
+         will be returned.\r
+         ASE_NoMemory, ASE_HWMalfunction are other possible error conditions\r
+*/\r
+\r
+ASIOError ASIOExit(void);\r
+/* Purpose:\r
+         Terminates the AudioStreamIO.\r
+       Parameter:\r
+         None.\r
+       Returns:\r
+         If neither input nor output is present ASE_NotPresent\r
+         will be returned.\r
+       Notes: this implies ASIOStop() and ASIODisposeBuffers(),\r
+         meaning that no host callbacks must be accessed after ASIOExit().\r
+*/\r
+\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+// Start/Stop\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+\r
+ASIOError ASIOStart(void);\r
+/* Purpose:\r
+         Start input and output processing synchronously.\r
+         This will\r
+         - reset the sample counter to zero\r
+         - start the hardware (both input and output)\r
+           The first call to the hosts' bufferSwitch(index == 0) then tells\r
+           the host to read from input buffer A (index 0), and start\r
+           processing to output buffer A while output buffer B (which\r
+           has been filled by the host prior to calling ASIOStart())\r
+           is possibly sounding (see also ASIOGetLatencies()) \r
+       Parameter:\r
+         None.\r
+       Returns:\r
+         If neither input nor output is present, ASE_NotPresent\r
+         will be returned.\r
+         If the hardware fails to start, ASE_HWMalfunction will be returned.\r
+       Notes:\r
+         There is no restriction on the time that ASIOStart() takes\r
+         to perform (that is, it is not considered a realtime trigger).\r
+*/\r
+\r
+ASIOError ASIOStop(void);\r
+/* Purpose:\r
+         Stops input and output processing altogether.\r
+       Parameter:\r
+         None.\r
+       Returns:\r
+         If neither input nor output is present ASE_NotPresent\r
+         will be returned.\r
+       Notes:\r
+         On return from ASIOStop(), the driver must in no\r
+         case call the hosts' bufferSwitch() routine.\r
+*/\r
+\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+// Inquiry methods and sample rate\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+\r
+ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels);\r
+/* Purpose:\r
+         Returns number of individual input/output channels.\r
+       Parameter:\r
+         numInputChannels will hold the number of available input channels\r
+         numOutputChannels will hold the number of available output channels\r
+       Returns:\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+         If only inputs, or only outputs are available, the according\r
+         other parameter will be zero, and ASE_OK is returned.\r
+*/\r
+\r
+ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);\r
+/* Purpose:\r
+         Returns the input and output latencies. This includes\r
+         device specific delays, like FIFOs etc.\r
+       Parameter:\r
+         inputLatency will hold the 'age' of the first sample frame\r
+         in the input buffer when the hosts reads it in bufferSwitch()\r
+         (this is theoretical, meaning it does not include the overhead\r
+         and delay between the actual physical switch, and the time\r
+         when bufferSitch() enters).\r
+         This will usually be the size of one block in sample frames, plus\r
+         device specific latencies.\r
+\r
+         outputLatency will specify the time between the buffer switch,\r
+         and the time when the next play buffer will start to sound.\r
+         The next play buffer is defined as the one the host starts\r
+         processing after (or at) bufferSwitch(), indicated by the\r
+         index parameter (0 for buffer A, 1 for buffer B).\r
+         It will usually be either one block, if the host writes directly\r
+         to a dma buffer, or two or more blocks if the buffer is 'latched' by\r
+         the driver. As an example, on ASIOStart(), the host will have filled\r
+         the play buffer at index 1 already; when it gets the callback (with\r
+         the parameter index == 0), this tells it to read from the input\r
+         buffer 0, and start to fill the play buffer 0 (assuming that now\r
+         play buffer 1 is already sounding). In this case, the output\r
+         latency is one block. If the driver decides to copy buffer 1\r
+         at that time, and pass it to the hardware at the next slot (which\r
+         is most commonly done, but should be avoided), the output latency\r
+         becomes two blocks instead, resulting in a total i/o latency of at least\r
+         3 blocks. As memory access is the main bottleneck in native dsp processing,\r
+         and to acheive less latency, it is highly recommended to try to avoid\r
+         copying (this is also why the driver is the owner of the buffers). To\r
+         summarize, the minimum i/o latency can be acheived if the input buffer\r
+         is processed by the host into the output buffer which will physically\r
+         start to sound on the next time slice. Also note that the host expects\r
+         the bufferSwitch() callback to be accessed for each time slice in order\r
+         to retain sync, possibly recursively; if it fails to process a block in\r
+         time, it will suspend its operation for some time in order to recover.\r
+       Returns:\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+*/\r
+\r
+ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);\r
+/* Purpose:\r
+         Returns min, max, and preferred buffer sizes for input/output\r
+       Parameter:\r
+         minSize will hold the minimum buffer size\r
+         maxSize will hold the maxium possible buffer size\r
+         preferredSize will hold the preferred buffer size (a size which\r
+         best fits performance and hardware requirements)\r
+         granularity will hold the granularity at which buffer sizes\r
+         may differ. Usually, the buffer size will be a power of 2;\r
+         in this case, granularity will hold -1 on return, signalling\r
+         possible buffer sizes starting from minSize, increased in\r
+         powers of 2 up to maxSize.\r
+       Returns:\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+       Notes:\r
+         When minimum and maximum buffer size are equal,\r
+         the preferred buffer size has to be the same value as well; granularity\r
+         should be 0 in this case.\r
+*/\r
+\r
+ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate);\r
+/* Purpose:\r
+         Inquires the hardware for the available sample rates.\r
+       Parameter:\r
+         sampleRate is the rate in question.\r
+       Returns:\r
+         If the inquired sample rate is not supported, ASE_NoClock will be returned.\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+*/\r
+ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate);\r
+/* Purpose:\r
+         Get the current sample Rate.\r
+       Parameter:\r
+         currentRate will hold the current sample rate on return.\r
+       Returns:\r
+         If sample rate is unknown, sampleRate will be 0 and ASE_NoClock will be returned.\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+       Notes:\r
+*/\r
+\r
+ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate);\r
+/* Purpose:\r
+         Set the hardware to the requested sample Rate. If sampleRate == 0,\r
+         enable external sync.\r
+       Parameter:\r
+         sampleRate: on input, the requested rate\r
+       Returns:\r
+         If sampleRate is unknown ASE_NoClock will be returned.\r
+         If the current clock is external, and sampleRate is != 0,\r
+         ASE_InvalidMode will be returned\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+       Notes:\r
+*/\r
+\r
+typedef struct ASIOClockSource\r
+{\r
+       long index;                                     // as used for ASIOSetClockSource()\r
+       long associatedChannel;         // for instance, S/PDIF or AES/EBU\r
+       long associatedGroup;           // see channel groups (ASIOGetChannelInfo())\r
+       ASIOBool isCurrentSource;       // ASIOTrue if this is the current clock source\r
+       char name[32];                          // for user selection\r
+} ASIOClockSource;\r
+\r
+ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);\r
+/* Purpose:\r
+         Get the available external audio clock sources\r
+       Parameter:\r
+         clocks points to an array of ASIOClockSource structures:\r
+               - index: this is used to identify the clock source\r
+                 when ASIOSetClockSource() is accessed, should be\r
+                 an index counting from zero\r
+               - associatedInputChannel: the first channel of an associated\r
+                 input group, if any.\r
+               - associatedGroup: the group index of that channel.\r
+                 groups of channels are defined to seperate for\r
+                 instance analog, S/PDIF, AES/EBU, ADAT connectors etc,\r
+                 when present simultaniously. Note that associated channel\r
+                 is enumerated according to numInputs/numOutputs, means it\r
+                 is independant from a group (see also ASIOGetChannelInfo())\r
+                 inputs are associated to a clock if the physical connection\r
+                 transfers both data and clock (like S/PDIF, AES/EBU, or\r
+                 ADAT inputs). if there is no input channel associated with\r
+                 the clock source (like Word Clock, or internal oscillator), both\r
+                 associatedChannel and associatedGroup should be set to -1.\r
+               - isCurrentSource: on exit, ASIOTrue if this is the current clock\r
+                 source, ASIOFalse else\r
+               - name: a null-terminated string for user selection of the available sources.\r
+         numSources:\r
+             on input: the number of allocated array members\r
+             on output: the number of available clock sources, at least\r
+             1 (internal clock generator).\r
+       Returns:\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+       Notes:\r
+*/\r
+\r
+ASIOError ASIOSetClockSource(long index);\r
+/* Purpose:\r
+         Set the audio clock source\r
+       Parameter:\r
+         index as obtained from an inquiry to ASIOGetClockSources()\r
+       Returns:\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+         If the clock can not be selected because an input channel which\r
+         carries the current clock source is active, ASE_InvalidMode\r
+         *may* be returned (this depends on the properties of the driver\r
+         and/or hardware).\r
+       Notes:\r
+         Should *not* return ASE_NoClock if there is no clock signal present\r
+         at the selected source; this will be inquired via ASIOGetSampleRate().\r
+         It should call the host callback procedure sampleRateHasChanged(),\r
+         if the switch causes a sample rate change, or if no external clock\r
+         is present at the selected source.\r
+*/\r
+\r
+ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);\r
+/* Purpose:\r
+         Inquires the sample position/time stamp pair.\r
+       Parameter:\r
+         sPos will hold the sample position on return. The sample\r
+         position is reset to zero when ASIOStart() gets called.\r
+         tStamp will hold the system time when the sample position\r
+         was latched.\r
+       Returns:\r
+         If no input/output is present, ASE_NotPresent will be returned.\r
+         If there is no clock, ASE_SPNotAdvancing will be returned.\r
+       Notes:\r
+\r
+         in order to be able to synchronise properly,\r
+         the sample position / time stamp pair must refer to the current block,\r
+         that is, the engine will call ASIOGetSamplePosition() in its bufferSwitch()\r
+         callback and expect the time for the current block. thus, when requested\r
+         in the very first bufferSwitch after ASIO_Start(), the sample position\r
+         should be zero, and the time stamp should refer to the very time where\r
+         the stream was started. it also means that the sample position must be\r
+         block aligned. the driver must ensure proper interpolation if the system\r
+         time can not be determined for the block position. the driver is responsible\r
+         for precise time stamps as it usually has most direct access to lower\r
+         level resources. proper behaviour of ASIO_GetSamplePosition() and ASIO_GetLatencies()\r
+         are essential for precise media synchronization!\r
+*/\r
+\r
+typedef struct ASIOChannelInfo\r
+{\r
+       long channel;                   // on input, channel index\r
+       ASIOBool isInput;               // on input\r
+       ASIOBool isActive;              // on exit\r
+       long channelGroup;              // dto\r
+       ASIOSampleType type;    // dto\r
+       char name[32];                  // dto\r
+} ASIOChannelInfo;\r
+\r
+ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);\r
+/* Purpose:\r
+         retreive information about the nature of a channel\r
+       Parameter:\r
+         info: pointer to a ASIOChannelInfo structure with\r
+               - channel: on input, the channel index of the channel in question.\r
+               - isInput: on input, ASIOTrue if info for an input channel is\r
+                 requested, else output\r
+               - channelGroup: on return, the channel group that the channel\r
+                 belongs to. For drivers which support different types of\r
+                 channels, like analog, S/PDIF, AES/EBU, ADAT etc interfaces,\r
+                 there should be a reasonable grouping of these types. Groups\r
+                 are always independant form a channel index, that is, a channel\r
+                 index always counts from 0 to numInputs/numOutputs regardless\r
+                 of the group it may belong to.\r
+                 There will always be at least one group (group 0). Please\r
+                 also note that by default, the host may decide to activate\r
+                 channels 0 and 1; thus, these should belong to the most\r
+                 useful type (analog i/o, if present).\r
+               - type: on return, contains the sample type of the channel\r
+               - isActive: on return, ASIOTrue if channel is active as it was\r
+                 installed by ASIOCreateBuffers(), ASIOFalse else\r
+               - name:  describing the type of channel in question. Used to allow\r
+                 for user selection, and enabling of specific channels. examples:\r
+             "Analog In", "SPDIF Out" etc\r
+       Returns:\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+       Notes:\r
+         If possible, the string should be organised such that the first\r
+         characters are most significantly describing the nature of the\r
+         port, to allow for identification even if the view showing the\r
+         port name is too small to display more than 8 characters, for\r
+         instance.\r
+*/\r
+\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+// Buffer preparation\r
+//- - - - - - - - - - - - - - - - - - - - - - - - -\r
+\r
+typedef struct ASIOBufferInfo\r
+{\r
+       ASIOBool isInput;                       // on input:  ASIOTrue: input, else output\r
+       long channelNum;                        // on input:  channel index\r
+       void *buffers[2];                       // on output: double buffer addresses\r
+} ASIOBufferInfo;\r
+\r
+ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
+       long bufferSize, ASIOCallbacks *callbacks);\r
+\r
+/* Purpose:\r
+         Allocates input/output buffers for all input and output channels to be activated.\r
+       Parameter:\r
+         bufferInfos is a pointer to an array of ASIOBufferInfo structures:\r
+           - isInput: on input, ASIOTrue if the buffer is to be allocated\r
+             for an input, output buffer else\r
+           - channelNum: on input, the index of the channel in question\r
+             (counting from 0)\r
+           - buffers: on exit, 2 pointers to the halves of the channels' double-buffer.\r
+             the size of the buffer(s) of course depend on both the ASIOSampleType\r
+             as obtained from ASIOGetChannelInfo(), and bufferSize\r
+         numChannels is the sum of all input and output channels to be created;\r
+         thus bufferInfos is a pointer to an array of numChannels ASIOBufferInfo\r
+         structures.\r
+         bufferSize selects one of the possible buffer sizes as obtained from\r
+         ASIOGetBufferSizes().\r
+         callbacks is a pointer to an ASIOCallbacks structure.\r
+       Returns:\r
+         If not enough memory is available ASE_NoMemory will be returned.\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+         If bufferSize is not supported, or one or more of the bufferInfos elements\r
+         contain invalid settings, ASE_InvalidMode will be returned.\r
+       Notes:\r
+         If individual channel selection is not possible but requested,\r
+         the driver has to handle this. namely, bufferSwitch() will only\r
+         have filled buffers of enabled outputs. If possible, processing\r
+         and buss activities overhead should be avoided for channels which\r
+         were not enabled here.\r
+*/\r
+\r
+ASIOError ASIODisposeBuffers(void);\r
+/* Purpose:\r
+         Releases all buffers for the device.\r
+       Parameter:\r
+         None.\r
+       Returns:\r
+         If no buffer were ever prepared, ASE_InvalidMode will be returned.\r
+         If no input/output is present ASE_NotPresent will be returned.\r
+       Notes:\r
+         This implies ASIOStop().\r
+*/\r
+\r
+ASIOError ASIOControlPanel(void);\r
+/* Purpose:\r
+         request the driver to start a control panel component\r
+         for device specific user settings. This will not be\r
+         accessed on some platforms (where the component is accessed\r
+         instead).\r
+       Parameter:\r
+         None.\r
+       Returns:\r
+         If no panel is available ASE_NotPresent will be returned.\r
+         Actually, the return code is ignored.\r
+       Notes:\r
+         if the user applied settings which require a re-configuration\r
+         of parts or all of the enigine and/or driver (such as a change of\r
+         the block size), the asioMessage callback can be used (see\r
+         ASIO_Callbacks).\r
+*/\r
+\r
+ASIOError ASIOFuture(long selector, void *params);\r
+/* Purpose:\r
+         various\r
+       Parameter:\r
+         selector: operation Code as to be defined. zero is reserved for\r
+         testing purposes.\r
+         params: depends on the selector; usually pointer to a structure\r
+         for passing and retreiving any type and amount of parameters.\r
+       Returns:\r
+         the return value is also selector dependant. if the selector\r
+         is unknown, ASE_InvalidParameter should be returned to prevent\r
+         further calls with this selector. on success, ASE_SUCCESS\r
+         must be returned (note: ASE_OK is *not* sufficient!)\r
+       Notes:\r
+         see selectors defined below.    \r
+*/\r
+\r
+enum\r
+{\r
+       kAsioEnableTimeCodeRead = 1,    // no arguments\r
+       kAsioDisableTimeCodeRead,               // no arguments\r
+       kAsioSetInputMonitor,                   // ASIOInputMonitor* in params\r
+       kAsioTransport,                                 // ASIOTransportParameters* in params\r
+       kAsioSetInputGain,                              // ASIOChannelControls* in params, apply gain\r
+       kAsioGetInputMeter,                             // ASIOChannelControls* in params, fill meter\r
+       kAsioSetOutputGain,                             // ASIOChannelControls* in params, apply gain\r
+       kAsioGetOutputMeter,                    // ASIOChannelControls* in params, fill meter\r
+       kAsioCanInputMonitor,                   // no arguments for kAsioCanXXX selectors\r
+       kAsioCanTimeInfo,\r
+       kAsioCanTimeCode,\r
+       kAsioCanTransport,\r
+       kAsioCanInputGain,\r
+       kAsioCanInputMeter,\r
+       kAsioCanOutputGain,\r
+       kAsioCanOutputMeter,\r
+\r
+       //      DSD support\r
+       //      The following extensions are required to allow switching\r
+       //      and control of the DSD subsystem.\r
+       kAsioSetIoFormat                        = 0x23111961,           /* ASIOIoFormat * in params.                    */\r
+       kAsioGetIoFormat                        = 0x23111983,           /* ASIOIoFormat * in params.                    */\r
+       kAsioCanDoIoFormat                      = 0x23112004,           /* ASIOIoFormat * in params.                    */\r
+};\r
+\r
+typedef struct ASIOInputMonitor\r
+{\r
+       long input;             // this input was set to monitor (or off), -1: all\r
+       long output;    // suggested output for monitoring the input (if so)\r
+       long gain;              // suggested gain, ranging 0 - 0x7fffffffL (-inf to +12 dB)\r
+       ASIOBool state; // ASIOTrue => on, ASIOFalse => off\r
+       long pan;               // suggested pan, 0 => all left, 0x7fffffff => right\r
+} ASIOInputMonitor;\r
+\r
+typedef struct ASIOChannelControls\r
+{\r
+       long channel;                   // on input, channel index\r
+       ASIOBool isInput;               // on input\r
+       long gain;                              // on input,  ranges 0 thru 0x7fffffff\r
+       long meter;                             // on return, ranges 0 thru 0x7fffffff\r
+       char future[32];\r
+} ASIOChannelControls;\r
+\r
+typedef struct ASIOTransportParameters\r
+{\r
+       long command;           // see enum below\r
+       ASIOSamples samplePosition;\r
+       long track;\r
+       long trackSwitches[16];         // 512 tracks on/off\r
+       char future[64];\r
+} ASIOTransportParameters;\r
+\r
+enum\r
+{\r
+       kTransStart = 1,\r
+       kTransStop,\r
+       kTransLocate,           // to samplePosition\r
+       kTransPunchIn,\r
+       kTransPunchOut,\r
+       kTransArmOn,            // track\r
+       kTransArmOff,           // track\r
+       kTransMonitorOn,        // track\r
+       kTransMonitorOff,       // track\r
+       kTransArm,                      // trackSwitches\r
+       kTransMonitor           // trackSwitches\r
+};\r
+\r
+/*\r
+// DSD support\r
+//     Some notes on how to use ASIOIoFormatType.\r
+//\r
+//     The caller will fill the format with the request types.\r
+//     If the board can do the request then it will leave the\r
+//     values unchanged. If the board does not support the\r
+//     request then it will change that entry to Invalid (-1)\r
+//\r
+//     So to request DSD then\r
+//\r
+//     ASIOIoFormat NeedThis={kASIODSDFormat};\r
+//\r
+//     if(ASE_SUCCESS != ASIOFuture(kAsioSetIoFormat,&NeedThis) ){\r
+//             // If the board did not accept one of the parameters then the\r
+//             // whole call will fail and the failing parameter will\r
+//             // have had its value changes to -1.\r
+//     }\r
+//\r
+// Note: Switching between the formats need to be done before the "prepared"\r
+// state (see ASIO 2 documentation) is entered.\r
+*/\r
+typedef long int ASIOIoFormatType;\r
+enum ASIOIoFormatType_e\r
+{\r
+       kASIOFormatInvalid = -1,\r
+       kASIOPCMFormat = 0,\r
+       kASIODSDFormat = 1,\r
+};\r
+\r
+typedef struct ASIOIoFormat_s\r
+{\r
+       ASIOIoFormatType        FormatType;\r
+       char                            future[512-sizeof(ASIOIoFormatType)];\r
+} ASIOIoFormat;\r
+\r
+\r
+ASIOError ASIOOutputReady(void);\r
+/* Purpose:\r
+         this tells the driver that the host has completed processing\r
+         the output buffers. if the data format required by the hardware\r
+         differs from the supported asio formats, but the hardware\r
+         buffers are DMA buffers, the driver will have to convert\r
+         the audio stream data; as the bufferSwitch callback is\r
+         usually issued at dma block switch time, the driver will\r
+         have to convert the *previous* host buffer, which increases\r
+         the output latency by one block.\r
+         when the host finds out that ASIOOutputReady() returns\r
+         true, it will issue this call whenever it completed\r
+         output processing. then the driver can convert the\r
+         host data directly to the dma buffer to be played next,\r
+         reducing output latency by one block.\r
+         another way to look at it is, that the buffer switch is called\r
+         in order to pass the *input* stream to the host, so that it can\r
+         process the input into the output, and the output stream is passed\r
+         to the driver when the host has completed its process.\r
+       Parameter:\r
+               None\r
+       Returns:\r
+         only if the above mentioned scenario is given, and a reduction\r
+         of output latency can be acheived by this mechanism, should\r
+         ASE_OK be returned. otherwise (and usually), ASE_NotPresent\r
+         should be returned in order to prevent further calls to this\r
+         function. note that the host may want to determine if it is\r
+         to use this when the system is not yet fully initialized, so\r
+         ASE_OK should always be returned if the mechanism makes sense.          \r
+       Notes:\r
+         please remeber to adjust ASIOGetLatencies() according to\r
+         whether ASIOOutputReady() was ever called or not, if your\r
+         driver supports this scenario.\r
+         also note that the engine may fail to call ASIO_OutputReady()\r
+         in time in overload cases. as already mentioned, bufferSwitch\r
+      should be called for every block regardless of whether a block\r
+      could be processed in time.\r
+*/\r
+\r
+// restore old alignment\r
+#if defined(_MSC_VER) && !defined(__MWERKS__) \r
+#pragma pack(pop)\r
+#elif PRAGMA_ALIGN_SUPPORTED\r
+#pragma options align = reset\r
+#endif\r
+\r
+#endif\r
+\r
diff --git a/include/asiodrivers.cpp b/include/asiodrivers.cpp
new file mode 100644 (file)
index 0000000..5f56454
--- /dev/null
@@ -0,0 +1,186 @@
+#include <string.h>\r
+#include "asiodrivers.h"\r
+\r
+AsioDrivers* asioDrivers = 0;\r
+\r
+bool loadAsioDriver(char *name);\r
+\r
+bool loadAsioDriver(char *name)\r
+{\r
+       if(!asioDrivers)\r
+               asioDrivers = new AsioDrivers();\r
+       if(asioDrivers)\r
+               return asioDrivers->loadDriver(name);\r
+       return false;\r
+}\r
+\r
+//------------------------------------------------------------------------------------\r
+\r
+#if MAC\r
+\r
+bool resolveASIO(unsigned long aconnID);\r
+\r
+AsioDrivers::AsioDrivers() : CodeFragments("ASIO Drivers", 'AsDr', 'Asio')\r
+{\r
+       connID = -1;\r
+       curIndex = -1;\r
+}\r
+\r
+AsioDrivers::~AsioDrivers()\r
+{\r
+       removeCurrentDriver();\r
+}\r
+\r
+bool AsioDrivers::getCurrentDriverName(char *name)\r
+{\r
+       if(curIndex >= 0)\r
+               return getName(curIndex, name);\r
+       return false;\r
+}\r
+\r
+long AsioDrivers::getDriverNames(char **names, long maxDrivers)\r
+{\r
+       for(long i = 0; i < getNumFragments() && i < maxDrivers; i++)\r
+               getName(i, names[i]);\r
+       return getNumFragments() < maxDrivers ? getNumFragments() : maxDrivers;\r
+}\r
+\r
+bool AsioDrivers::loadDriver(char *name)\r
+{\r
+       char dname[64];\r
+       unsigned long newID;\r
+\r
+       for(long i = 0; i < getNumFragments(); i++)\r
+       {\r
+               if(getName(i, dname) && !strcmp(name, dname))\r
+               {\r
+                       if(newInstance(i, &newID))\r
+                       {\r
+                               if(resolveASIO(newID))\r
+                               {\r
+                                       if(connID != -1)\r
+                                               removeInstance(curIndex, connID);\r
+                                       curIndex = i;\r
+                                       connID = newID;\r
+                                       return true;\r
+                               }\r
+                       }\r
+                       break;\r
+               }\r
+       }\r
+       return false;\r
+}\r
+\r
+void AsioDrivers::removeCurrentDriver()\r
+{\r
+       if(connID != -1)\r
+               removeInstance(curIndex, connID);\r
+       connID = -1;\r
+       curIndex = -1;\r
+}\r
+\r
+//------------------------------------------------------------------------------------\r
+\r
+#elif WINDOWS\r
+\r
+#include "iasiodrv.h"\r
+\r
+extern IASIO* theAsioDriver;\r
+\r
+AsioDrivers::AsioDrivers() : AsioDriverList()\r
+{\r
+       curIndex = -1;\r
+}\r
+\r
+AsioDrivers::~AsioDrivers()\r
+{\r
+}\r
+\r
+bool AsioDrivers::getCurrentDriverName(char *name)\r
+{\r
+       if(curIndex >= 0)\r
+               return asioGetDriverName(curIndex, name, 32) == 0 ? true : false;\r
+       name[0] = 0;\r
+       return false;\r
+}\r
+\r
+long AsioDrivers::getDriverNames(char **names, long maxDrivers)\r
+{\r
+       for(long i = 0; i < asioGetNumDev() && i < maxDrivers; i++)\r
+               asioGetDriverName(i, names[i], 32);\r
+       return asioGetNumDev() < maxDrivers ? asioGetNumDev() : maxDrivers;\r
+}\r
+\r
+bool AsioDrivers::loadDriver(char *name)\r
+{\r
+       char dname[64];\r
+       char curName[64];\r
+\r
+       for(long i = 0; i < asioGetNumDev(); i++)\r
+       {\r
+               if(!asioGetDriverName(i, dname, 32) && !strcmp(name, dname))\r
+               {\r
+                       curName[0] = 0;\r
+                       getCurrentDriverName(curName);  // in case we fail...\r
+                       removeCurrentDriver();\r
+\r
+                       if(!asioOpenDriver(i, (void **)&theAsioDriver))\r
+                       {\r
+                               curIndex = i;\r
+                               return true;\r
+                       }\r
+                       else\r
+                       {\r
+                               theAsioDriver = 0;\r
+                               if(curName[0] && strcmp(dname, curName))\r
+                                       loadDriver(curName);    // try restore\r
+                       }\r
+                       break;\r
+               }\r
+       }\r
+       return false;\r
+}\r
+\r
+void AsioDrivers::removeCurrentDriver()\r
+{\r
+       if(curIndex != -1)\r
+               asioCloseDriver(curIndex);\r
+       curIndex = -1;\r
+}\r
+\r
+#elif SGI || BEOS\r
+\r
+#include "asiolist.h"\r
+\r
+AsioDrivers::AsioDrivers() \r
+       : AsioDriverList()\r
+{\r
+       curIndex = -1;\r
+}\r
+\r
+AsioDrivers::~AsioDrivers()\r
+{\r
+}\r
+\r
+bool AsioDrivers::getCurrentDriverName(char *name)\r
+{\r
+       return false;\r
+}\r
+\r
+long AsioDrivers::getDriverNames(char **names, long maxDrivers)\r
+{\r
+       return 0;\r
+}\r
+\r
+bool AsioDrivers::loadDriver(char *name)\r
+{\r
+       return false;\r
+}\r
+\r
+void AsioDrivers::removeCurrentDriver()\r
+{\r
+}\r
+\r
+#else\r
+#error implement me\r
+#endif\r
diff --git a/include/asiodrivers.h b/include/asiodrivers.h
new file mode 100644 (file)
index 0000000..2ddf7ad
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef __AsioDrivers__\r
+#define __AsioDrivers__\r
+\r
+#include "ginclude.h"\r
+\r
+#if MAC\r
+#include "CodeFragments.hpp"\r
+\r
+class AsioDrivers : public CodeFragments\r
+\r
+#elif WINDOWS\r
+#include <windows.h>\r
+#include "asiolist.h"\r
+\r
+class AsioDrivers : public AsioDriverList\r
+\r
+#elif SGI || BEOS\r
+#include "asiolist.h"\r
+\r
+class AsioDrivers : public AsioDriverList\r
+\r
+#else\r
+#error implement me\r
+#endif\r
+\r
+{\r
+public:\r
+       AsioDrivers();\r
+       ~AsioDrivers();\r
+       \r
+       bool getCurrentDriverName(char *name);\r
+       long getDriverNames(char **names, long maxDrivers);\r
+       bool loadDriver(char *name);\r
+       void removeCurrentDriver();\r
+       long getCurrentDriverIndex() {return curIndex;}\r
+protected:\r
+       unsigned long connID;\r
+       long curIndex;\r
+};\r
+\r
+#endif\r
diff --git a/include/asiodrvr.h b/include/asiodrvr.h
new file mode 100644 (file)
index 0000000..663f75a
--- /dev/null
@@ -0,0 +1,76 @@
+/*\r
+       Steinberg Audio Stream I/O API\r
+       (c) 1996, Steinberg Soft- und Hardware GmbH\r
+       charlie (May 1996)\r
+\r
+       asiodrvr.h\r
+       c++ superclass to implement asio functionality. from this,\r
+       you can derive whatever required\r
+*/\r
+\r
+#ifndef _asiodrvr_\r
+#define _asiodrvr_\r
+\r
+// cpu and os system we are running on\r
+#include "asiosys.h"\r
+// basic "C" interface\r
+#include "asio.h"\r
+\r
+class AsioDriver;\r
+extern AsioDriver *getDriver();                // for generic constructor \r
+\r
+#if WINDOWS\r
+#include <windows.h>\r
+#include "combase.h"\r
+#include "iasiodrv.h"\r
+class AsioDriver : public IASIO ,public CUnknown\r
+{\r
+public:\r
+       AsioDriver(LPUNKNOWN pUnk, HRESULT *phr);\r
+\r
+       DECLARE_IUNKNOWN\r
+       // Factory method\r
+       static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);\r
+       // IUnknown\r
+       virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject);\r
+\r
+#else\r
+\r
+class AsioDriver\r
+{\r
+public:\r
+       AsioDriver();\r
+#endif\r
+       virtual ~AsioDriver();\r
+\r
+       virtual ASIOBool init(void* sysRef);\r
+       virtual void getDriverName(char *name); // max 32 bytes incl. terminating zero\r
+       virtual long getDriverVersion();\r
+       virtual void getErrorMessage(char *string);     // max 124 bytes incl.\r
+\r
+       virtual ASIOError start();\r
+       virtual ASIOError stop();\r
+\r
+       virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);\r
+       virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);\r
+       virtual ASIOError getBufferSize(long *minSize, long *maxSize,\r
+               long *preferredSize, long *granularity);\r
+\r
+       virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);\r
+       virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);\r
+       virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);\r
+       virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);\r
+       virtual ASIOError setClockSource(long reference);\r
+\r
+       virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp);\r
+       virtual ASIOError getChannelInfo(ASIOChannelInfo *info);\r
+\r
+       virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
+               long bufferSize, ASIOCallbacks *callbacks);\r
+       virtual ASIOError disposeBuffers();\r
+\r
+       virtual ASIOError controlPanel();\r
+       virtual ASIOError future(long selector, void *opt);\r
+       virtual ASIOError outputReady();\r
+};\r
+#endif\r
diff --git a/include/asiolist.cpp b/include/asiolist.cpp
new file mode 100644 (file)
index 0000000..5a62f5b
--- /dev/null
@@ -0,0 +1,268 @@
+#include <windows.h>\r
+#include "iasiodrv.h"\r
+#include "asiolist.h"\r
+\r
+#define ASIODRV_DESC           "description"\r
+#define INPROC_SERVER          "InprocServer32"\r
+#define ASIO_PATH                      "software\\asio"\r
+#define COM_CLSID                      "clsid"\r
+\r
+// ******************************************************************\r
+// Local Functions \r
+// ******************************************************************\r
+static LONG findDrvPath (char *clsidstr,char *dllpath,int dllpathsize)\r
+{\r
+       HKEY                    hkEnum,hksub,hkpath;\r
+       char                    databuf[512];\r
+       LONG                    cr,rc = -1;\r
+       DWORD                   datatype,datasize;\r
+       DWORD                   index;\r
+       OFSTRUCT                ofs;\r
+       HFILE                   hfile;\r
+       BOOL                    found = FALSE;\r
+\r
+       CharLowerBuff(clsidstr,strlen(clsidstr));\r
+       if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) {\r
+\r
+               index = 0;\r
+               while (cr == ERROR_SUCCESS && !found) {\r
+                       cr = RegEnumKey(hkEnum,index++,(LPTSTR)databuf,512);\r
+                       if (cr == ERROR_SUCCESS) {\r
+                               CharLowerBuff(databuf,strlen(databuf));\r
+                               if (!(strcmp(databuf,clsidstr))) {\r
+                                       if ((cr = RegOpenKeyEx(hkEnum,(LPCTSTR)databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {\r
+                                               if ((cr = RegOpenKeyEx(hksub,(LPCTSTR)INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) {\r
+                                                       datatype = REG_SZ; datasize = (DWORD)dllpathsize;\r
+                                                       cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize);\r
+                                                       if (cr == ERROR_SUCCESS) {\r
+                                                               memset(&ofs,0,sizeof(OFSTRUCT));\r
+                                                               ofs.cBytes = sizeof(OFSTRUCT); \r
+                                                               hfile = OpenFile(dllpath,&ofs,OF_EXIST);\r
+                                                               if (hfile) rc = 0; \r
+                                                       }\r
+                                                       RegCloseKey(hkpath);\r
+                                               }\r
+                                               RegCloseKey(hksub);\r
+                                       }\r
+                                       found = TRUE;   // break out \r
+                               }\r
+                       }\r
+               }                               \r
+               RegCloseKey(hkEnum);\r
+       }\r
+       return rc;\r
+}\r
+\r
+\r
+static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv)\r
+{\r
+       HKEY    hksub;\r
+       char    databuf[256];\r
+       char    dllpath[MAXPATHLEN];\r
+       WORD    wData[100];\r
+       CLSID   clsid;\r
+       DWORD   datatype,datasize;\r
+       LONG    cr,rc;\r
+\r
+       if (!lpdrv) {\r
+               if ((cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {\r
+\r
+                       datatype = REG_SZ; datasize = 256;\r
+                       cr = RegQueryValueEx(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize);\r
+                       if (cr == ERROR_SUCCESS) {\r
+                               rc = findDrvPath (databuf,dllpath,MAXPATHLEN);\r
+                               if (rc == 0) {\r
+                                       lpdrv = new ASIODRVSTRUCT[1];\r
+                                       if (lpdrv) {\r
+                                               memset(lpdrv,0,sizeof(ASIODRVSTRUCT));\r
+                                               lpdrv->drvID = drvID;\r
+                                               MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100);\r
+                                               if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) {\r
+                                                       memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID));\r
+                                               }\r
+\r
+                                               datatype = REG_SZ; datasize = 256;\r
+                                               cr = RegQueryValueEx(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize);\r
+                                               if (cr == ERROR_SUCCESS) {\r
+                                                       strcpy(lpdrv->drvname,databuf);\r
+                                               }\r
+                                               else strcpy(lpdrv->drvname,keyname);\r
+                                       }\r
+                               }\r
+                       }\r
+                       RegCloseKey(hksub);\r
+               }\r
+       }       \r
+       else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next);\r
+\r
+       return lpdrv;\r
+}\r
+\r
+static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv)\r
+{\r
+       IASIO   *iasio;\r
+\r
+       if (lpdrv != 0) {\r
+               deleteDrvStruct(lpdrv->next);\r
+               if (lpdrv->asiodrv) {\r
+                       iasio = (IASIO *)lpdrv->asiodrv;\r
+                       iasio->Release();\r
+               }\r
+               delete lpdrv;\r
+       }\r
+}\r
+\r
+\r
+static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv)\r
+{\r
+       while (lpdrv) {\r
+               if (lpdrv->drvID == drvID) return lpdrv;\r
+               lpdrv = lpdrv->next;\r
+       }\r
+       return 0;\r
+}\r
+// ******************************************************************\r
+\r
+\r
+// ******************************************************************\r
+//     AsioDriverList\r
+// ******************************************************************\r
+AsioDriverList::AsioDriverList ()\r
+{\r
+       HKEY                    hkEnum = 0;\r
+       char                    keyname[MAXDRVNAMELEN];\r
+       LPASIODRVSTRUCT pdl;\r
+       LONG                    cr;\r
+       DWORD                   index = 0;\r
+       BOOL                    fin = FALSE;\r
+\r
+       numdrv          = 0;\r
+       lpdrvlist       = 0;\r
+\r
+       cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum);\r
+       while (cr == ERROR_SUCCESS) {\r
+               if ((cr = RegEnumKey(hkEnum,index++,(LPTSTR)keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) {\r
+                       lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist);\r
+               }\r
+               else fin = TRUE;\r
+       }\r
+       if (hkEnum) RegCloseKey(hkEnum);\r
+\r
+       pdl = lpdrvlist;\r
+       while (pdl) {\r
+               numdrv++;\r
+               pdl = pdl->next;\r
+       }\r
+\r
+       if (numdrv) CoInitialize(0);    // initialize COM\r
+}\r
+\r
+AsioDriverList::~AsioDriverList ()\r
+{\r
+       if (numdrv) {\r
+               deleteDrvStruct(lpdrvlist);\r
+               CoUninitialize();\r
+       }\r
+}\r
+\r
+\r
+LONG AsioDriverList::asioGetNumDev (VOID)\r
+{\r
+       return (LONG)numdrv;\r
+}\r
+\r
+\r
+LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv)\r
+{\r
+       LPASIODRVSTRUCT lpdrv = 0;\r
+       long                    rc;\r
+\r
+       if (!asiodrv) return DRVERR_INVALID_PARAM;\r
+\r
+       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {\r
+               if (!lpdrv->asiodrv) {\r
+                       rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv);\r
+                       if (rc == S_OK) {\r
+                               lpdrv->asiodrv = *asiodrv;\r
+                               return 0;\r
+                       }\r
+                       // else if (rc == REGDB_E_CLASSNOTREG)\r
+                       //      strcpy (info->messageText, "Driver not registered in the Registration Database!");\r
+               }\r
+               else rc = DRVERR_DEVICE_ALREADY_OPEN;\r
+       }\r
+       else rc = DRVERR_DEVICE_NOT_FOUND;\r
+       \r
+       return rc;\r
+}\r
+\r
+\r
+LONG AsioDriverList::asioCloseDriver (int drvID)\r
+{\r
+       LPASIODRVSTRUCT lpdrv = 0;\r
+       IASIO                   *iasio;\r
+\r
+       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {\r
+               if (lpdrv->asiodrv) {\r
+                       iasio = (IASIO *)lpdrv->asiodrv;\r
+                       iasio->Release();\r
+                       lpdrv->asiodrv = 0;\r
+               }\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize)\r
+{      \r
+       LPASIODRVSTRUCT                 lpdrv = 0;\r
+\r
+       if (!drvname) return DRVERR_INVALID_PARAM;\r
+\r
+       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {\r
+               if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) {\r
+                       strcpy(drvname,lpdrv->drvname);\r
+               }\r
+               else {\r
+                       memcpy(drvname,lpdrv->drvname,drvnamesize-4);\r
+                       drvname[drvnamesize-4] = '.';\r
+                       drvname[drvnamesize-3] = '.';\r
+                       drvname[drvnamesize-2] = '.';\r
+                       drvname[drvnamesize-1] = 0;\r
+               }\r
+               return 0;\r
+       }\r
+       return DRVERR_DEVICE_NOT_FOUND;\r
+}\r
+\r
+LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize)\r
+{\r
+       LPASIODRVSTRUCT                 lpdrv = 0;\r
+\r
+       if (!dllpath) return DRVERR_INVALID_PARAM;\r
+\r
+       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {\r
+               if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) {\r
+                       strcpy(dllpath,lpdrv->dllpath);\r
+                       return 0;\r
+               }\r
+               dllpath[0] = 0;\r
+               return DRVERR_INVALID_PARAM;\r
+       }\r
+       return DRVERR_DEVICE_NOT_FOUND;\r
+}\r
+\r
+LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid)\r
+{\r
+       LPASIODRVSTRUCT                 lpdrv = 0;\r
+\r
+       if (!clsid) return DRVERR_INVALID_PARAM;\r
+\r
+       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {\r
+               memcpy(clsid,&lpdrv->clsid,sizeof(CLSID));\r
+               return 0;\r
+       }\r
+       return DRVERR_DEVICE_NOT_FOUND;\r
+}\r
+\r
+\r
diff --git a/include/asiolist.h b/include/asiolist.h
new file mode 100644 (file)
index 0000000..01c64f0
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __asiolist__\r
+#define __asiolist__\r
+\r
+#define DRVERR                 -5000\r
+#define DRVERR_INVALID_PARAM           DRVERR-1\r
+#define DRVERR_DEVICE_ALREADY_OPEN     DRVERR-2\r
+#define DRVERR_DEVICE_NOT_FOUND                DRVERR-3\r
+\r
+#define MAXPATHLEN                     512\r
+#define MAXDRVNAMELEN          128\r
+\r
+struct asiodrvstruct\r
+{\r
+       int                                             drvID;\r
+       CLSID                                   clsid;\r
+       char                                    dllpath[MAXPATHLEN];\r
+       char                                    drvname[MAXDRVNAMELEN];\r
+       LPVOID                                  asiodrv;\r
+       struct asiodrvstruct    *next;\r
+};\r
+\r
+typedef struct asiodrvstruct ASIODRVSTRUCT;\r
+typedef ASIODRVSTRUCT  *LPASIODRVSTRUCT;\r
+\r
+class AsioDriverList {\r
+public:\r
+       AsioDriverList();\r
+       ~AsioDriverList();\r
+       \r
+       LONG asioOpenDriver (int,VOID **);\r
+       LONG asioCloseDriver (int);\r
+\r
+       // nice to have\r
+       LONG asioGetNumDev (VOID);\r
+       LONG asioGetDriverName (int,char *,int);                \r
+       LONG asioGetDriverPath (int,char *,int);\r
+       LONG asioGetDriverCLSID (int,CLSID *);\r
+\r
+       // or use directly access\r
+       LPASIODRVSTRUCT lpdrvlist;\r
+       int                             numdrv;\r
+};\r
+\r
+typedef class AsioDriverList *LPASIODRIVERLIST;\r
+\r
+#endif\r
diff --git a/include/asiosys.h b/include/asiosys.h
new file mode 100644 (file)
index 0000000..37f7a48
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef __asiosys__\r
+       #define __asiosys__\r
+\r
+       #ifdef WIN32\r
+               #undef MAC \r
+               #define PPC 0\r
+               #define WINDOWS 1\r
+               #define SGI 0\r
+               #define SUN 0\r
+               #define LINUX 0\r
+               #define BEOS 0\r
+\r
+               #define NATIVE_INT64 0\r
+               #define IEEE754_64FLOAT 1\r
+       \r
+       #elif BEOS\r
+               #define MAC 0\r
+               #define PPC 0\r
+               #define WINDOWS 0\r
+               #define PC 0\r
+               #define SGI 0\r
+               #define SUN 0\r
+               #define LINUX 0\r
+               \r
+               #define NATIVE_INT64 0\r
+               #define IEEE754_64FLOAT 1\r
+               \r
+               #ifndef DEBUG\r
+                       #define DEBUG 0\r
+                       #if DEBUG\r
+                               void DEBUGGERMESSAGE(char *string);\r
+                       #else\r
+                               #define DEBUGGERMESSAGE(a)\r
+                       #endif\r
+               #endif\r
+\r
+       #elif SGI\r
+               #define MAC 0\r
+               #define PPC 0\r
+               #define WINDOWS 0\r
+               #define PC 0\r
+               #define SUN 0\r
+               #define LINUX 0\r
+               #define BEOS 0\r
+               \r
+               #define NATIVE_INT64 0\r
+               #define IEEE754_64FLOAT 1\r
+               \r
+               #ifndef DEBUG\r
+                       #define DEBUG 0\r
+                       #if DEBUG\r
+                               void DEBUGGERMESSAGE(char *string);\r
+                       #else\r
+                               #define DEBUGGERMESSAGE(a)\r
+                       #endif\r
+               #endif\r
+\r
+       #else   // MAC\r
+\r
+               #define MAC 1\r
+               #define PPC 1\r
+               #define WINDOWS 0\r
+               #define PC 0\r
+               #define SGI 0\r
+               #define SUN 0\r
+               #define LINUX 0\r
+               #define BEOS 0\r
+\r
+               #define NATIVE_INT64 0\r
+               #define IEEE754_64FLOAT 1\r
+\r
+               #ifndef DEBUG\r
+                       #define DEBUG 0\r
+                       #if DEBUG\r
+                               void DEBUGGERMESSAGE(char *string);\r
+                       #else\r
+                               #define DEBUGGERMESSAGE(a)\r
+                       #endif\r
+               #endif\r
+       #endif\r
+\r
+#endif\r
diff --git a/include/dsound.h b/include/dsound.h
new file mode 100644 (file)
index 0000000..cb19cca
--- /dev/null
@@ -0,0 +1,2369 @@
+/*==========================================================================;
+ *
+ *  Copyright (c) Microsoft Corporation.  All rights reserved.
+ *
+ *  File:       dsound.h
+ *  Content:    DirectSound include file
+ *
+ **************************************************************************/
+
+#define COM_NO_WINDOWS_H
+#include <objbase.h>
+#include <float.h>
+
+#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 (file)
index 0000000..b627dc2
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef __gInclude__\r
+#define __gInclude__\r
+\r
+#if SGI \r
+       #undef BEOS \r
+       #undef MAC \r
+       #undef WINDOWS\r
+       //\r
+       #define ASIO_BIG_ENDIAN 1\r
+       #define ASIO_CPU_MIPS 1\r
+#elif defined WIN32\r
+       #undef BEOS \r
+       #undef MAC \r
+       #undef SGI\r
+       #define WINDOWS 1\r
+       #define ASIO_LITTLE_ENDIAN 1\r
+       #define ASIO_CPU_X86 1\r
+#elif BEOS\r
+       #undef MAC \r
+       #undef SGI\r
+       #undef WINDOWS\r
+       #define ASIO_LITTLE_ENDIAN 1\r
+       #define ASIO_CPU_X86 1\r
+       //\r
+#else\r
+       #define MAC 1\r
+       #undef BEOS \r
+       #undef WINDOWS\r
+       #undef SGI\r
+       #define ASIO_BIG_ENDIAN 1\r
+       #define ASIO_CPU_PPC 1\r
+#endif\r
+\r
+// always\r
+#define NATIVE_INT64 0\r
+#define IEEE754_64FLOAT 1\r
+\r
+#endif // __gInclude__\r
diff --git a/include/iasiodrv.h b/include/iasiodrv.h
new file mode 100644 (file)
index 0000000..64d2dbb
--- /dev/null
@@ -0,0 +1,37 @@
+#include "asiosys.h"\r
+#include "asio.h"\r
+\r
+/* Forward Declarations */ \r
+\r
+#ifndef __ASIODRIVER_FWD_DEFINED__\r
+#define __ASIODRIVER_FWD_DEFINED__\r
+typedef interface IASIO IASIO;\r
+#endif         /* __ASIODRIVER_FWD_DEFINED__ */\r
+\r
+interface IASIO : public IUnknown\r
+{\r
+\r
+       virtual ASIOBool init(void *sysHandle) = 0;\r
+       virtual void getDriverName(char *name) = 0;     \r
+       virtual long getDriverVersion() = 0;\r
+       virtual void getErrorMessage(char *string) = 0; \r
+       virtual ASIOError start() = 0;\r
+       virtual ASIOError stop() = 0;\r
+       virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0;\r
+       virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0;\r
+       virtual ASIOError getBufferSize(long *minSize, long *maxSize,\r
+               long *preferredSize, long *granularity) = 0;\r
+       virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0;\r
+       virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0;\r
+       virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0;\r
+       virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0;\r
+       virtual ASIOError setClockSource(long reference) = 0;\r
+       virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;\r
+       virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0;\r
+       virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
+               long bufferSize, ASIOCallbacks *callbacks) = 0;\r
+       virtual ASIOError disposeBuffers() = 0;\r
+       virtual ASIOError controlPanel() = 0;\r
+       virtual ASIOError future(long selector,void *opt) = 0;\r
+       virtual ASIOError outputReady() = 0;\r
+};\r
diff --git a/include/iasiothiscallresolver.cpp b/include/iasiothiscallresolver.cpp
new file mode 100644 (file)
index 0000000..38c39d2
--- /dev/null
@@ -0,0 +1,563 @@
+/*\r
+       IASIOThiscallResolver.cpp see the comments in iasiothiscallresolver.h for\r
+    the top level description - this comment describes the technical details of\r
+    the implementation.\r
+\r
+    The latest version of this file is available from:\r
+    http://www.audiomulch.com/~rossb/code/calliasio\r
+\r
+    please email comments to Ross Bencina <rossb@audiomulch.com>\r
+\r
+    BACKGROUND\r
+\r
+    The IASIO interface declared in the Steinberg ASIO 2 SDK declares\r
+    functions with no explicit calling convention. This causes MSVC++ to default\r
+    to using the thiscall convention, which is a proprietary convention not\r
+    implemented by some non-microsoft compilers - notably borland BCC,\r
+    C++Builder, and gcc. MSVC++ is the defacto standard compiler used by\r
+    Steinberg. As a result of this situation, the ASIO sdk will compile with\r
+    any compiler, however attempting to execute the compiled code will cause a\r
+    crash due to different default calling conventions on non-Microsoft\r
+    compilers.\r
+\r
+    IASIOThiscallResolver solves the problem by providing an adapter class that\r
+    delegates to the IASIO interface using the correct calling convention\r
+    (thiscall). Due to the lack of support for thiscall in the Borland and GCC\r
+    compilers, the calls have been implemented in assembly language.\r
+\r
+    A number of macros are defined for thiscall function calls with different\r
+    numbers of parameters, with and without return values - it may be possible\r
+    to modify the format of these macros to make them work with other inline\r
+    assemblers.\r
+\r
+\r
+    THISCALL DEFINITION\r
+\r
+    A number of definitions of the thiscall calling convention are floating\r
+    around the internet. The following definition has been validated against\r
+    output from the MSVC++ compiler:\r
+\r
+    For non-vararg functions, thiscall works as follows: the object (this)\r
+    pointer is passed in ECX. All arguments are passed on the stack in\r
+    right to left order. The return value is placed in EAX. The callee\r
+    clears the passed arguments from the stack.\r
+\r
+\r
+    FINDING FUNCTION POINTERS FROM AN IASIO POINTER\r
+\r
+    The first field of a COM object is a pointer to its vtble. Thus a pointer\r
+    to an object implementing the IASIO interface also points to a pointer to\r
+    that object's vtbl. The vtble is a table of function pointers for all of\r
+    the virtual functions exposed by the implemented interfaces.\r
+\r
+    If we consider a variable declared as a pointer to IASO:\r
+\r
+    IASIO *theAsioDriver\r
+\r
+    theAsioDriver points to:\r
+\r
+    object implementing IASIO\r
+    {\r
+        IASIOvtbl *vtbl\r
+        other data\r
+    }\r
+\r
+    in other words, theAsioDriver points to a pointer to an IASIOvtbl\r
+\r
+    vtbl points to a table of function pointers:\r
+\r
+    IASIOvtbl ( interface IASIO : public IUnknown )\r
+    {\r
+    (IUnknown functions)\r
+    0   virtual HRESULT STDMETHODCALLTYPE (*QueryInterface)(REFIID riid, void **ppv) = 0;\r
+    4   virtual ULONG STDMETHODCALLTYPE (*AddRef)() = 0;\r
+    8   virtual ULONG STDMETHODCALLTYPE (*Release)() = 0;      \r
+\r
+    (IASIO functions)\r
+    12 virtual ASIOBool (*init)(void *sysHandle) = 0;\r
+    16 virtual void (*getDriverName)(char *name) = 0;\r
+    20 virtual long (*getDriverVersion)() = 0;\r
+    24 virtual void (*getErrorMessage)(char *string) = 0;\r
+    28 virtual ASIOError (*start)() = 0;\r
+    32 virtual ASIOError (*stop)() = 0;\r
+    36 virtual ASIOError (*getChannels)(long *numInputChannels, long *numOutputChannels) = 0;\r
+    40 virtual ASIOError (*getLatencies)(long *inputLatency, long *outputLatency) = 0;\r
+    44 virtual ASIOError (*getBufferSize)(long *minSize, long *maxSize,\r
+            long *preferredSize, long *granularity) = 0;\r
+    48 virtual ASIOError (*canSampleRate)(ASIOSampleRate sampleRate) = 0;\r
+    52 virtual ASIOError (*getSampleRate)(ASIOSampleRate *sampleRate) = 0;\r
+    56 virtual ASIOError (*setSampleRate)(ASIOSampleRate sampleRate) = 0;\r
+    60 virtual ASIOError (*getClockSources)(ASIOClockSource *clocks, long *numSources) = 0;\r
+    64 virtual ASIOError (*setClockSource)(long reference) = 0;\r
+    68 virtual ASIOError (*getSamplePosition)(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;\r
+    72 virtual ASIOError (*getChannelInfo)(ASIOChannelInfo *info) = 0;\r
+    76 virtual ASIOError (*createBuffers)(ASIOBufferInfo *bufferInfos, long numChannels,\r
+            long bufferSize, ASIOCallbacks *callbacks) = 0;\r
+    80 virtual ASIOError (*disposeBuffers)() = 0;\r
+    84 virtual ASIOError (*controlPanel)() = 0;\r
+    88 virtual ASIOError (*future)(long selector,void *opt) = 0;\r
+    92 virtual ASIOError (*outputReady)() = 0;\r
+    };\r
+\r
+    The numbers in the left column show the byte offset of each function ptr\r
+    from the beginning of the vtbl. These numbers are used in the code below\r
+    to select different functions.\r
+\r
+    In order to find the address of a particular function, theAsioDriver\r
+    must first be dereferenced to find the value of the vtbl pointer:\r
+\r
+    mov     eax, theAsioDriver\r
+    mov     edx, [theAsioDriver]  // edx now points to vtbl[0]\r
+\r
+    Then an offset must be added to the vtbl pointer to select a\r
+    particular function, for example vtbl+44 points to the slot containing\r
+    a pointer to the getBufferSize function.\r
+\r
+    Finally vtbl+x must be dereferenced to obtain the value of the function\r
+    pointer stored in that address:\r
+\r
+    call    [edx+44]    // call the function pointed to by\r
+                        // the value in the getBufferSize field of the vtbl\r
+\r
+\r
+    SEE ALSO\r
+\r
+    Martin Fay's OpenASIO DLL at http://www.martinfay.com solves the same\r
+    problem by providing a new COM interface which wraps IASIO with an\r
+    interface that uses portable calling conventions. OpenASIO must be compiled\r
+    with MSVC, and requires that you ship the OpenASIO DLL with your\r
+    application.\r
+\r
+    \r
+    ACKNOWLEDGEMENTS\r
+\r
+    Ross Bencina: worked out the thiscall details above, wrote the original\r
+    Borland asm macros, and a patch for asio.cpp (which is no longer needed).\r
+    Thanks to Martin Fay for introducing me to the issues discussed here,\r
+    and to Rene G. Ceballos for assisting with asm dumps from MSVC++.\r
+\r
+    Antti Silvast: converted the original calliasio to work with gcc and NASM\r
+    by implementing the asm code in a separate file.\r
+\r
+       Fraser Adams: modified the original calliasio containing the Borland inline\r
+    asm to add inline asm for gcc i.e. Intel syntax for Borland and AT&T syntax\r
+    for gcc. This seems a neater approach for gcc than to have a separate .asm\r
+    file and it means that we only need one version of the thiscall patch.\r
+\r
+    Fraser Adams: rewrote the original calliasio patch in the form of the\r
+    IASIOThiscallResolver class in order to avoid modifications to files from\r
+    the Steinberg SDK, which may have had potential licence issues.\r
+\r
+    Andrew Baldwin: contributed fixes for compatibility problems with more\r
+    recent versions of the gcc assembler.\r
+*/\r
+\r
+\r
+// We only need IASIOThiscallResolver at all if we are on Win32. For other\r
+// platforms we simply bypass the IASIOThiscallResolver definition to allow us\r
+// to be safely #include'd whatever the platform to keep client code portable\r
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)\r
+\r
+\r
+// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver\r
+// is not used.\r
+#if !defined(_MSC_VER)\r
+\r
+\r
+#include <new>\r
+#include <assert.h>\r
+\r
+// We have a mechanism in iasiothiscallresolver.h to ensure that asio.h is\r
+// #include'd before it in client code, we do NOT want to do this test here.\r
+#define iasiothiscallresolver_sourcefile 1\r
+#include "iasiothiscallresolver.h"\r
+#undef iasiothiscallresolver_sourcefile\r
+\r
+// iasiothiscallresolver.h redefines ASIOInit for clients, but we don't want\r
+// this macro defined in this translation unit.\r
+#undef ASIOInit\r
+\r
+\r
+// theAsioDriver is a global pointer to the current IASIO instance which the\r
+// ASIO SDK uses to perform all actions on the IASIO interface. We substitute\r
+// our own forwarding interface into this pointer.\r
+extern IASIO* theAsioDriver;\r
+\r
+\r
+// The following macros define the inline assembler for BORLAND first then gcc\r
+\r
+#if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)          \r
+\r
+\r
+#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )\\r
+    void *this_ = (thisPtr);                                                \\r
+    __asm {                                                                 \\r
+        mov     ecx, this_            ;                                     \\r
+        mov     eax, [ecx]            ;                                     \\r
+        call    [eax+funcOffset]      ;                                     \\r
+        mov     resultName, eax       ;                                     \\r
+    }\r
+\r
+\r
+#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )\\r
+    void *this_ = (thisPtr);                                                \\r
+    __asm {                                                                 \\r
+        mov     eax, param1           ;                                     \\r
+        push    eax                   ;                                     \\r
+        mov     ecx, this_            ;                                     \\r
+        mov     eax, [ecx]            ;                                     \\r
+        call    [eax+funcOffset]      ;                                     \\r
+    }\r
+\r
+\r
+#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )\\r
+    void *this_ = (thisPtr);                                                \\r
+    __asm {                                                                 \\r
+        mov     eax, param1           ;                                     \\r
+        push    eax                   ;                                     \\r
+        mov     ecx, this_            ;                                     \\r
+        mov     eax, [ecx]            ;                                     \\r
+        call    [eax+funcOffset]      ;                                     \\r
+        mov     resultName, eax       ;                                     \\r
+    }\r
+\r
+\r
+#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )\\r
+    void *this_ = (thisPtr);                                                \\r
+    void *doubleParamPtr_ (&param1);                                        \\r
+    __asm {                                                                 \\r
+        mov     eax, doubleParamPtr_  ;                                     \\r
+        push    [eax+4]               ;                                     \\r
+        push    [eax]                 ;                                     \\r
+        mov     ecx, this_            ;                                     \\r
+        mov     eax, [ecx]            ;                                     \\r
+        call    [eax+funcOffset]      ;                                     \\r
+        mov     resultName, eax       ;                                     \\r
+    }\r
+\r
+\r
+#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )\\r
+    void *this_ = (thisPtr);                                                \\r
+    __asm {                                                                 \\r
+        mov     eax, param2           ;                                     \\r
+        push    eax                   ;                                     \\r
+        mov     eax, param1           ;                                     \\r
+        push    eax                   ;                                     \\r
+        mov     ecx, this_            ;                                     \\r
+        mov     eax, [ecx]            ;                                     \\r
+        call    [eax+funcOffset]      ;                                     \\r
+        mov     resultName, eax       ;                                     \\r
+    }\r
+\r
+\r
+#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\\r
+    void *this_ = (thisPtr);                                                \\r
+    __asm {                                                                 \\r
+        mov     eax, param4           ;                                     \\r
+        push    eax                   ;                                     \\r
+        mov     eax, param3           ;                                     \\r
+        push    eax                   ;                                     \\r
+        mov     eax, param2           ;                                     \\r
+        push    eax                   ;                                     \\r
+        mov     eax, param1           ;                                     \\r
+        push    eax                   ;                                     \\r
+        mov     ecx, this_            ;                                     \\r
+        mov     eax, [ecx]            ;                                     \\r
+        call    [eax+funcOffset]      ;                                     \\r
+        mov     resultName, eax       ;                                     \\r
+    }\r
+\r
+\r
+#elif defined(__GNUC__)\r
+\r
+\r
+#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )                  \\r
+    __asm__ __volatile__ ("movl (%1), %%edx\n\t"                            \\r
+                          "call *"#funcOffset"(%%edx)\n\t"                  \\r
+                          :"=a"(resultName) /* Output Operands */           \\r
+                          :"c"(thisPtr)     /* Input Operands */            \\r
+                         );                                                 \\r
+\r
+\r
+#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )                 \\r
+    __asm__ __volatile__ ("pushl %0\n\t"                                    \\r
+                          "movl (%1), %%edx\n\t"                            \\r
+                          "call *"#funcOffset"(%%edx)\n\t"                  \\r
+                          :                 /* Output Operands */           \\r
+                          :"r"(param1),     /* Input Operands */            \\r
+                           "c"(thisPtr)                                     \\r
+                         );                                                 \\r
+\r
+\r
+#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )          \\r
+    __asm__ __volatile__ ("pushl %1\n\t"                                    \\r
+                          "movl (%2), %%edx\n\t"                            \\r
+                          "call *"#funcOffset"(%%edx)\n\t"                  \\r
+                          :"=a"(resultName) /* Output Operands */           \\r
+                          :"r"(param1),     /* Input Operands */            \\r
+                           "c"(thisPtr)                                     \\r
+                          );                                                \\r
+\r
+\r
+#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )   \\r
+    __asm__ __volatile__ ("pushl 4(%1)\n\t"                                 \\r
+                          "pushl (%1)\n\t"                                  \\r
+                          "movl (%2), %%edx\n\t"                            \\r
+                          "call *"#funcOffset"(%%edx);\n\t"                 \\r
+                          :"=a"(resultName) /* Output Operands */           \\r
+                          :"a"(&param1),    /* Input Operands */            \\r
+                           /* Note: Using "r" above instead of "a" fails */ \\r
+                           /* when using GCC 3.3.3, and maybe later versions*/\\r
+                           "c"(thisPtr)                                     \\r
+                          );                                                \\r
+\r
+\r
+#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )  \\r
+    __asm__ __volatile__ ("pushl %1\n\t"                                    \\r
+                          "pushl %2\n\t"                                    \\r
+                          "movl (%3), %%edx\n\t"                            \\r
+                          "call *"#funcOffset"(%%edx)\n\t"                  \\r
+                          :"=a"(resultName) /* Output Operands */           \\r
+                          :"r"(param2),     /* Input Operands */            \\r
+                           "r"(param1),                                     \\r
+                           "c"(thisPtr)                                     \\r
+                          );                                                \\r
+\r
+\r
+#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\\r
+    __asm__ __volatile__ ("pushl %1\n\t"                                    \\r
+                          "pushl %2\n\t"                                    \\r
+                          "pushl %3\n\t"                                    \\r
+                          "pushl %4\n\t"                                    \\r
+                          "movl (%5), %%edx\n\t"                            \\r
+                          "call *"#funcOffset"(%%edx)\n\t"                  \\r
+                          :"=a"(resultName) /* Output Operands */           \\r
+                          :"r"(param4),     /* Input Operands  */           \\r
+                           "r"(param3),                                     \\r
+                           "r"(param2),                                     \\r
+                           "r"(param1),                                     \\r
+                           "c"(thisPtr)                                     \\r
+                          );                                                \\r
+\r
+#endif\r
+\r
+\r
+\r
+// Our static singleton instance.\r
+IASIOThiscallResolver IASIOThiscallResolver::instance;\r
+\r
+// Constructor called to initialize static Singleton instance above. Note that\r
+// it is important not to clear that_ incase it has already been set by the call\r
+// to placement new in ASIOInit().\r
+IASIOThiscallResolver::IASIOThiscallResolver()\r
+{\r
+}\r
+\r
+// Constructor called from ASIOInit() below\r
+IASIOThiscallResolver::IASIOThiscallResolver(IASIO* that)\r
+: that_( that )\r
+{\r
+}\r
+\r
+// Implement IUnknown methods as assert(false). IASIOThiscallResolver is not\r
+// really a COM object, just a wrapper which will work with the ASIO SDK.\r
+// If you wanted to use ASIO without the SDK you might want to implement COM\r
+// aggregation in these methods.\r
+HRESULT STDMETHODCALLTYPE IASIOThiscallResolver::QueryInterface(REFIID riid, void **ppv)\r
+{\r
+    (void)riid;     // suppress unused variable warning\r
+\r
+    assert( false ); // this function should never be called by the ASIO SDK.\r
+\r
+    *ppv = NULL;\r
+    return E_NOINTERFACE;\r
+}\r
+\r
+ULONG STDMETHODCALLTYPE IASIOThiscallResolver::AddRef()\r
+{\r
+    assert( false ); // this function should never be called by the ASIO SDK.\r
+\r
+    return 1;\r
+}\r
+\r
+ULONG STDMETHODCALLTYPE IASIOThiscallResolver::Release()\r
+{\r
+    assert( false ); // this function should never be called by the ASIO SDK.\r
+    \r
+    return 1;\r
+}\r
+\r
+\r
+// Implement the IASIO interface methods by performing the vptr manipulation\r
+// described above then delegating to the real implementation.\r
+ASIOBool IASIOThiscallResolver::init(void *sysHandle)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_1( result, that_, 12, sysHandle );\r
+    return result;\r
+}\r
+\r
+void IASIOThiscallResolver::getDriverName(char *name)\r
+{\r
+    CALL_VOID_THISCALL_1( that_, 16, name );\r
+}\r
+\r
+long IASIOThiscallResolver::getDriverVersion()\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_0( result, that_, 20 );\r
+    return result;\r
+}\r
+\r
+void IASIOThiscallResolver::getErrorMessage(char *string)\r
+{\r
+     CALL_VOID_THISCALL_1( that_, 24, string );\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::start()\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_0( result, that_, 28 );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::stop()\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_0( result, that_, 32 );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::getChannels(long *numInputChannels, long *numOutputChannels)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_2( result, that_, 36, numInputChannels, numOutputChannels );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::getLatencies(long *inputLatency, long *outputLatency)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_2( result, that_, 40, inputLatency, outputLatency );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::getBufferSize(long *minSize, long *maxSize,\r
+        long *preferredSize, long *granularity)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_4( result, that_, 44, minSize, maxSize, preferredSize, granularity );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::canSampleRate(ASIOSampleRate sampleRate)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_1_DOUBLE( result, that_, 48, sampleRate );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::getSampleRate(ASIOSampleRate *sampleRate)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_1( result, that_, 52, sampleRate );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::setSampleRate(ASIOSampleRate sampleRate)\r
+{    \r
+    ASIOBool result;\r
+    CALL_THISCALL_1_DOUBLE( result, that_, 56, sampleRate );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::getClockSources(ASIOClockSource *clocks, long *numSources)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_2( result, that_, 60, clocks, numSources );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::setClockSource(long reference)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_1( result, that_, 64, reference );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_2( result, that_, 68, sPos, tStamp );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::getChannelInfo(ASIOChannelInfo *info)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_1( result, that_, 72, info );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::createBuffers(ASIOBufferInfo *bufferInfos,\r
+        long numChannels, long bufferSize, ASIOCallbacks *callbacks)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_4( result, that_, 76, bufferInfos, numChannels, bufferSize, callbacks );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::disposeBuffers()\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_0( result, that_, 80 );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::controlPanel()\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_0( result, that_, 84 );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::future(long selector,void *opt)\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_2( result, that_, 88, selector, opt );\r
+    return result;\r
+}\r
+\r
+ASIOError IASIOThiscallResolver::outputReady()\r
+{\r
+    ASIOBool result;\r
+    CALL_THISCALL_0( result, that_, 92 );\r
+    return result;\r
+}\r
+\r
+\r
+// Implement our substitute ASIOInit() method\r
+ASIOError IASIOThiscallResolver::ASIOInit(ASIODriverInfo *info)\r
+{\r
+    // To ensure that our instance's vptr is correctly constructed, even if\r
+    // ASIOInit is called prior to main(), we explicitly call its constructor\r
+    // (potentially over the top of an existing instance). Note that this is\r
+    // pretty ugly, and is only safe because IASIOThiscallResolver has no\r
+    // destructor and contains no objects with destructors.\r
+    new((void*)&instance) IASIOThiscallResolver( theAsioDriver );\r
+\r
+    // Interpose between ASIO client code and the real driver.\r
+    theAsioDriver = &instance;\r
+\r
+    // Note that we never need to switch theAsioDriver back to point to the\r
+    // real driver because theAsioDriver is reset to zero in ASIOExit().\r
+\r
+    // Delegate to the real ASIOInit\r
+       return ::ASIOInit(info);\r
+}\r
+\r
+\r
+#endif /* !defined(_MSC_VER) */\r
+\r
+#endif /* Win32 */\r
+\r
diff --git a/include/iasiothiscallresolver.h b/include/iasiothiscallresolver.h
new file mode 100644 (file)
index 0000000..b59d910
--- /dev/null
@@ -0,0 +1,201 @@
+// ****************************************************************************\r
+//\r
+// Changed:         I have modified this file slightly (includes) to work  with\r
+//                  RtAudio. RtAudio.cpp must include this file after asio.h.                                                    \r
+//\r
+// File:                       IASIOThiscallResolver.h\r
+// Description:     The IASIOThiscallResolver class implements the IASIO\r
+//                                     interface and acts as a proxy to the real IASIO interface by\r
+//                  calling through its vptr table using the thiscall calling\r
+//                  convention. To put it another way, we interpose\r
+//                  IASIOThiscallResolver between ASIO SDK code and the driver.\r
+//                  This is necessary because most non-Microsoft compilers don't\r
+//                  implement the thiscall calling convention used by IASIO.\r
+//\r
+//                                     iasiothiscallresolver.cpp contains the background of this\r
+//                                     problem plus a technical description of the vptr\r
+//                  manipulations.\r
+//\r
+//                                     In order to use this mechanism one simply has to add\r
+//                                     iasiothiscallresolver.cpp to the list of files to compile\r
+//                  and #include <iasiothiscallresolver.h>\r
+//\r
+//                                     Note that this #include must come after the other ASIO SDK\r
+//                  #includes, for example:\r
+//\r
+//                                     #include <windows.h>\r
+//                                     #include <asiosys.h>\r
+//                                     #include <asio.h>\r
+//                                     #include <asiodrivers.h>\r
+//                                     #include <iasiothiscallresolver.h>\r
+//\r
+//                                     Actually the important thing is to #include\r
+//                  <iasiothiscallresolver.h> after <asio.h>. We have\r
+//                  incorporated a test to enforce this ordering.\r
+//\r
+//                                     The code transparently takes care of the interposition by\r
+//                  using macro substitution to intercept calls to ASIOInit()\r
+//                  and ASIOExit(). We save the original ASIO global\r
+//                  "theAsioDriver" in our "that" variable, and then set\r
+//                  "theAsioDriver" to equal our IASIOThiscallResolver instance.\r
+//\r
+//                                     Whilst this method of resolving the thiscall problem requires\r
+//                                     the addition of #include <iasiothiscallresolver.h> to client\r
+//                  code it has the advantage that it does not break the terms\r
+//                  of the ASIO licence by publishing it. We are NOT modifying\r
+//                  any Steinberg code here, we are merely implementing the IASIO\r
+//                                     interface in the same way that we would need to do if we\r
+//                                     wished to provide an open source ASIO driver.\r
+//\r
+//                                     For compilation with MinGW -lole32 needs to be added to the\r
+//                  linker options. For BORLAND, linking with Import32.lib is\r
+//                  sufficient.\r
+//\r
+//                                     The dependencies are with: CoInitialize, CoUninitialize,\r
+//                                     CoCreateInstance, CLSIDFromString - used by asiolist.cpp\r
+//                                     and are required on Windows whether ThiscallResolver is used\r
+//                                     or not.\r
+//\r
+//                                     Searching for the above strings in the root library path\r
+//                                     of your compiler should enable the correct libraries to be\r
+//                                     identified if they aren't immediately obvious.\r
+//\r
+//                  Note that the current implementation of IASIOThiscallResolver\r
+//                  is not COM compliant - it does not correctly implement the\r
+//                  IUnknown interface. Implementing it is not necessary because\r
+//                  it is not called by parts of the ASIO SDK which call through\r
+//                  theAsioDriver ptr. The IUnknown methods are implemented as\r
+//                  assert(false) to ensure that the code fails if they are\r
+//                  ever called.\r
+// Restrictions:       None. Public Domain & Open Source distribute freely\r
+//                                     You may use IASIOThiscallResolver commercially as well as\r
+//                  privately.\r
+//                                     You the user assume the responsibility for the use of the\r
+//                                     files, binary or text, and there is no guarantee or warranty,\r
+//                                     expressed or implied, including but not limited to the\r
+//                                     implied warranties of merchantability and fitness for a\r
+//                                     particular purpose. You assume all responsibility and agree\r
+//                                     to hold no entity, copyright holder or distributors liable\r
+//                                     for any loss of data or inaccurate representations of data\r
+//                                     as a result of using IASIOThiscallResolver.\r
+// Version:         1.4 Added separate macro CALL_THISCALL_1_DOUBLE from\r
+//                  Andrew Baldwin, and volatile for whole gcc asm blocks,\r
+//                  both for compatibility with newer gcc versions. Cleaned up\r
+//                  Borland asm to use one less register.\r
+//                  1.3 Switched to including assert.h for better compatibility.\r
+//                  Wrapped entire .h and .cpp contents with a check for\r
+//                  _MSC_VER to provide better compatibility with MS compilers.\r
+//                  Changed Singleton implementation to use static instance\r
+//                  instead of freestore allocated instance. Removed ASIOExit\r
+//                  macro as it is no longer needed.\r
+//                  1.2 Removed semicolons from ASIOInit and ASIOExit macros to\r
+//                  allow them to be embedded in expressions (if statements).\r
+//                  Cleaned up some comments. Removed combase.c dependency (it\r
+//                  doesn't compile with BCB anyway) by stubbing IUnknown.\r
+//                  1.1 Incorporated comments from Ross Bencina including things\r
+//                                     such as changing name from ThiscallResolver to\r
+//                                     IASIOThiscallResolver, tidying up the constructor, fixing\r
+//                                     a bug in IASIOThiscallResolver::ASIOExit() and improving\r
+//                                     portability through the use of conditional compilation\r
+//                                     1.0 Initial working version.\r
+// Created:                    6/09/2003\r
+// Authors:         Fraser Adams\r
+//                  Ross Bencina\r
+//                  Rene G. Ceballos\r
+//                  Martin Fay\r
+//                  Antti Silvast\r
+//                  Andrew Baldwin\r
+//\r
+// ****************************************************************************\r
+\r
+\r
+#ifndef included_iasiothiscallresolver_h\r
+#define included_iasiothiscallresolver_h\r
+\r
+// We only need IASIOThiscallResolver at all if we are on Win32. For other\r
+// platforms we simply bypass the IASIOThiscallResolver definition to allow us\r
+// to be safely #include'd whatever the platform to keep client code portable\r
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)\r
+\r
+\r
+// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver\r
+// is not used.\r
+#if !defined(_MSC_VER)\r
+\r
+\r
+// The following is in order to ensure that this header is only included after\r
+// the other ASIO headers (except for the case of iasiothiscallresolver.cpp).\r
+// We need to do this because IASIOThiscallResolver works by eclipsing the\r
+// original definition of ASIOInit() with a macro (see below).\r
+#if !defined(iasiothiscallresolver_sourcefile)\r
+       #if !defined(__ASIO_H)\r
+       #error iasiothiscallresolver.h must be included AFTER asio.h\r
+       #endif\r
+#endif\r
+\r
+#include <windows.h>\r
+#include "iasiodrv.h" /* From ASIO SDK */\r
+\r
+\r
+class IASIOThiscallResolver : public IASIO {\r
+private:\r
+       IASIO* that_; // Points to the real IASIO\r
+\r
+       static IASIOThiscallResolver instance; // Singleton instance\r
+\r
+       // Constructors - declared private so construction is limited to\r
+    // our Singleton instance\r
+    IASIOThiscallResolver();\r
+       IASIOThiscallResolver(IASIO* that);\r
+public:\r
+\r
+    // Methods from the IUnknown interface. We don't fully implement IUnknown\r
+    // because the ASIO SDK never calls these methods through theAsioDriver ptr.\r
+    // These methods are implemented as assert(false).\r
+    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv);\r
+    virtual ULONG STDMETHODCALLTYPE AddRef();\r
+    virtual ULONG STDMETHODCALLTYPE Release();\r
+\r
+    // Methods from the IASIO interface, implemented as forwarning calls to that.\r
+       virtual ASIOBool init(void *sysHandle);\r
+       virtual void getDriverName(char *name);\r
+       virtual long getDriverVersion();\r
+       virtual void getErrorMessage(char *string);\r
+       virtual ASIOError start();\r
+       virtual ASIOError stop();\r
+       virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);\r
+       virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);\r
+       virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);\r
+       virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);\r
+       virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);\r
+       virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);\r
+       virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);\r
+       virtual ASIOError setClockSource(long reference);\r
+       virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp);\r
+       virtual ASIOError getChannelInfo(ASIOChannelInfo *info);\r
+       virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks);\r
+       virtual ASIOError disposeBuffers();\r
+       virtual ASIOError controlPanel();\r
+       virtual ASIOError future(long selector,void *opt);\r
+       virtual ASIOError outputReady();\r
+\r
+    // Class method, see ASIOInit() macro below.\r
+    static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit\r
+};\r
+\r
+\r
+// Replace calls to ASIOInit with our interposing version.\r
+// This macro enables us to perform thiscall resolution simply by #including\r
+// <iasiothiscallresolver.h> after the asio #includes (this file _must_ be\r
+// included _after_ the asio #includes)\r
+\r
+#define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name))\r
+\r
+\r
+#endif /* !defined(_MSC_VER) */\r
+\r
+#endif /* Win32 */\r
+\r
+#endif /* included_iasiothiscallresolver_h */\r
+\r
+\r
diff --git a/include/soundcard.h b/include/soundcard.h
new file mode 100644 (file)
index 0000000..e8fc9f6
--- /dev/null
@@ -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 <sys/ioctl.h>
+#endif
+
+#ifdef linux
+/* In Linux we need to be prepared for cross compiling */
+#include <linux/ioctl.h>
+#else
+# ifdef __FreeBSD__
+#    include <sys/ioccom.h>
+# else
+#    include <sys/ioctl.h>
+# 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<ll;ii++)\
+                                  _seqbuf[_seqbufptr+ii+2] = bufp[ii];\
+                               for(ii=ll;ii<6;ii++)\
+                                  _seqbuf[_seqbufptr+ii+2] = 0xff;\
+                               _SEQ_ADVBUF(8);}
+
+#define SEQ_CHN_PRESSURE(dev, chn, pressure) \
+               _CHN_COMMON(dev, MIDI_CHN_PRESSURE, chn, pressure, 0, 0)
+
+#define SEQ_SET_PATCH SEQ_PGM_CHANGE
+#ifdef OSSLIB
+#   define SEQ_PGM_CHANGE(dev, chn, patch) \
+               {OSS_patch_caching(dev, chn, patch, seqfd, _seqbuf, _seqbuflen); \
+                _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0);}
+#else
+#   define SEQ_PGM_CHANGE(dev, chn, patch) \
+               _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0)
+#endif
+
+#define SEQ_CONTROL(dev, chn, controller, value) \
+               _CHN_COMMON(dev, MIDI_CTL_CHANGE, chn, controller, 0, value)
+
+#define SEQ_BENDER(dev, chn, value) \
+               _CHN_COMMON(dev, MIDI_PITCH_BEND, chn, 0, 0, value)
+
+#define SEQ_V2_X_CONTROL(dev, voice, controller, value)        \
+                               {_SEQ_NEEDBUF(8);\
+                               _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
+                               _seqbuf[_seqbufptr+1] = SEQ_CONTROLLER;\
+                               _seqbuf[_seqbufptr+2] = (dev);\
+                               _seqbuf[_seqbufptr+3] = (voice);\
+                               _seqbuf[_seqbufptr+4] = (controller);\
+                               _seqbuf[_seqbufptr+5] = ((value)&0xff);\
+                               _seqbuf[_seqbufptr+6] = ((value>>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 (file)
index e8fc9f6..0000000
+++ /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 <sys/ioctl.h>
-#endif
-
-#ifdef linux
-/* In Linux we need to be prepared for cross compiling */
-#include <linux/ioctl.h>
-#else
-# ifdef __FreeBSD__
-#    include <sys/ioccom.h>
-# else
-#    include <sys/ioctl.h>
-# 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<ll;ii++)\
-                                  _seqbuf[_seqbufptr+ii+2] = bufp[ii];\
-                               for(ii=ll;ii<6;ii++)\
-                                  _seqbuf[_seqbufptr+ii+2] = 0xff;\
-                               _SEQ_ADVBUF(8);}
-
-#define SEQ_CHN_PRESSURE(dev, chn, pressure) \
-               _CHN_COMMON(dev, MIDI_CHN_PRESSURE, chn, pressure, 0, 0)
-
-#define SEQ_SET_PATCH SEQ_PGM_CHANGE
-#ifdef OSSLIB
-#   define SEQ_PGM_CHANGE(dev, chn, patch) \
-               {OSS_patch_caching(dev, chn, patch, seqfd, _seqbuf, _seqbuflen); \
-                _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0);}
-#else
-#   define SEQ_PGM_CHANGE(dev, chn, patch) \
-               _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0)
-#endif
-
-#define SEQ_CONTROL(dev, chn, controller, value) \
-               _CHN_COMMON(dev, MIDI_CTL_CHANGE, chn, controller, 0, value)
-
-#define SEQ_BENDER(dev, chn, value) \
-               _CHN_COMMON(dev, MIDI_PITCH_BEND, chn, 0, 0, value)
-
-#define SEQ_V2_X_CONTROL(dev, voice, controller, value)        \
-                               {_SEQ_NEEDBUF(8);\
-                               _seqbuf[_seqbufptr] = SEQ_EXTENDED;\
-                               _seqbuf[_seqbufptr+1] = SEQ_CONTROLLER;\
-                               _seqbuf[_seqbufptr+2] = (dev);\
-                               _seqbuf[_seqbufptr+3] = (voice);\
-                               _seqbuf[_seqbufptr+4] = (controller);\
-                               _seqbuf[_seqbufptr+5] = ((value)&0xff);\
-                               _seqbuf[_seqbufptr+6] = ((value>>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
index bc17be58c4b02b205c486a9acf6a7a9b4c952d2a..ec4144791a9203dc2d7398e5fb291d5f82b726fa 100644 (file)
@@ -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)
index ee73090c3a67e91e212837753a013237f2405886..fe5f324a1960e32d9a93f9423e4891175b91172c 100755 (executable)
@@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
 \r
 ###############################################################################\r
 \r
-Project: "duplex"=".\duplex.dsp" - Package Owner=<4>\r
+Project: "audioprobe"=.\audioprobe.dsp - Package Owner=<4>\r
 \r
 Package=<5>\r
 {{{\r
@@ -15,7 +15,7 @@ Package=<4>
 \r
 ###############################################################################\r
 \r
-Project: "playraw"=".\playraw.dsp" - Package Owner=<4>\r
+Project: "duplex"=.\duplex.dsp - Package Owner=<4>\r
 \r
 Package=<5>\r
 {{{\r
@@ -27,7 +27,7 @@ Package=<4>
 \r
 ###############################################################################\r
 \r
-Project: "playsaw"=".\playsaw.dsp" - Package Owner=<4>\r
+Project: "playraw"=.\playraw.dsp - Package Owner=<4>\r
 \r
 Package=<5>\r
 {{{\r
@@ -39,7 +39,7 @@ Package=<4>
 \r
 ###############################################################################\r
 \r
-Project: "probe"=".\probe.dsp" - Package Owner=<4>\r
+Project: "playsaw"=.\playsaw.dsp - Package Owner=<4>\r
 \r
 Package=<5>\r
 {{{\r
@@ -51,7 +51,7 @@ Package=<4>
 \r
 ###############################################################################\r
 \r
-Project: "record"=".\record.dsp" - Package Owner=<4>\r
+Project: "record"=.\record.dsp - Package Owner=<4>\r
 \r
 Package=<5>\r
 {{{\r
@@ -63,7 +63,7 @@ Package=<4>
 \r
 ###############################################################################\r
 \r
-Project: "testall"=".\testall.dsp" - Package Owner=<4>\r
+Project: "testall"=.\testall.dsp - Package Owner=<4>\r
 \r
 Package=<5>\r
 {{{\r
index 772881c1657c63cc62fb73a2d69980f251ba99e7..c39bcb49967716fa7055ec0af55ad7e3ae538fd6 100644 (file)
@@ -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 );
index 5efb0dd840468ba4d7584aaafc8ecee7a4c9a816..2eeb330d83f052efbc5d1df7ea885344724af623 100644 (file)
@@ -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 );