RM = /bin/rm
-OBJECTS = RtAudio.o
+OBJECTS = RtAudio.o @objects@
LIBRARY = librtaudio.a
DEFS = @debug@
DEFS += @audio_apis@
-CFLAGS = @cflags@
+CFLAGS = @cflags@ -Iinclude
CFLAGS += @warn@
all : $(LIBRARY)
%.o : %.cpp
$(CC) $(CFLAGS) $(DEFS) -c $(<) -o $@
+%.o : include/%.cpp
+ $(CC) $(CFLAGS) $(DEFS) -c $(<) -o $@
+
clean :
-rm -f $(LIBRARY)
-rm -f $(OBJECTS)
// 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;
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];
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,
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 ) ) {
}
// Set various stream parameters
+ DsHandle *handle = 0;
stream_.nDeviceChannels[mode] = channels + firstChannel;
stream_.nUserChannels[mode] = channels;
stream_.bufferSize = *bufferSize;
}
// Allocate our DsHandle structures for the stream.
- DsHandle *handle;
if ( stream_.apiHandle == 0 ) {
try {
handle = new DsHandle;
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];
MUTEX_LOCK( &stream_.mutex );
- HRESULT result;
+ HRESULT result = 0;
LPVOID audioPtr;
DWORD dataLen;
DsHandle *handle = (DsHandle *) stream_.apiHandle;
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,
+++ /dev/null
-/*\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
+++ /dev/null
-//---------------------------------------------------------------------------------------------------\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
+++ /dev/null
-#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
+++ /dev/null
-#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
+++ /dev/null
-/*\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
+++ /dev/null
-#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
+++ /dev/null
-#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
+++ /dev/null
-#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
+++ /dev/null
-#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
+++ /dev/null
-#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
+++ /dev/null
-/*\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_ (¶m1); \\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"(¶m1), /* 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
+++ /dev/null
-// ****************************************************************************\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
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)
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*)
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!))
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*)
[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
audio_apis="-D__WINDOWS_DS__"
LIBS="-ldsound -lwinmm $LIBS"
fi
+
+ LIBS="-lole32 $LIBS"
;;
*)
--- /dev/null
+/*\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
--- /dev/null
+//---------------------------------------------------------------------------------------------------\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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+/*\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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+/*==========================================================================;
+ *
+ * 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
+
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+/*\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_ (¶m1); \\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"(¶m1), /* 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
--- /dev/null
+// ****************************************************************************\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
--- /dev/null
+#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
+++ /dev/null
-#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
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)
\r
###############################################################################\r
\r
-Project: "duplex"=".\duplex.dsp" - Package Owner=<4>\r
+Project: "audioprobe"=.\audioprobe.dsp - Package Owner=<4>\r
\r
Package=<5>\r
{{{\r
\r
###############################################################################\r
\r
-Project: "playraw"=".\playraw.dsp" - Package Owner=<4>\r
+Project: "duplex"=.\duplex.dsp - Package Owner=<4>\r
\r
Package=<5>\r
{{{\r
\r
###############################################################################\r
\r
-Project: "playsaw"=".\playsaw.dsp" - Package Owner=<4>\r
+Project: "playraw"=.\playraw.dsp - Package Owner=<4>\r
\r
Package=<5>\r
{{{\r
\r
###############################################################################\r
\r
-Project: "probe"=".\probe.dsp" - Package Owner=<4>\r
+Project: "playsaw"=.\playsaw.dsp - Package Owner=<4>\r
\r
Package=<5>\r
{{{\r
\r
###############################################################################\r
\r
-Project: "record"=".\record.dsp" - Package Owner=<4>\r
+Project: "record"=.\record.dsp - Package Owner=<4>\r
\r
Package=<5>\r
{{{\r
\r
###############################################################################\r
\r
-Project: "testall"=".\testall.dsp" - Package Owner=<4>\r
+Project: "testall"=.\testall.dsp - Package Owner=<4>\r
\r
Package=<5>\r
{{{\r
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 );
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 );