浏览代码

文件调整,删除重复的库文件

huihui 3 年之前
父节点
当前提交
8191a21e65
共有 30 个文件被更改,包括 38 次插入19967 次删除
  1. 1 0
      .gitignore
  2. 12 0
      .gitmodules
  3. 4 2
      source/AudioDecode/AudioDecode.pro
  4. 1 58
      source/AudioDecode/AudioDecoder/AudioDecoder.pri
  5. 0 56
      source/AudioDecode/AudioDecoder/lib/RtAudio/RtAudio.pri
  6. 0 258
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/asio.cpp
  7. 0 1070
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/asio.h
  8. 0 186
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiodrivers.cpp
  9. 0 42
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiodrivers.h
  10. 0 77
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiodrvr.h
  11. 0 309
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiolist.cpp
  12. 0 46
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiolist.h
  13. 0 82
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiosys.h
  14. 0 2369
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/dsound.h
  15. 0 212
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/functiondiscoverykeys_devpkey.h
  16. 0 38
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/ginclude.h
  17. 0 37
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/iasiodrv.h
  18. 0 572
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/iasiothiscallresolver.cpp
  19. 0 202
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/iasiothiscallresolver.h
  20. 0 1878
      source/AudioDecode/AudioDecoder/lib/RtAudio/include/soundcard.h
  21. 0 10637
      source/AudioDecode/AudioDecoder/lib/RtAudio/src/RtAudio.cpp
  22. 0 1204
      source/AudioDecode/AudioDecoder/lib/RtAudio/src/RtAudio.h
  23. 0 12
      source/AudioDecode/AudioDecoder/lib/RtAudio/src/rtaudio.pc.in
  24. 0 261
      source/AudioDecode/AudioDecoder/lib/RtAudio/src/rtaudio_c.cpp
  25. 0 306
      source/AudioDecode/AudioDecoder/lib/RtAudio/src/rtaudio_c.h
  26. 6 45
      source/AudioEncode/AudioEncode.pro
  27. 6 3
      source/FFMPEG_Qt/FFMPEG_Qt.pro
  28. 2 2
      source/FFmpegDemo.pro
  29. 3 3
      source/OtherDemo/mydemo/FilterDemo/TestAvFilter.pro
  30. 3 0
      拷贝依赖dll.bat

+ 1 - 0
.gitignore

@@ -13,3 +13,4 @@ source/build-VideoDecode-Desktop_Qt_5_13_2_MSVC2017_32bit_654258-Release
 /build-FFmpegDemo-Desktop_Qt_5_13_2_MSVC2017_32bit_654258-Debug
 /build-FFmpegDemo-Desktop_Qt_5_13_2_MSVC2017_32bit_654258-Release
 source/FFmpegDemo.pro.user
+bin/

+ 12 - 0
.gitmodules

@@ -0,0 +1,12 @@
+[submodule "lib/ffmpeg"]
+	path = lib/ffmpeg
+	url = https://gitee.com/huihui765/ffmpeg-dev.git
+	branch = V4.3.1
+[submodule "lib/RtAudio"]
+	path = lib/RtAudio
+	url = https://gitee.com/devlib/RtAudio-dev.git
+	branch = master
+[submodule "lib/SDL2"]
+	path = lib/SDL2
+	url = https://gitee.com/devlib/SDL2-dev.git
+	branch = master

+ 4 - 2
source/AudioDecode/AudioDecode.pro

@@ -38,12 +38,14 @@ OBJECTS_DIR = obj/Obj
 #DESTDIR=$$PWD/bin/
 contains(QT_ARCH, i386) {
     message("32-bit")
-    DESTDIR = $${PWD}/bin/bin32
+    DESTDIR = $${PWD}/../..//bin/win32
 } else {
     message("64-bit")
-    DESTDIR = $${PWD}/bin/bin64
+    DESTDIR = $${PWD}/../../bin/win64
 }
 
+include($$PWD/../../lib/lib.pri)
+
 #包含音频解码的代码
 include(AudioDecoder/AudioDecoder.pri)
 

+ 1 - 58
source/AudioDecode/AudioDecoder/AudioDecoder.pri

@@ -1,6 +1,7 @@
 CONFIG += c++11
 QMAKE_CXXFLAGS += -std=c++11
 
+INCLUDEPATH += $$PWD/src
 
 SOURCES += \
         $$PWD/src/MoudleConfig.cpp \
@@ -31,61 +32,3 @@ HEADERS += \
         $$PWD/src/EventHandle/AudioPlayerEventHandle.h \
         $$PWD/src/Mutex/Cond.h \
         $$PWD/src/Mutex/Mutex.h
-
-
-include($$PWD/lib/RtAudio/RtAudio.pri)
-
-win32{
-
-    DEFINES += NDEBUG WIN32 _CONSOLE __WINDOWS_ASIO__ __WINDOWS_DS__ __WINDOWS_WASAPI__
-
-    contains(QT_ARCH, i386) {
-        message("32-bit")
-        INCLUDEPATH += $$PWD/lib/win32/ffmpeg/include \
-                       $$PWD/lib/win32/SDL2/include \
-                       $$PWD/src
-
-        LIBS += -L$$PWD/lib/win32/ffmpeg/lib -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lpostproc -lswresample -lswscale
-        LIBS += -L$$PWD/lib/win32/SDL2/lib -lSDL2
-    } else {
-        message("64-bit")
-        INCLUDEPATH += $$PWD/lib/win64/ffmpeg/include \
-                       $$PWD/lib/win64/SDL2/include \
-                       $$PWD/src
-
-        LIBS += -L$$PWD/lib/win64/ffmpeg/lib -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lpostproc -lswresample -lswscale
-        LIBS += -L$$PWD/lib/win64/SDL2/lib -lSDL2
-    }
-
-    LIBS += -lmfplat -lmfuuid -lksuser -lwinmm -lwmcodecdspuuid
-}
-
-unix{
-
-    DEFINES += NDEBUG _CONSOLE __LINUX_ALSA__
-
-    contains(QT_ARCH, i386) {
-        message("32-bit, 请自行编译32位库!")
-    } else {
-        message("64-bit")
-        INCLUDEPATH += $$PWD/lib/linux/ffmpeg/include \
-                       $$PWD/lib/linux/SDL2/include/SDL2 \
-                       $$PWD/lib/linux/alsa/include \
-                       $$PWD/src
-
-        LIBS += -L$$PWD/lib/linux/ffmpeg/lib  -lavformat  -lavcodec -lavdevice -lavfilter -lavutil -lswresample -lswscale -lpostproc
-        LIBS += -L$$PWD/lib/linux/SDL2/lib -lSDL2
-        LIBS += -L$$PWD/lib/linux/alsa/lib -lasound
-        LIBS += -lpthread -ldl
-    }
-
-    #QMAKE_POST_LINK 表示编译后执行内容
-    #QMAKE_PRE_LINK 表示编译前执行内容
-
-    #解压库文件
-    #QMAKE_PRE_LINK += "cd $$PWD/lib/linux && tar xvzf ffmpeg.tar.gz "
-
-    system("cd $$PWD/lib/linux && tar xvzf ffmpeg.tar.gz")
-    system("cd $$PWD/lib/linux && tar xvzf SDL2.tar.gz")
-    system("cd $$PWD/lib/linux && tar xvzf alsa.tar.gz")
-}

+ 0 - 56
source/AudioDecode/AudioDecoder/lib/RtAudio/RtAudio.pri

@@ -1,56 +0,0 @@
-
-INCLUDEPATH += $$PWD/src
-
-INCLUDEPATH += $$PWD/include
-
-win32{
-
-HEADERS += \
-    $$PWD/include/asio.h \
-    $$PWD/include/asiodrivers.h \
-    $$PWD/include/asiodrvr.h \
-    $$PWD/include/asiolist.h \
-    $$PWD/include/asiosys.h \
-    $$PWD/include/dsound.h \
-    $$PWD/include/functiondiscoverykeys_devpkey.h \
-    $$PWD/include/ginclude.h \
-    $$PWD/include/iasiodrv.h \
-    $$PWD/include/iasiothiscallresolver.h \
-    $$PWD/include/soundcard.h \
-    $$PWD/src/RtAudio.h \
-    $$PWD/src/rtaudio_c.h
-
-SOURCES += \
-    $$PWD/include/asio.cpp \
-    $$PWD/include/asiodrivers.cpp \
-    $$PWD/include/asiolist.cpp \
-    $$PWD/include/iasiothiscallresolver.cpp \
-    $$PWD/src/RtAudio.cpp \
-    $$PWD/src/rtaudio_c.cpp
-
-    LIBS += -lAdvapi32 -luser32 -lole32 -ldsound
-}
-
-unix{
-
-HEADERS += \
-    $$PWD/include/asio.h \
-    $$PWD/include/asiodrivers.h \
-    $$PWD/include/asiodrvr.h \
-    $$PWD/include/asiolist.h \
-    $$PWD/include/asiosys.h \
-    $$PWD/include/dsound.h \
-    $$PWD/include/functiondiscoverykeys_devpkey.h \
-    $$PWD/include/ginclude.h \
-    $$PWD/include/soundcard.h \
-    $$PWD/src/RtAudio.h \
-    $$PWD/src/rtaudio_c.h
-
-SOURCES += \
-    $$PWD/src/RtAudio.cpp \
-    $$PWD/src/rtaudio_c.cpp
-
-}
-
-DISTFILES += \
-    $$PWD/src/rtaudio.pc.in

+ 0 - 258
source/AudioDecode/AudioDecoder/lib/RtAudio/include/asio.cpp

@@ -1,258 +0,0 @@
-/*
-	Steinberg Audio Stream I/O API
-	(c) 1996, Steinberg Soft- und Hardware GmbH
-
-	asio.cpp
-	
-	asio functions entries which translate the
-	asio interface to the asiodrvr class methods
-*/ 
-	
-#include <string.h>
-#include "asiosys.h"		// platform definition
-#include "asio.h"
-
-#if MAC
-#include "asiodrvr.h"
-
-#pragma export on
-
-AsioDriver *theAsioDriver = 0;
-
-extern "C"
-{
-
-long main()
-{
-	return 'ASIO';
-}
-
-#elif WINDOWS
-
-#include <WinSock2.h>
-#include <Windows.h>
-#include "iasiodrv.h"
-#include "asiodrivers.h"
-
-IASIO *theAsioDriver = 0;
-extern AsioDrivers *asioDrivers;
-
-#elif SGI || SUN || BEOS || LINUX
-#include "asiodrvr.h"
-static AsioDriver *theAsioDriver = 0;
-#endif
-
-//-----------------------------------------------------------------------------------------------------
-ASIOError ASIOInit(ASIODriverInfo *info)
-{
-#if MAC || SGI || SUN || BEOS || LINUX
-	if(theAsioDriver)
-	{
-		delete theAsioDriver;
-		theAsioDriver = 0;
-	}		
-	info->driverVersion = 0;
-	strcpy(info->name, "No ASIO Driver");
-	theAsioDriver = getDriver();
-	if(!theAsioDriver)
-	{
-		strcpy(info->errorMessage, "Not enough memory for the ASIO driver!"); 
-		return ASE_NotPresent;
-	}
-	if(!theAsioDriver->init(info->sysRef))
-	{
-		theAsioDriver->getErrorMessage(info->errorMessage);
-		delete theAsioDriver;
-		theAsioDriver = 0;
-		return ASE_NotPresent;
-	}
-	strcpy(info->errorMessage, "No ASIO Driver Error");
-	theAsioDriver->getDriverName(info->name);
-	info->driverVersion = theAsioDriver->getDriverVersion();
-	return ASE_OK;
-
-#else
-
-	info->driverVersion = 0;
-	strcpy(info->name, "No ASIO Driver");
-	if(theAsioDriver)	// must be loaded!
-	{
-		if(!theAsioDriver->init(info->sysRef))
-		{
-			theAsioDriver->getErrorMessage(info->errorMessage);
-			theAsioDriver = 0;
-			return ASE_NotPresent;
-		}		
-
-		strcpy(info->errorMessage, "No ASIO Driver Error");
-		theAsioDriver->getDriverName(info->name);
-		info->driverVersion = theAsioDriver->getDriverVersion();
-		return ASE_OK;
-	}
-	return ASE_NotPresent;
-
-#endif	// !MAC
-}
-
-ASIOError ASIOExit(void)
-{
-	if(theAsioDriver)
-	{
-#if WINDOWS
-		asioDrivers->removeCurrentDriver();
-#else
-		delete theAsioDriver;
-#endif
-	}		
-	theAsioDriver = 0;
-	return ASE_OK;
-}
-
-ASIOError ASIOStart(void)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->start();
-}
-
-ASIOError ASIOStop(void)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->stop();
-}
-
-ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels)
-{
-	if(!theAsioDriver)
-	{
-		*numInputChannels = *numOutputChannels = 0;
-		return ASE_NotPresent;
-	}
-	return theAsioDriver->getChannels(numInputChannels, numOutputChannels);
-}
-
-ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency)
-{
-	if(!theAsioDriver)
-	{
-		*inputLatency = *outputLatency = 0;
-		return ASE_NotPresent;
-	}
-	return theAsioDriver->getLatencies(inputLatency, outputLatency);
-}
-
-ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity)
-{
-	if(!theAsioDriver)
-	{
-		*minSize = *maxSize = *preferredSize = *granularity = 0;
-		return ASE_NotPresent;
-	}
-	return theAsioDriver->getBufferSize(minSize, maxSize, preferredSize, granularity);
-}
-
-ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->canSampleRate(sampleRate);
-}
-
-ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->getSampleRate(currentRate);
-}
-
-ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->setSampleRate(sampleRate);
-}
-
-ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources)
-{
-	if(!theAsioDriver)
-	{
-		*numSources = 0;
-		return ASE_NotPresent;
-	}
-	return theAsioDriver->getClockSources(clocks, numSources);
-}
-
-ASIOError ASIOSetClockSource(long reference)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->setClockSource(reference);
-}
-
-ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->getSamplePosition(sPos, tStamp);
-}
-
-ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info)
-{
-	if(!theAsioDriver)
-	{
-		info->channelGroup = -1;
-		info->type = ASIOSTInt16MSB;
-		strcpy(info->name, "None");
-		return ASE_NotPresent;
-	}
-	return theAsioDriver->getChannelInfo(info);
-}
-
-ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
-	long bufferSize, ASIOCallbacks *callbacks)
-{
-	if(!theAsioDriver)
-	{
-		ASIOBufferInfo *info = bufferInfos;
-		for(long i = 0; i < numChannels; i++, info++)
-			info->buffers[0] = info->buffers[1] = 0;
-		return ASE_NotPresent;
-	}
-	return theAsioDriver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks);
-}
-
-ASIOError ASIODisposeBuffers(void)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->disposeBuffers();
-}
-
-ASIOError ASIOControlPanel(void)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->controlPanel();
-}
-
-ASIOError ASIOFuture(long selector, void *opt)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->future(selector, opt);
-}
-
-ASIOError ASIOOutputReady(void)
-{
-	if(!theAsioDriver)
-		return ASE_NotPresent;
-	return theAsioDriver->outputReady();
-}
-
-#if MAC
-}	// extern "C"
-#pragma export off
-#endif
-
-

+ 0 - 1070
source/AudioDecode/AudioDecoder/lib/RtAudio/include/asio.h

@@ -1,1070 +0,0 @@
-//---------------------------------------------------------------------------------------------------
-//---------------------------------------------------------------------------------------------------
-
-/*
-	Steinberg Audio Stream I/O API
-	(c) 1997 - 2013, Steinberg Media Technologies GmbH
-
-	ASIO Interface Specification v 2.3
-
-	2005 - Added support for DSD sample data (in cooperation with Sony)
-	2012 - Added support for drop out detection
-		
-	
-
-	basic concept is an i/o synchronous double-buffer scheme:
-	
-	on bufferSwitch(index == 0), host will read/write:
-
-		after ASIOStart(), the
-  read  first input buffer A (index 0)
-	|   will be invalid (empty)
-	*   ------------------------
-	|------------------------|-----------------------|
-	|                        |                       |
-	|  Input Buffer A (0)    |   Input Buffer B (1)  |
-	|                        |                       |
-	|------------------------|-----------------------|
-	|                        |                       |
-	|  Output Buffer A (0)   |   Output Buffer B (1) |
-	|                        |                       |
-	|------------------------|-----------------------|
-	*                        -------------------------
-	|                        before calling ASIOStart(),
-  write                      host will have filled output
-                             buffer B (index 1) already
-
-  *please* take special care of proper statement of input
-  and output latencies (see ASIOGetLatencies()), these
-  control sequencer sync accuracy
-
-*/
-
-//---------------------------------------------------------------------------------------------------
-//---------------------------------------------------------------------------------------------------
-
-/*
-
-prototypes summary:
-
-ASIOError ASIOInit(ASIODriverInfo *info);
-ASIOError ASIOExit(void);
-ASIOError ASIOStart(void);
-ASIOError ASIOStop(void);
-ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels);
-ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);
-ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);
-ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate);
-ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate);
-ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate);
-ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);
-ASIOError ASIOSetClockSource(long reference);
-ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);
-ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);
-ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
-	long bufferSize, ASIOCallbacks *callbacks);
-ASIOError ASIODisposeBuffers(void);
-ASIOError ASIOControlPanel(void);
-void *ASIOFuture(long selector, void *params);
-ASIOError ASIOOutputReady(void);
-
-*/
-
-//---------------------------------------------------------------------------------------------------
-//---------------------------------------------------------------------------------------------------
-
-#ifndef __ASIO_H
-#define __ASIO_H
-
-// force 4 byte alignment
-#if defined(_MSC_VER) && !defined(__MWERKS__) 
-#pragma pack(push,4)
-#elif PRAGMA_ALIGN_SUPPORTED
-#pragma options align = native
-#endif
-
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-// Type definitions
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-
-// number of samples data type is 64 bit integer
-#if NATIVE_INT64
-	typedef long long int ASIOSamples;
-#else
-	typedef struct ASIOSamples {
-		unsigned long hi;
-		unsigned long lo;
-	} ASIOSamples;
-#endif
-
-// Timestamp data type is 64 bit integer,
-// Time format is Nanoseconds.
-#if NATIVE_INT64
-	typedef long long int ASIOTimeStamp ;
-#else
-	typedef struct ASIOTimeStamp {
-		unsigned long hi;
-		unsigned long lo;
-	} ASIOTimeStamp;
-#endif
-
-// Samplerates are expressed in IEEE 754 64 bit double float,
-// native format as host computer
-#if IEEE754_64FLOAT
-	typedef double ASIOSampleRate;
-#else
-	typedef struct ASIOSampleRate {
-		char ieee[8];
-	} ASIOSampleRate;
-#endif
-
-// Boolean values are expressed as long
-typedef long ASIOBool;
-enum {
-	ASIOFalse = 0,
-	ASIOTrue = 1
-};
-
-// Sample Types are expressed as long
-typedef long ASIOSampleType;
-enum {
-	ASIOSTInt16MSB   = 0,
-	ASIOSTInt24MSB   = 1,		// used for 20 bits as well
-	ASIOSTInt32MSB   = 2,
-	ASIOSTFloat32MSB = 3,		// IEEE 754 32 bit float
-	ASIOSTFloat64MSB = 4,		// IEEE 754 64 bit double float
-
-	// these are used for 32 bit data buffer, with different alignment of the data inside
-	// 32 bit PCI bus systems can be more easily used with these
-	ASIOSTInt32MSB16 = 8,		// 32 bit data with 16 bit alignment
-	ASIOSTInt32MSB18 = 9,		// 32 bit data with 18 bit alignment
-	ASIOSTInt32MSB20 = 10,		// 32 bit data with 20 bit alignment
-	ASIOSTInt32MSB24 = 11,		// 32 bit data with 24 bit alignment
-	
-	ASIOSTInt16LSB   = 16,
-	ASIOSTInt24LSB   = 17,		// used for 20 bits as well
-	ASIOSTInt32LSB   = 18,
-	ASIOSTFloat32LSB = 19,		// IEEE 754 32 bit float, as found on Intel x86 architecture
-	ASIOSTFloat64LSB = 20, 		// IEEE 754 64 bit double float, as found on Intel x86 architecture
-
-	// these are used for 32 bit data buffer, with different alignment of the data inside
-	// 32 bit PCI bus systems can more easily used with these
-	ASIOSTInt32LSB16 = 24,		// 32 bit data with 18 bit alignment
-	ASIOSTInt32LSB18 = 25,		// 32 bit data with 18 bit alignment
-	ASIOSTInt32LSB20 = 26,		// 32 bit data with 20 bit alignment
-	ASIOSTInt32LSB24 = 27,		// 32 bit data with 24 bit alignment
-
-	//	ASIO DSD format.
-	ASIOSTDSDInt8LSB1   = 32,		// DSD 1 bit data, 8 samples per byte. First sample in Least significant bit.
-	ASIOSTDSDInt8MSB1   = 33,		// DSD 1 bit data, 8 samples per byte. First sample in Most significant bit.
-	ASIOSTDSDInt8NER8	= 40,		// DSD 8 bit data, 1 sample per byte. No Endianness required.
-
-	ASIOSTLastEntry
-};
-
-/*-----------------------------------------------------------------------------
-// DSD operation and buffer layout
-// Definition by Steinberg/Sony Oxford.
-//
-// We have tried to treat DSD as PCM and so keep a consistant structure across
-// the ASIO interface.
-//
-// DSD's sample rate is normally referenced as a multiple of 44.1Khz, so
-// the standard sample rate is refered to as 64Fs (or 2.8224Mhz). We looked
-// at making a special case for DSD and adding a field to the ASIOFuture that
-// would allow the user to select the Over Sampleing Rate (OSR) as a seperate
-// entity but decided in the end just to treat it as a simple value of
-// 2.8224Mhz and use the standard interface to set it.
-//
-// The second problem was the "word" size, in PCM the word size is always a
-// greater than or equal to 8 bits (a byte). This makes life easy as we can
-// then pack the samples into the "natural" size for the machine.
-// In DSD the "word" size is 1 bit. This is not a major problem and can easily
-// be dealt with if we ensure that we always deal with a multiple of 8 samples.
-//
-// DSD brings with it another twist to the Endianness religion. How are the
-// samples packed into the byte. It would be nice to just say the most significant
-// bit is always the first sample, however there would then be a performance hit
-// on little endian machines. Looking at how some of the processing goes...
-// Little endian machines like the first sample to be in the Least Significant Bit,
-//   this is because when you write it to memory the data is in the correct format
-//   to be shifted in and out of the words.
-// Big endian machine prefer the first sample to be in the Most Significant Bit,
-//   again for the same reasion.
-//
-// And just when things were looking really muddy there is a proposed extension to
-// DSD that uses 8 bit word sizes. It does not care what endianness you use.
-//
-// Switching the driver between DSD and PCM mode
-// ASIOFuture allows for extending the ASIO API quite transparently.
-// See kAsioSetIoFormat, kAsioGetIoFormat, kAsioCanDoIoFormat
-//
-//-----------------------------------------------------------------------------*/
-
-
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-// Error codes
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-
-typedef long ASIOError;
-enum {
-	ASE_OK = 0,             // This value will be returned whenever the call succeeded
-	ASE_SUCCESS = 0x3f4847a0,	// unique success return value for ASIOFuture calls
-	ASE_NotPresent = -1000, // hardware input or output is not present or available
-	ASE_HWMalfunction,      // hardware is malfunctioning (can be returned by any ASIO function)
-	ASE_InvalidParameter,   // input parameter invalid
-	ASE_InvalidMode,        // hardware is in a bad mode or used in a bad mode
-	ASE_SPNotAdvancing,     // hardware is not running when sample position is inquired
-	ASE_NoClock,            // sample clock or rate cannot be determined or is not present
-	ASE_NoMemory            // not enough memory for completing the request
-};
-
-//---------------------------------------------------------------------------------------------------
-//---------------------------------------------------------------------------------------------------
-
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-// Time Info support
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-
-typedef struct ASIOTimeCode
-{       
-	double          speed;                  // speed relation (fraction of nominal speed)
-	                                        // optional; set to 0. or 1. if not supported
-	ASIOSamples     timeCodeSamples;        // time in samples
-	unsigned long   flags;                  // some information flags (see below)
-	char future[64];
-} ASIOTimeCode;
-
-typedef enum ASIOTimeCodeFlags
-{
-	kTcValid                = 1,
-	kTcRunning              = 1 << 1,
-	kTcReverse              = 1 << 2,
-	kTcOnspeed              = 1 << 3,
-	kTcStill                = 1 << 4,
-	
-	kTcSpeedValid           = 1 << 8
-}  ASIOTimeCodeFlags;
-
-typedef struct AsioTimeInfo
-{
-	double          speed;                  // absolute speed (1. = nominal)
-	ASIOTimeStamp   systemTime;             // system time related to samplePosition, in nanoseconds
-	                                        // on mac, must be derived from Microseconds() (not UpTime()!)
-	                                        // on windows, must be derived from timeGetTime()
-	ASIOSamples     samplePosition;
-	ASIOSampleRate  sampleRate;             // current rate
-	unsigned long flags;                    // (see below)
-	char reserved[12];
-} AsioTimeInfo;
-
-typedef enum AsioTimeInfoFlags
-{
-	kSystemTimeValid        = 1,            // must always be valid
-	kSamplePositionValid    = 1 << 1,       // must always be valid
-	kSampleRateValid        = 1 << 2,
-	kSpeedValid             = 1 << 3,
-	
-	kSampleRateChanged      = 1 << 4,
-	kClockSourceChanged     = 1 << 5
-} AsioTimeInfoFlags;
-
-typedef struct ASIOTime                          // both input/output
-{
-	long reserved[4];                       // must be 0
-	struct AsioTimeInfo     timeInfo;       // required
-	struct ASIOTimeCode     timeCode;       // optional, evaluated if (timeCode.flags & kTcValid)
-} ASIOTime;
-
-/*
-
-using time info:
-it is recommended to use the new method with time info even if the asio
-device does not support timecode; continuous calls to ASIOGetSamplePosition
-and ASIOGetSampleRate are avoided, and there is a more defined relationship
-between callback time and the time info.
-
-see the example below.
-to initiate time info mode, after you have received the callbacks pointer in
-ASIOCreateBuffers, you will call the asioMessage callback with kAsioSupportsTimeInfo
-as the argument. if this returns 1, host has accepted time info mode.
-now host expects the new callback bufferSwitchTimeInfo to be used instead
-of the old bufferSwitch method. the ASIOTime structure is assumed to be valid
-and accessible until the callback returns.
-
-using time code:
-if the device supports reading time code, it will call host's asioMessage callback
-with kAsioSupportsTimeCode as the selector. it may then fill the according
-fields and set the kTcValid flag.
-host will call the future method with the kAsioEnableTimeCodeRead selector when
-it wants to enable or disable tc reading by the device. you should also support
-the kAsioCanTimeInfo and kAsioCanTimeCode selectors in ASIOFuture (see example).
-
-note:
-the AsioTimeInfo/ASIOTimeCode pair is supposed to work in both directions.
-as a matter of convention, the relationship between the sample
-position counter and the time code at buffer switch time is
-(ignoring offset between tc and sample pos when tc is running):
-
-on input:	sample 0 -> input  buffer sample 0 -> time code 0
-on output:	sample 0 -> output buffer sample 0 -> time code 0
-
-this means that for 'real' calculations, one has to take into account
-the according latencies.
-
-example:
-
-ASIOTime asioTime;
-
-in createBuffers()
-{
-	memset(&asioTime, 0, sizeof(ASIOTime));
-	AsioTimeInfo* ti = &asioTime.timeInfo;
-	ti->sampleRate = theSampleRate;
-	ASIOTimeCode* tc = &asioTime.timeCode;
-	tc->speed = 1.;
-	timeInfoMode = false;
-	canTimeCode = false;
-	if(callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0) == 1)
-	{
-		timeInfoMode = true;
-#if kCanTimeCode
-		if(callbacks->asioMessage(kAsioSupportsTimeCode, 0, 0, 0) == 1)
-			canTimeCode = true;
-#endif
-	}
-}
-
-void switchBuffers(long doubleBufferIndex, bool processNow)
-{
-	if(timeInfoMode)
-	{
-		AsioTimeInfo* ti = &asioTime.timeInfo;
-		ti->flags =	kSystemTimeValid | kSamplePositionValid | kSampleRateValid;
-		ti->systemTime = theNanoSeconds;
-		ti->samplePosition = theSamplePosition;
-		if(ti->sampleRate != theSampleRate)
-			ti->flags |= kSampleRateChanged;
-		ti->sampleRate = theSampleRate;
-
-#if kCanTimeCode
-		if(canTimeCode && timeCodeEnabled)
-		{
-			ASIOTimeCode* tc = &asioTime.timeCode;
-			tc->timeCodeSamples = tcSamples;						// tc in samples
-			tc->flags = kTcValid | kTcRunning | kTcOnspeed;			// if so...
-		}
-		ASIOTime* bb = callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse);
-#else
-		callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse);
-#endif
-	}
-	else
-		callbacks->bufferSwitch(doubleBufferIndex, ASIOFalse);
-}
-
-ASIOError ASIOFuture(long selector, void *params)
-{
-	switch(selector)
-	{
-		case kAsioEnableTimeCodeRead:
-			timeCodeEnabled = true;
-			return ASE_SUCCESS;
-		case kAsioDisableTimeCodeRead:
-			timeCodeEnabled = false;
-			return ASE_SUCCESS;
-		case kAsioCanTimeInfo:
-			return ASE_SUCCESS;
-		#if kCanTimeCode
-		case kAsioCanTimeCode:
-			return ASE_SUCCESS;
-		#endif
-	}
-	return ASE_NotPresent;
-};
-
-*/
-
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-// application's audio stream handler callbacks
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-
-typedef struct ASIOCallbacks
-{
-	void (*bufferSwitch) (long doubleBufferIndex, ASIOBool directProcess);
-		// bufferSwitch indicates that both input and output are to be processed.
-		// the current buffer half index (0 for A, 1 for B) determines
-		// - the output buffer that the host should start to fill. the other buffer
-		//   will be passed to output hardware regardless of whether it got filled
-		//   in time or not.
-		// - the input buffer that is now filled with incoming data. Note that
-		//   because of the synchronicity of i/o, the input always has at
-		//   least one buffer latency in relation to the output.
-		// directProcess suggests to the host whether it should immedeately
-		// start processing (directProcess == ASIOTrue), or whether its process
-		// should be deferred because the call comes from a very low level
-		// (for instance, a high level priority interrupt), and direct processing
-		// would cause timing instabilities for the rest of the system. If in doubt,
-		// directProcess should be set to ASIOFalse.
-		// Note: bufferSwitch may be called at interrupt time for highest efficiency.
-
-	void (*sampleRateDidChange) (ASIOSampleRate sRate);
-		// gets called when the AudioStreamIO detects a sample rate change
-		// If sample rate is unknown, 0 is passed (for instance, clock loss
-		// when externally synchronized).
-
-	long (*asioMessage) (long selector, long value, void* message, double* opt);
-		// generic callback for various purposes, see selectors below.
-		// note this is only present if the asio version is 2 or higher
-
-	ASIOTime* (*bufferSwitchTimeInfo) (ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess);
-		// new callback with time info. makes ASIOGetSamplePosition() and various
-		// calls to ASIOGetSampleRate obsolete,
-		// and allows for timecode sync etc. to be preferred; will be used if
-		// the driver calls asioMessage with selector kAsioSupportsTimeInfo.
-} ASIOCallbacks;
-
-// asioMessage selectors
-enum
-{
-	kAsioSelectorSupported = 1,	// selector in <value>, returns 1L if supported,
-								// 0 otherwise
-    kAsioEngineVersion,			// returns engine (host) asio implementation version,
-								// 2 or higher
-	kAsioResetRequest,			// request driver reset. if accepted, this
-								// will close the driver (ASIO_Exit() ) and
-								// re-open it again (ASIO_Init() etc). some
-								// drivers need to reconfigure for instance
-								// when the sample rate changes, or some basic
-								// changes have been made in ASIO_ControlPanel().
-								// returns 1L; note the request is merely passed
-								// to the application, there is no way to determine
-								// if it gets accepted at this time (but it usually
-								// will be).
-	kAsioBufferSizeChange,		// not yet supported, will currently always return 0L.
-								// for now, use kAsioResetRequest instead.
-								// once implemented, the new buffer size is expected
-								// in <value>, and on success returns 1L
-	kAsioResyncRequest,			// the driver went out of sync, such that
-								// the timestamp is no longer valid. this
-								// is a request to re-start the engine and
-								// slave devices (sequencer). returns 1 for ok,
-								// 0 if not supported.
-	kAsioLatenciesChanged, 		// the drivers latencies have changed. The engine
-								// will refetch the latencies.
-	kAsioSupportsTimeInfo,		// if host returns true here, it will expect the
-								// callback bufferSwitchTimeInfo to be called instead
-								// of bufferSwitch
-	kAsioSupportsTimeCode,		// 
-	kAsioMMCCommand,			// unused - value: number of commands, message points to mmc commands
-	kAsioSupportsInputMonitor,	// kAsioSupportsXXX return 1 if host supports this
-	kAsioSupportsInputGain,     // unused and undefined
-	kAsioSupportsInputMeter,    // unused and undefined
-	kAsioSupportsOutputGain,    // unused and undefined
-	kAsioSupportsOutputMeter,   // unused and undefined
-	kAsioOverload,              // driver detected an overload
-
-	kAsioNumMessageSelectors
-};
-
-//---------------------------------------------------------------------------------------------------
-//---------------------------------------------------------------------------------------------------
-
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-// (De-)Construction
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-
-typedef struct ASIODriverInfo
-{
-	long asioVersion;		// currently, 2
-	long driverVersion;		// driver specific
-	char name[32];
-	char errorMessage[124];
-	void *sysRef;			// on input: system reference
-							// (Windows: application main window handle, Mac & SGI: 0)
-} ASIODriverInfo;
-
-ASIOError ASIOInit(ASIODriverInfo *info);
-/* Purpose:
-	  Initialize the AudioStreamIO.
-	Parameter:
-	  info: pointer to an ASIODriver structure:
-	    - asioVersion:
-			- on input, the host version. *** Note *** this is 0 for earlier asio
-			implementations, and the asioMessage callback is implemeted
-			only if asioVersion is 2 or greater. sorry but due to a design fault
-			the driver doesn't have access to the host version in ASIOInit :-(
-			added selector for host (engine) version in the asioMessage callback
-			so we're ok from now on.
-			- on return, asio implementation version.
-			  older versions are 1
-			  if you support this version (namely, ASIO_outputReady() )
-			  this should be 2 or higher. also see the note in
-			  ASIO_getTimeStamp() !
-	    - version: on return, the driver version (format is driver specific)
-	    - name: on return, a null-terminated string containing the driver's name
-		- error message: on return, should contain a user message describing
-		  the type of error that occured during ASIOInit(), if any.
-		- sysRef: platform specific
-	Returns:
-	  If neither input nor output is present ASE_NotPresent
-	  will be returned.
-	  ASE_NoMemory, ASE_HWMalfunction are other possible error conditions
-*/
-
-ASIOError ASIOExit(void);
-/* Purpose:
-	  Terminates the AudioStreamIO.
-	Parameter:
-	  None.
-	Returns:
-	  If neither input nor output is present ASE_NotPresent
-	  will be returned.
-	Notes: this implies ASIOStop() and ASIODisposeBuffers(),
-	  meaning that no host callbacks must be accessed after ASIOExit().
-*/
-
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-// Start/Stop
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-
-ASIOError ASIOStart(void);
-/* Purpose:
-	  Start input and output processing synchronously.
-	  This will
-	  - reset the sample counter to zero
-	  - start the hardware (both input and output)
-	    The first call to the hosts' bufferSwitch(index == 0) then tells
-	    the host to read from input buffer A (index 0), and start
-	    processing to output buffer A while output buffer B (which
-	    has been filled by the host prior to calling ASIOStart())
-	    is possibly sounding (see also ASIOGetLatencies()) 
-	Parameter:
-	  None.
-	Returns:
-	  If neither input nor output is present, ASE_NotPresent
-	  will be returned.
-	  If the hardware fails to start, ASE_HWMalfunction will be returned.
-	Notes:
-	  There is no restriction on the time that ASIOStart() takes
-	  to perform (that is, it is not considered a realtime trigger).
-*/
-
-ASIOError ASIOStop(void);
-/* Purpose:
-	  Stops input and output processing altogether.
-	Parameter:
-	  None.
-	Returns:
-	  If neither input nor output is present ASE_NotPresent
-	  will be returned.
-	Notes:
-	  On return from ASIOStop(), the driver must in no
-	  case call the hosts' bufferSwitch() routine.
-*/
-
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-// Inquiry methods and sample rate
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-
-ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels);
-/* Purpose:
-	  Returns number of individual input/output channels.
-	Parameter:
-	  numInputChannels will hold the number of available input channels
-	  numOutputChannels will hold the number of available output channels
-	Returns:
-	  If no input/output is present ASE_NotPresent will be returned.
-	  If only inputs, or only outputs are available, the according
-	  other parameter will be zero, and ASE_OK is returned.
-*/
-
-ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);
-/* Purpose:
-	  Returns the input and output latencies. This includes
-	  device specific delays, like FIFOs etc.
-	Parameter:
-	  inputLatency will hold the 'age' of the first sample frame
-	  in the input buffer when the hosts reads it in bufferSwitch()
-	  (this is theoretical, meaning it does not include the overhead
-	  and delay between the actual physical switch, and the time
-	  when bufferSitch() enters).
-	  This will usually be the size of one block in sample frames, plus
-	  device specific latencies.
-
-	  outputLatency will specify the time between the buffer switch,
-	  and the time when the next play buffer will start to sound.
-	  The next play buffer is defined as the one the host starts
-	  processing after (or at) bufferSwitch(), indicated by the
-	  index parameter (0 for buffer A, 1 for buffer B).
-	  It will usually be either one block, if the host writes directly
-	  to a dma buffer, or two or more blocks if the buffer is 'latched' by
-	  the driver. As an example, on ASIOStart(), the host will have filled
-	  the play buffer at index 1 already; when it gets the callback (with
-	  the parameter index == 0), this tells it to read from the input
-	  buffer 0, and start to fill the play buffer 0 (assuming that now
-	  play buffer 1 is already sounding). In this case, the output
-	  latency is one block. If the driver decides to copy buffer 1
-	  at that time, and pass it to the hardware at the next slot (which
-	  is most commonly done, but should be avoided), the output latency
-	  becomes two blocks instead, resulting in a total i/o latency of at least
-	  3 blocks. As memory access is the main bottleneck in native dsp processing,
-	  and to acheive less latency, it is highly recommended to try to avoid
-	  copying (this is also why the driver is the owner of the buffers). To
-	  summarize, the minimum i/o latency can be acheived if the input buffer
-	  is processed by the host into the output buffer which will physically
-	  start to sound on the next time slice. Also note that the host expects
-	  the bufferSwitch() callback to be accessed for each time slice in order
-	  to retain sync, possibly recursively; if it fails to process a block in
-	  time, it will suspend its operation for some time in order to recover.
-	Returns:
-	  If no input/output is present ASE_NotPresent will be returned.
-*/
-
-ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);
-/* Purpose:
-	  Returns min, max, and preferred buffer sizes for input/output
-	Parameter:
-	  minSize will hold the minimum buffer size
-	  maxSize will hold the maxium possible buffer size
-	  preferredSize will hold the preferred buffer size (a size which
-	  best fits performance and hardware requirements)
-	  granularity will hold the granularity at which buffer sizes
-	  may differ. Usually, the buffer size will be a power of 2;
-	  in this case, granularity will hold -1 on return, signalling
-	  possible buffer sizes starting from minSize, increased in
-	  powers of 2 up to maxSize.
-	Returns:
-	  If no input/output is present ASE_NotPresent will be returned.
-	Notes:
-	  When minimum and maximum buffer size are equal,
-	  the preferred buffer size has to be the same value as well; granularity
-	  should be 0 in this case.
-*/
-
-ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate);
-/* Purpose:
-	  Inquires the hardware for the available sample rates.
-	Parameter:
-	  sampleRate is the rate in question.
-	Returns:
-	  If the inquired sample rate is not supported, ASE_NoClock will be returned.
-	  If no input/output is present ASE_NotPresent will be returned.
-*/
-ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate);
-/* Purpose:
-	  Get the current sample Rate.
-	Parameter:
-	  currentRate will hold the current sample rate on return.
-	Returns:
-	  If sample rate is unknown, sampleRate will be 0 and ASE_NoClock will be returned.
-	  If no input/output is present ASE_NotPresent will be returned.
-	Notes:
-*/
-
-ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate);
-/* Purpose:
-	  Set the hardware to the requested sample Rate. If sampleRate == 0,
-	  enable external sync.
-	Parameter:
-	  sampleRate: on input, the requested rate
-	Returns:
-	  If sampleRate is unknown ASE_NoClock will be returned.
-	  If the current clock is external, and sampleRate is != 0,
-	  ASE_InvalidMode will be returned
-	  If no input/output is present ASE_NotPresent will be returned.
-	Notes:
-*/
-
-typedef struct ASIOClockSource
-{
-	long index;					// as used for ASIOSetClockSource()
-	long associatedChannel;		// for instance, S/PDIF or AES/EBU
-	long associatedGroup;		// see channel groups (ASIOGetChannelInfo())
-	ASIOBool isCurrentSource;	// ASIOTrue if this is the current clock source
-	char name[32];				// for user selection
-} ASIOClockSource;
-
-ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);
-/* Purpose:
-	  Get the available external audio clock sources
-	Parameter:
-	  clocks points to an array of ASIOClockSource structures:
-	  	- index: this is used to identify the clock source
-	  	  when ASIOSetClockSource() is accessed, should be
-	  	  an index counting from zero
-	  	- associatedInputChannel: the first channel of an associated
-	  	  input group, if any.
-	  	- associatedGroup: the group index of that channel.
-	  	  groups of channels are defined to seperate for
-	  	  instance analog, S/PDIF, AES/EBU, ADAT connectors etc,
-	  	  when present simultaniously. Note that associated channel
-	  	  is enumerated according to numInputs/numOutputs, means it
-	  	  is independant from a group (see also ASIOGetChannelInfo())
-	  	  inputs are associated to a clock if the physical connection
-	  	  transfers both data and clock (like S/PDIF, AES/EBU, or
-	  	  ADAT inputs). if there is no input channel associated with
-	  	  the clock source (like Word Clock, or internal oscillator), both
-	  	  associatedChannel and associatedGroup should be set to -1.
-	  	- isCurrentSource: on exit, ASIOTrue if this is the current clock
-	  	  source, ASIOFalse else
-		- name: a null-terminated string for user selection of the available sources.
-	  numSources:
-	      on input: the number of allocated array members
-	      on output: the number of available clock sources, at least
-	      1 (internal clock generator).
-	Returns:
-	  If no input/output is present ASE_NotPresent will be returned.
-	Notes:
-*/
-
-ASIOError ASIOSetClockSource(long index);
-/* Purpose:
-	  Set the audio clock source
-	Parameter:
-	  index as obtained from an inquiry to ASIOGetClockSources()
-	Returns:
-	  If no input/output is present ASE_NotPresent will be returned.
-	  If the clock can not be selected because an input channel which
-	  carries the current clock source is active, ASE_InvalidMode
-	  *may* be returned (this depends on the properties of the driver
-	  and/or hardware).
-	Notes:
-	  Should *not* return ASE_NoClock if there is no clock signal present
-	  at the selected source; this will be inquired via ASIOGetSampleRate().
-	  It should call the host callback procedure sampleRateHasChanged(),
-	  if the switch causes a sample rate change, or if no external clock
-	  is present at the selected source.
-*/
-
-ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);
-/* Purpose:
-	  Inquires the sample position/time stamp pair.
-	Parameter:
-	  sPos will hold the sample position on return. The sample
-	  position is reset to zero when ASIOStart() gets called.
-	  tStamp will hold the system time when the sample position
-	  was latched.
-	Returns:
-	  If no input/output is present, ASE_NotPresent will be returned.
-	  If there is no clock, ASE_SPNotAdvancing will be returned.
-	Notes:
-
-	  in order to be able to synchronise properly,
-	  the sample position / time stamp pair must refer to the current block,
-	  that is, the engine will call ASIOGetSamplePosition() in its bufferSwitch()
-	  callback and expect the time for the current block. thus, when requested
-	  in the very first bufferSwitch after ASIO_Start(), the sample position
-	  should be zero, and the time stamp should refer to the very time where
-	  the stream was started. it also means that the sample position must be
-	  block aligned. the driver must ensure proper interpolation if the system
-	  time can not be determined for the block position. the driver is responsible
-	  for precise time stamps as it usually has most direct access to lower
-	  level resources. proper behaviour of ASIO_GetSamplePosition() and ASIO_GetLatencies()
-	  are essential for precise media synchronization!
-*/
-
-typedef struct ASIOChannelInfo
-{
-	long channel;			// on input, channel index
-	ASIOBool isInput;		// on input
-	ASIOBool isActive;		// on exit
-	long channelGroup;		// dto
-	ASIOSampleType type;	// dto
-	char name[32];			// dto
-} ASIOChannelInfo;
-
-ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);
-/* Purpose:
-	  retreive information about the nature of a channel
-	Parameter:
-	  info: pointer to a ASIOChannelInfo structure with
-	  	- channel: on input, the channel index of the channel in question.
-	  	- isInput: on input, ASIOTrue if info for an input channel is
-	  	  requested, else output
-		- channelGroup: on return, the channel group that the channel
-		  belongs to. For drivers which support different types of
-		  channels, like analog, S/PDIF, AES/EBU, ADAT etc interfaces,
-		  there should be a reasonable grouping of these types. Groups
-		  are always independant form a channel index, that is, a channel
-		  index always counts from 0 to numInputs/numOutputs regardless
-		  of the group it may belong to.
-		  There will always be at least one group (group 0). Please
-		  also note that by default, the host may decide to activate
-		  channels 0 and 1; thus, these should belong to the most
-		  useful type (analog i/o, if present).
-	  	- type: on return, contains the sample type of the channel
-	  	- isActive: on return, ASIOTrue if channel is active as it was
-	  	  installed by ASIOCreateBuffers(), ASIOFalse else
-	  	- name:  describing the type of channel in question. Used to allow
-	  	  for user selection, and enabling of specific channels. examples:
-	      "Analog In", "SPDIF Out" etc
-	Returns:
-	  If no input/output is present ASE_NotPresent will be returned.
-	Notes:
-	  If possible, the string should be organised such that the first
-	  characters are most significantly describing the nature of the
-	  port, to allow for identification even if the view showing the
-	  port name is too small to display more than 8 characters, for
-	  instance.
-*/
-
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-// Buffer preparation
-//- - - - - - - - - - - - - - - - - - - - - - - - -
-
-typedef struct ASIOBufferInfo
-{
-	ASIOBool isInput;			// on input:  ASIOTrue: input, else output
-	long channelNum;			// on input:  channel index
-	void *buffers[2];			// on output: double buffer addresses
-} ASIOBufferInfo;
-
-ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
-	long bufferSize, ASIOCallbacks *callbacks);
-
-/* Purpose:
-	  Allocates input/output buffers for all input and output channels to be activated.
-	Parameter:
-	  bufferInfos is a pointer to an array of ASIOBufferInfo structures:
-	    - isInput: on input, ASIOTrue if the buffer is to be allocated
-	      for an input, output buffer else
-	    - channelNum: on input, the index of the channel in question
-	      (counting from 0)
-	    - buffers: on exit, 2 pointers to the halves of the channels' double-buffer.
-	      the size of the buffer(s) of course depend on both the ASIOSampleType
-	      as obtained from ASIOGetChannelInfo(), and bufferSize
-	  numChannels is the sum of all input and output channels to be created;
-	  thus bufferInfos is a pointer to an array of numChannels ASIOBufferInfo
-	  structures.
-	  bufferSize selects one of the possible buffer sizes as obtained from
-	  ASIOGetBufferSizes().
-	  callbacks is a pointer to an ASIOCallbacks structure.
-	Returns:
-	  If not enough memory is available ASE_NoMemory will be returned.
-	  If no input/output is present ASE_NotPresent will be returned.
-	  If bufferSize is not supported, or one or more of the bufferInfos elements
-	  contain invalid settings, ASE_InvalidMode will be returned.
-	Notes:
-	  If individual channel selection is not possible but requested,
-	  the driver has to handle this. namely, bufferSwitch() will only
-	  have filled buffers of enabled outputs. If possible, processing
-	  and buss activities overhead should be avoided for channels which
-	  were not enabled here.
-*/
-
-ASIOError ASIODisposeBuffers(void);
-/* Purpose:
-	  Releases all buffers for the device.
-	Parameter:
-	  None.
-	Returns:
-	  If no buffer were ever prepared, ASE_InvalidMode will be returned.
-	  If no input/output is present ASE_NotPresent will be returned.
-	Notes:
-	  This implies ASIOStop().
-*/
-
-ASIOError ASIOControlPanel(void);
-/* Purpose:
-	  request the driver to start a control panel component
-	  for device specific user settings. This will not be
-	  accessed on some platforms (where the component is accessed
-	  instead).
-	Parameter:
-	  None.
-	Returns:
-	  If no panel is available ASE_NotPresent will be returned.
-	  Actually, the return code is ignored.
-	Notes:
-	  if the user applied settings which require a re-configuration
-	  of parts or all of the enigine and/or driver (such as a change of
-	  the block size), the asioMessage callback can be used (see
-	  ASIO_Callbacks).
-*/
-
-ASIOError ASIOFuture(long selector, void *params);
-/* Purpose:
-	  various
-	Parameter:
-	  selector: operation Code as to be defined. zero is reserved for
-	  testing purposes.
-	  params: depends on the selector; usually pointer to a structure
-	  for passing and retreiving any type and amount of parameters.
-	Returns:
-	  the return value is also selector dependant. if the selector
-	  is unknown, ASE_InvalidParameter should be returned to prevent
-	  further calls with this selector. on success, ASE_SUCCESS
-	  must be returned (note: ASE_OK is *not* sufficient!)
-	Notes:
-	  see selectors defined below.	  
-*/
-
-enum
-{
-	kAsioEnableTimeCodeRead = 1,	// no arguments
-	kAsioDisableTimeCodeRead,		// no arguments
-	kAsioSetInputMonitor,			// ASIOInputMonitor* in params
-	kAsioTransport,					// ASIOTransportParameters* in params
-	kAsioSetInputGain,				// ASIOChannelControls* in params, apply gain
-	kAsioGetInputMeter,				// ASIOChannelControls* in params, fill meter
-	kAsioSetOutputGain,				// ASIOChannelControls* in params, apply gain
-	kAsioGetOutputMeter,			// ASIOChannelControls* in params, fill meter
-	kAsioCanInputMonitor,			// no arguments for kAsioCanXXX selectors
-	kAsioCanTimeInfo,
-	kAsioCanTimeCode,
-	kAsioCanTransport,
-	kAsioCanInputGain,
-	kAsioCanInputMeter,
-	kAsioCanOutputGain,
-	kAsioCanOutputMeter,
-	kAsioOptionalOne,
-	
-	//	DSD support
-	//	The following extensions are required to allow switching
-	//	and control of the DSD subsystem.
-	kAsioSetIoFormat			= 0x23111961,		/* ASIOIoFormat * in params.			*/
-	kAsioGetIoFormat			= 0x23111983,		/* ASIOIoFormat * in params.			*/
-	kAsioCanDoIoFormat			= 0x23112004,		/* ASIOIoFormat * in params.			*/
-	
-	// Extension for drop out detection
-	kAsioCanReportOverload			= 0x24042012,	/* return ASE_SUCCESS if driver can detect and report overloads */
-	
-	kAsioGetInternalBufferSamples	= 0x25042012	/* ASIOInternalBufferInfo * in params. Deliver size of driver internal buffering, return ASE_SUCCESS if supported */
-};
-
-typedef struct ASIOInputMonitor
-{
-	long input;		// this input was set to monitor (or off), -1: all
-	long output;	// suggested output for monitoring the input (if so)
-	long gain;		// suggested gain, ranging 0 - 0x7fffffffL (-inf to +12 dB)
-	ASIOBool state;	// ASIOTrue => on, ASIOFalse => off
-	long pan;		// suggested pan, 0 => all left, 0x7fffffff => right
-} ASIOInputMonitor;
-
-typedef struct ASIOChannelControls
-{
-	long channel;			// on input, channel index
-	ASIOBool isInput;		// on input
-	long gain;				// on input,  ranges 0 thru 0x7fffffff
-	long meter;				// on return, ranges 0 thru 0x7fffffff
-	char future[32];
-} ASIOChannelControls;
-
-typedef struct ASIOTransportParameters
-{
-	long command;		// see enum below
-	ASIOSamples samplePosition;
-	long track;
-	long trackSwitches[16];		// 512 tracks on/off
-	char future[64];
-} ASIOTransportParameters;
-
-enum
-{
-	kTransStart = 1,
-	kTransStop,
-	kTransLocate,		// to samplePosition
-	kTransPunchIn,
-	kTransPunchOut,
-	kTransArmOn,		// track
-	kTransArmOff,		// track
-	kTransMonitorOn,	// track
-	kTransMonitorOff,	// track
-	kTransArm,			// trackSwitches
-	kTransMonitor		// trackSwitches
-};
-
-/*
-// DSD support
-//	Some notes on how to use ASIOIoFormatType.
-//
-//	The caller will fill the format with the request types.
-//	If the board can do the request then it will leave the
-//	values unchanged. If the board does not support the
-//	request then it will change that entry to Invalid (-1)
-//
-//	So to request DSD then
-//
-//	ASIOIoFormat NeedThis={kASIODSDFormat};
-//
-//	if(ASE_SUCCESS != ASIOFuture(kAsioSetIoFormat,&NeedThis) ){
-//		// If the board did not accept one of the parameters then the
-//		// whole call will fail and the failing parameter will
-//		// have had its value changes to -1.
-//	}
-//
-// Note: Switching between the formats need to be done before the "prepared"
-// state (see ASIO 2 documentation) is entered.
-*/
-typedef long int ASIOIoFormatType;
-enum ASIOIoFormatType_e
-{
-	kASIOFormatInvalid = -1,
-	kASIOPCMFormat = 0,
-	kASIODSDFormat = 1,
-};
-
-typedef struct ASIOIoFormat_s
-{
-	ASIOIoFormatType	FormatType;
-	char				future[512-sizeof(ASIOIoFormatType)];
-} ASIOIoFormat;
-
-// Extension for drop detection
-// Note: Refers to buffering that goes beyond the double buffer e.g. used by USB driver designs
-typedef struct ASIOInternalBufferInfo
-{
-	long inputSamples;			// size of driver's internal input buffering which is included in getLatencies
-	long outputSamples;			// size of driver's internal output buffering which is included in getLatencies
-} ASIOInternalBufferInfo;
-
-
-ASIOError ASIOOutputReady(void);
-/* Purpose:
-	  this tells the driver that the host has completed processing
-	  the output buffers. if the data format required by the hardware
-	  differs from the supported asio formats, but the hardware
-	  buffers are DMA buffers, the driver will have to convert
-	  the audio stream data; as the bufferSwitch callback is
-	  usually issued at dma block switch time, the driver will
-	  have to convert the *previous* host buffer, which increases
-	  the output latency by one block.
-	  when the host finds out that ASIOOutputReady() returns
-	  true, it will issue this call whenever it completed
-	  output processing. then the driver can convert the
-	  host data directly to the dma buffer to be played next,
-	  reducing output latency by one block.
-	  another way to look at it is, that the buffer switch is called
-	  in order to pass the *input* stream to the host, so that it can
-	  process the input into the output, and the output stream is passed
-	  to the driver when the host has completed its process.
-	Parameter:
-		None
-	Returns:
-	  only if the above mentioned scenario is given, and a reduction
-	  of output latency can be acheived by this mechanism, should
-	  ASE_OK be returned. otherwise (and usually), ASE_NotPresent
-	  should be returned in order to prevent further calls to this
-	  function. note that the host may want to determine if it is
-	  to use this when the system is not yet fully initialized, so
-	  ASE_OK should always be returned if the mechanism makes sense.	  
-	Notes:
-	  please remeber to adjust ASIOGetLatencies() according to
-	  whether ASIOOutputReady() was ever called or not, if your
-	  driver supports this scenario.
-	  also note that the engine may fail to call ASIO_OutputReady()
-	  in time in overload cases. as already mentioned, bufferSwitch
-      should be called for every block regardless of whether a block
-      could be processed in time.
-*/
-
-// restore old alignment
-#if defined(_MSC_VER) && !defined(__MWERKS__) 
-#pragma pack(pop)
-#elif PRAGMA_ALIGN_SUPPORTED
-#pragma options align = reset
-#endif
-
-#endif
-

+ 0 - 186
source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiodrivers.cpp

@@ -1,186 +0,0 @@
-#include <string.h>
-#include "asiodrivers.h"
-
-AsioDrivers* asioDrivers = 0;
-
-bool loadAsioDriver(char *name);
-
-bool loadAsioDriver(char *name)
-{
-	if(!asioDrivers)
-		asioDrivers = new AsioDrivers();
-	if(asioDrivers)
-		return asioDrivers->loadDriver(name);
-	return false;
-}
-
-//------------------------------------------------------------------------------------
-
-#if MAC
-
-bool resolveASIO(unsigned long aconnID);
-
-AsioDrivers::AsioDrivers() : CodeFragments("ASIO Drivers", 'AsDr', 'Asio')
-{
-	connID = -1;
-	curIndex = -1;
-}
-
-AsioDrivers::~AsioDrivers()
-{
-	removeCurrentDriver();
-}
-
-bool AsioDrivers::getCurrentDriverName(char *name)
-{
-	if(curIndex >= 0)
-		return getName(curIndex, name);
-	return false;
-}
-
-long AsioDrivers::getDriverNames(char **names, long maxDrivers)
-{
-	for(long i = 0; i < getNumFragments() && i < maxDrivers; i++)
-		getName(i, names[i]);
-	return getNumFragments() < maxDrivers ? getNumFragments() : maxDrivers;
-}
-
-bool AsioDrivers::loadDriver(char *name)
-{
-	char dname[64];
-	unsigned long newID;
-
-	for(long i = 0; i < getNumFragments(); i++)
-	{
-		if(getName(i, dname) && !strcmp(name, dname))
-		{
-			if(newInstance(i, &newID))
-			{
-				if(resolveASIO(newID))
-				{
-					if(connID != -1)
-						removeInstance(curIndex, connID);
-					curIndex = i;
-					connID = newID;
-					return true;
-				}
-			}
-			break;
-		}
-	}
-	return false;
-}
-
-void AsioDrivers::removeCurrentDriver()
-{
-	if(connID != -1)
-		removeInstance(curIndex, connID);
-	connID = -1;
-	curIndex = -1;
-}
-
-//------------------------------------------------------------------------------------
-
-#elif WINDOWS
-
-#include "iasiodrv.h"
-
-extern IASIO* theAsioDriver;
-
-AsioDrivers::AsioDrivers() : AsioDriverList()
-{
-	curIndex = -1;
-}
-
-AsioDrivers::~AsioDrivers()
-{
-}
-
-bool AsioDrivers::getCurrentDriverName(char *name)
-{
-	if(curIndex >= 0)
-		return asioGetDriverName(curIndex, name, 32) == 0 ? true : false;
-	name[0] = 0;
-	return false;
-}
-
-long AsioDrivers::getDriverNames(char **names, long maxDrivers)
-{
-	for(long i = 0; i < asioGetNumDev() && i < maxDrivers; i++)
-		asioGetDriverName(i, names[i], 32);
-	return asioGetNumDev() < maxDrivers ? asioGetNumDev() : maxDrivers;
-}
-
-bool AsioDrivers::loadDriver(char *name)
-{
-	char dname[64];
-	char curName[64];
-
-	for(long i = 0; i < asioGetNumDev(); i++)
-	{
-		if(!asioGetDriverName(i, dname, 32) && !strcmp(name, dname))
-		{
-			curName[0] = 0;
-			getCurrentDriverName(curName);	// in case we fail...
-			removeCurrentDriver();
-
-			if(!asioOpenDriver(i, (void **)&theAsioDriver))
-			{
-				curIndex = i;
-				return true;
-			}
-			else
-			{
-				theAsioDriver = 0;
-				if(curName[0] && strcmp(dname, curName))
-					loadDriver(curName);	// try restore
-			}
-			break;
-		}
-	}
-	return false;
-}
-
-void AsioDrivers::removeCurrentDriver()
-{
-	if(curIndex != -1)
-		asioCloseDriver(curIndex);
-	curIndex = -1;
-}
-
-#elif SGI || BEOS
-
-#include "asiolist.h"
-
-AsioDrivers::AsioDrivers() 
-	: AsioDriverList()
-{
-	curIndex = -1;
-}
-
-AsioDrivers::~AsioDrivers()
-{
-}
-
-bool AsioDrivers::getCurrentDriverName(char *name)
-{
-	return false;
-}
-
-long AsioDrivers::getDriverNames(char **names, long maxDrivers)
-{
-	return 0;
-}
-
-bool AsioDrivers::loadDriver(char *name)
-{
-	return false;
-}
-
-void AsioDrivers::removeCurrentDriver()
-{
-}
-
-#else
-#error implement me
-#endif

+ 0 - 42
source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiodrivers.h

@@ -1,42 +0,0 @@
-#ifndef __AsioDrivers__
-#define __AsioDrivers__
-
-#include "ginclude.h"
-
-#if MAC
-#include "CodeFragments.hpp"
-
-class AsioDrivers : public CodeFragments
-
-#elif WINDOWS
-#include <WinSock2.h>
-#include <Windows.h>
-#include "asiolist.h"
-
-class AsioDrivers : public AsioDriverList
-
-#elif SGI || BEOS
-#include "asiolist.h"
-
-class AsioDrivers : public AsioDriverList
-
-#else
-#error implement me
-#endif
-
-{
-public:
-	AsioDrivers();
-	~AsioDrivers();
-	
-	bool getCurrentDriverName(char *name);
-	long getDriverNames(char **names, long maxDrivers);
-	bool loadDriver(char *name);
-	void removeCurrentDriver();
-	long getCurrentDriverIndex() {return curIndex;}
-protected:
-	unsigned long connID;
-	long curIndex;
-};
-
-#endif

+ 0 - 77
source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiodrvr.h

@@ -1,77 +0,0 @@
-/*
-	Steinberg Audio Stream I/O API
-	(c) 1996, Steinberg Soft- und Hardware GmbH
-	charlie (May 1996)
-
-	asiodrvr.h
-	c++ superclass to implement asio functionality. from this,
-	you can derive whatever required
-*/
-
-#ifndef _asiodrvr_
-#define _asiodrvr_
-
-// cpu and os system we are running on
-#include "asiosys.h"
-// basic "C" interface
-#include "asio.h"
-
-class AsioDriver;
-extern AsioDriver *getDriver();		// for generic constructor 
-
-#if WINDOWS
-#include <WinSock2.h>
-#include <Windows.h>
-#include "combase.h"
-#include "iasiodrv.h"
-class AsioDriver : public IASIO ,public CUnknown
-{
-public:
-	AsioDriver(LPUNKNOWN pUnk, HRESULT *phr);
-
-	DECLARE_IUNKNOWN
-	// Factory method
-	static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
-	// IUnknown
-	virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject);
-
-#else
-
-class AsioDriver
-{
-public:
-	AsioDriver();
-#endif
-	virtual ~AsioDriver();
-
-	virtual ASIOBool init(void* sysRef);
-	virtual void getDriverName(char *name);	// max 32 bytes incl. terminating zero
-	virtual long getDriverVersion();
-	virtual void getErrorMessage(char *string);	// max 124 bytes incl.
-
-	virtual ASIOError start();
-	virtual ASIOError stop();
-
-	virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);
-	virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);
-	virtual ASIOError getBufferSize(long *minSize, long *maxSize,
-		long *preferredSize, long *granularity);
-
-	virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);
-	virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);
-	virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);
-	virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);
-	virtual ASIOError setClockSource(long reference);
-
-	virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp);
-	virtual ASIOError getChannelInfo(ASIOChannelInfo *info);
-
-	virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
-		long bufferSize, ASIOCallbacks *callbacks);
-	virtual ASIOError disposeBuffers();
-
-	virtual ASIOError controlPanel();
-	virtual ASIOError future(long selector, void *opt);
-	virtual ASIOError outputReady();
-};
-#endif

+ 0 - 309
source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiolist.cpp

@@ -1,309 +0,0 @@
-#include <WinSock2.h>
-#include <Windows.h>
-#include "iasiodrv.h"
-#include "asiolist.h"
-
-#define ASIODRV_DESC		"description"
-#define INPROC_SERVER		"InprocServer32"
-#define ASIO_PATH			"software\\asio"
-#define COM_CLSID			"clsid"
-
-// ******************************************************************
-// Local Functions 
-// ******************************************************************
-static LONG findDrvPath (char *clsidstr,char *dllpath,int dllpathsize)
-{
-	HKEY			hkEnum,hksub,hkpath;
-	char			databuf[512];
-	LONG 			cr,rc = -1;
-	DWORD			datatype,datasize;
-	DWORD			index;
-	OFSTRUCT		ofs;
-	HFILE			hfile;
-	BOOL			found = FALSE;
-
-#ifdef UNICODE
-	CharLowerBuffA(clsidstr,strlen(clsidstr));
-	if ((cr = RegOpenKeyA(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) {
-
-		index = 0;
-		while (cr == ERROR_SUCCESS && !found) {
-			cr = RegEnumKeyA(hkEnum,index++,databuf,512);
-			if (cr == ERROR_SUCCESS) {
-				CharLowerBuffA(databuf,strlen(databuf));
-				if (!(strcmp(databuf,clsidstr))) {
-					if ((cr = RegOpenKeyExA(hkEnum,databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
-						if ((cr = RegOpenKeyExA(hksub,INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) {
-							datatype = REG_SZ; datasize = (DWORD)dllpathsize;
-							cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize);
-							if (cr == ERROR_SUCCESS) {
-								memset(&ofs,0,sizeof(OFSTRUCT));
-								ofs.cBytes = sizeof(OFSTRUCT); 
-								hfile = OpenFile(dllpath,&ofs,OF_EXIST);
-								if (hfile) rc = 0; 
-							}
-							RegCloseKey(hkpath);
-						}
-						RegCloseKey(hksub);
-					}
-					found = TRUE;	// break out 
-				}
-			}
-		}				
-		RegCloseKey(hkEnum);
-	}
-#else
-	CharLowerBuff(clsidstr,strlen(clsidstr));
-	if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) {
-
-		index = 0;
-		while (cr == ERROR_SUCCESS && !found) {
-			cr = RegEnumKey(hkEnum,index++,databuf,512);
-			if (cr == ERROR_SUCCESS) {
-				CharLowerBuff(databuf,strlen(databuf));
-				if (!(strcmp(databuf,clsidstr))) {
-					if ((cr = RegOpenKeyEx(hkEnum,databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
-						if ((cr = RegOpenKeyEx(hksub,INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) {
-							datatype = REG_SZ; datasize = (DWORD)dllpathsize;
-							cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize);
-							if (cr == ERROR_SUCCESS) {
-								memset(&ofs,0,sizeof(OFSTRUCT));
-								ofs.cBytes = sizeof(OFSTRUCT); 
-								hfile = OpenFile(dllpath,&ofs,OF_EXIST);
-								if (hfile) rc = 0; 
-							}
-							RegCloseKey(hkpath);
-						}
-						RegCloseKey(hksub);
-					}
-					found = TRUE;	// break out 
-				}
-			}
-		}				
-		RegCloseKey(hkEnum);
-	}
-#endif
-	return rc;
-}
-
-
-static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv)
-{
-	HKEY	hksub;
-	char	databuf[256];
-	char	dllpath[MAXPATHLEN];
-	WORD	wData[100];
-	CLSID	clsid;
-	DWORD	datatype,datasize;
-	LONG	cr,rc;
-
-	if (!lpdrv) {
-		if ((cr = RegOpenKeyExA(hkey,keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
-
-			datatype = REG_SZ; datasize = 256;
-			cr = RegQueryValueExA(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize);
-			if (cr == ERROR_SUCCESS) {
-				rc = findDrvPath (databuf,dllpath,MAXPATHLEN);
-				if (rc == 0) {
-					lpdrv = new ASIODRVSTRUCT[1];
-					if (lpdrv) {
-						memset(lpdrv,0,sizeof(ASIODRVSTRUCT));
-						lpdrv->drvID = drvID;
-						MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100);
-						if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) {
-							memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID));
-						}
-
-						datatype = REG_SZ; datasize = 256;
-						cr = RegQueryValueExA(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize);
-						if (cr == ERROR_SUCCESS) {
-							strcpy(lpdrv->drvname,databuf);
-						}
-						else strcpy(lpdrv->drvname,keyname);
-					}
-				}
-			}
-			RegCloseKey(hksub);
-		}
-	}	
-	else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next);
-
-	return lpdrv;
-}
-
-static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv)
-{
-	IASIO	*iasio;
-
-	if (lpdrv != 0) {
-		deleteDrvStruct(lpdrv->next);
-		if (lpdrv->asiodrv) {
-			iasio = (IASIO *)lpdrv->asiodrv;
-			iasio->Release();
-		}
-		delete lpdrv;
-	}
-}
-
-
-static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv)
-{
-	while (lpdrv) {
-		if (lpdrv->drvID == drvID) return lpdrv;
-		lpdrv = lpdrv->next;
-	}
-	return 0;
-}
-// ******************************************************************
-
-
-// ******************************************************************
-//	AsioDriverList
-// ******************************************************************
-AsioDriverList::AsioDriverList ()
-{
-	HKEY			hkEnum = 0;
-	char			keyname[MAXDRVNAMELEN];
-	LPASIODRVSTRUCT	pdl;
-	LONG 			cr;
-	DWORD			index = 0;
-	BOOL			fin = FALSE;
-
-	numdrv		= 0;
-	lpdrvlist	= 0;
-
-#ifdef UNICODE
-	cr = RegOpenKeyA(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum);
-#else
-	cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum);
-#endif
-	while (cr == ERROR_SUCCESS) {
-#ifdef UNICODE
-		if ((cr = RegEnumKeyA(hkEnum,index++,keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) {
-#else
-		if ((cr = RegEnumKey(hkEnum,index++,keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) {
-#endif
-			lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist);
-		}
-		else fin = TRUE;
-	}
-	if (hkEnum) RegCloseKey(hkEnum);
-
-	pdl = lpdrvlist;
-	while (pdl) {
-		numdrv++;
-		pdl = pdl->next;
-	}
-
-	if (numdrv) CoInitialize(0);	// initialize COM
-}
-
-AsioDriverList::~AsioDriverList ()
-{
-	if (numdrv) {
-		deleteDrvStruct(lpdrvlist);
-		CoUninitialize();
-	}
-}
-
-
-LONG AsioDriverList::asioGetNumDev (VOID)
-{
-	return (LONG)numdrv;
-}
-
-
-LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv)
-{
-	LPASIODRVSTRUCT	lpdrv = 0;
-	long			rc;
-
-	if (!asiodrv) return DRVERR_INVALID_PARAM;
-
-	if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
-		if (!lpdrv->asiodrv) {
-			rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv);
-			if (rc == S_OK) {
-				lpdrv->asiodrv = *asiodrv;
-				return 0;
-			}
-			// else if (rc == REGDB_E_CLASSNOTREG)
-			//	strcpy (info->messageText, "Driver not registered in the Registration Database!");
-		}
-		else rc = DRVERR_DEVICE_ALREADY_OPEN;
-	}
-	else rc = DRVERR_DEVICE_NOT_FOUND;
-	
-	return rc;
-}
-
-
-LONG AsioDriverList::asioCloseDriver (int drvID)
-{
-	LPASIODRVSTRUCT	lpdrv = 0;
-	IASIO			*iasio;
-
-	if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
-		if (lpdrv->asiodrv) {
-			iasio = (IASIO *)lpdrv->asiodrv;
-			iasio->Release();
-			lpdrv->asiodrv = 0;
-		}
-	}
-
-	return 0;
-}
-
-LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize)
-{	
-	LPASIODRVSTRUCT			lpdrv = 0;
-
-	if (!drvname) return DRVERR_INVALID_PARAM;
-
-	if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
-		if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) {
-			strcpy(drvname,lpdrv->drvname);
-		}
-		else {
-			memcpy(drvname,lpdrv->drvname,drvnamesize-4);
-			drvname[drvnamesize-4] = '.';
-			drvname[drvnamesize-3] = '.';
-			drvname[drvnamesize-2] = '.';
-			drvname[drvnamesize-1] = 0;
-		}
-		return 0;
-	}
-	return DRVERR_DEVICE_NOT_FOUND;
-}
-
-LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize)
-{
-	LPASIODRVSTRUCT			lpdrv = 0;
-
-	if (!dllpath) return DRVERR_INVALID_PARAM;
-
-	if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
-		if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) {
-			strcpy(dllpath,lpdrv->dllpath);
-			return 0;
-		}
-		dllpath[0] = 0;
-		return DRVERR_INVALID_PARAM;
-	}
-	return DRVERR_DEVICE_NOT_FOUND;
-}
-
-LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid)
-{
-	LPASIODRVSTRUCT			lpdrv = 0;
-
-	if (!clsid) return DRVERR_INVALID_PARAM;
-
-	if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
-		memcpy(clsid,&lpdrv->clsid,sizeof(CLSID));
-		return 0;
-	}
-	return DRVERR_DEVICE_NOT_FOUND;
-}
-
-

+ 0 - 46
source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiolist.h

@@ -1,46 +0,0 @@
-#ifndef __asiolist__
-#define __asiolist__
-
-#define DRVERR			-5000
-#define DRVERR_INVALID_PARAM		DRVERR-1
-#define DRVERR_DEVICE_ALREADY_OPEN	DRVERR-2
-#define DRVERR_DEVICE_NOT_FOUND		DRVERR-3
-
-#define MAXPATHLEN			512
-#define MAXDRVNAMELEN		128
-
-struct asiodrvstruct
-{
-	int						drvID;
-	CLSID					clsid;
-	char					dllpath[MAXPATHLEN];
-	char					drvname[MAXDRVNAMELEN];
-	LPVOID					asiodrv;
-	struct asiodrvstruct	*next;
-};
-
-typedef struct asiodrvstruct ASIODRVSTRUCT;
-typedef ASIODRVSTRUCT	*LPASIODRVSTRUCT;
-
-class AsioDriverList {
-public:
-	AsioDriverList();
-	~AsioDriverList();
-	
-	LONG asioOpenDriver (int,VOID **);
-	LONG asioCloseDriver (int);
-
-	// nice to have
-	LONG asioGetNumDev (VOID);
-	LONG asioGetDriverName (int,char *,int);		
-	LONG asioGetDriverPath (int,char *,int);
-	LONG asioGetDriverCLSID (int,CLSID *);
-
-	// or use directly access
-	LPASIODRVSTRUCT	lpdrvlist;
-	int				numdrv;
-};
-
-typedef class AsioDriverList *LPASIODRIVERLIST;
-
-#endif

+ 0 - 82
source/AudioDecode/AudioDecoder/lib/RtAudio/include/asiosys.h

@@ -1,82 +0,0 @@
-#ifndef __asiosys__
-	#define __asiosys__
-
-	#if defined(_WIN32) || defined(_WIN64)
-		#undef MAC 
-		#define PPC 0
-		#define WINDOWS 1
-		#define SGI 0
-		#define SUN 0
-		#define LINUX 0
-		#define BEOS 0
-
-		#define NATIVE_INT64 0
-		#define IEEE754_64FLOAT 1
-	
-	#elif BEOS
-		#define MAC 0
-		#define PPC 0
-		#define WINDOWS 0
-		#define PC 0
-		#define SGI 0
-		#define SUN 0
-		#define LINUX 0
-		
-		#define NATIVE_INT64 0
-		#define IEEE754_64FLOAT 1
-		
-		#ifndef DEBUG
-			#define DEBUG 0
-		 	#if DEBUG
-		 		void DEBUGGERMESSAGE(char *string);
-		 	#else
-		  		#define DEBUGGERMESSAGE(a)
-			#endif
-		#endif
-
-	#elif SGI
-		#define MAC 0
-		#define PPC 0
-		#define WINDOWS 0
-		#define PC 0
-		#define SUN 0
-		#define LINUX 0
-		#define BEOS 0
-		
-		#define NATIVE_INT64 0
-		#define IEEE754_64FLOAT 1
-		
-		#ifndef DEBUG
-			#define DEBUG 0
-		 	#if DEBUG
-		 		void DEBUGGERMESSAGE(char *string);
-		 	#else
-		  		#define DEBUGGERMESSAGE(a)
-			#endif
-		#endif
-
-	#else	// MAC
-
-		#define MAC 1
-		#define PPC 1
-		#define WINDOWS 0
-		#define PC 0
-		#define SGI 0
-		#define SUN 0
-		#define LINUX 0
-		#define BEOS 0
-
-		#define NATIVE_INT64 0
-		#define IEEE754_64FLOAT 1
-
-		#ifndef DEBUG
-			#define DEBUG 0
-			#if DEBUG
-				void DEBUGGERMESSAGE(char *string);
-			#else
-				#define DEBUGGERMESSAGE(a)
-			#endif
-		#endif
-	#endif
-
-#endif

+ 0 - 2369
source/AudioDecode/AudioDecoder/lib/RtAudio/include/dsound.h

@@ -1,2369 +0,0 @@
-/*==========================================================================;
- *
- *  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
-

+ 0 - 212
source/AudioDecode/AudioDecoder/lib/RtAudio/include/functiondiscoverykeys_devpkey.h

@@ -1,212 +0,0 @@
-#pragma once
-
-/*++
-
-Copyright (c) Microsoft Corporation.  All rights reserved.
-
-Module Name:
-
-    devpkey.h
-
-Abstract:
-
-    Defines property keys for the Plug and Play Device Property API.
-
-Author:
-
-    Jim Cavalaris (jamesca) 10-14-2003
-
-Environment:
-
-    User-mode only.
-
-Revision History:
-
-    14-October-2003     jamesca
-
-        Creation and initial implementation.
-
-    20-June-2006        dougb
-
-        Copied Jim's version replaced "DEFINE_DEVPROPKEY(DEVPKEY_" with "DEFINE_PROPERTYKEY(PKEY_"
-    
---*/
-
-//#include <devpropdef.h>
-
-//
-// _NAME
-//
-
-DEFINE_PROPERTYKEY(PKEY_NAME,                          0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac, 10);    // DEVPROP_TYPE_STRING
-
-//
-// Device properties
-// These PKEYs correspond to the old setupapi SPDRP_XXX properties
-//
-DEFINE_PROPERTYKEY(PKEY_Device_DeviceDesc,             0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 2);     // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_HardwareIds,            0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 3);     // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_CompatibleIds,          0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 4);     // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_Service,                0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 6);     // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_Class,                  0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 9);     // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_ClassGuid,              0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 10);    // DEVPROP_TYPE_GUID
-DEFINE_PROPERTYKEY(PKEY_Device_Driver,                 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 11);    // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_ConfigFlags,            0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 12);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_Manufacturer,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 13);    // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);    // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_LocationInfo,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 15);    // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_PDOName,                0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 16);    // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_Capabilities,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 17);    // DEVPROP_TYPE_UNINT32
-DEFINE_PROPERTYKEY(PKEY_Device_UINumber,               0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 18);    // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_UpperFilters,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 19);    // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_LowerFilters,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 20);    // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_BusTypeGuid,            0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 21);    // DEVPROP_TYPE_GUID
-DEFINE_PROPERTYKEY(PKEY_Device_LegacyBusType,          0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 22);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_BusNumber,              0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 23);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_EnumeratorName,         0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 24);    // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_Security,               0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 25);    // DEVPROP_TYPE_SECURITY_DESCRIPTOR
-DEFINE_PROPERTYKEY(PKEY_Device_SecuritySDS,            0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 26);    // DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_DevType,                0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 27);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_Exclusive,              0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 28);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_Characteristics,        0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 29);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_Address,                0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 30);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_UINumberDescFormat,     0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 31);    // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_PowerData,              0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 32);    // DEVPROP_TYPE_BINARY
-DEFINE_PROPERTYKEY(PKEY_Device_RemovalPolicy,          0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 33);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_RemovalPolicyDefault,   0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 34);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_RemovalPolicyOverride,  0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 35);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_InstallState,           0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 36);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_LocationPaths,          0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 37);    // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_BaseContainerId,        0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 38);    // DEVPROP_TYPE_GUID
-
-//
-// Device properties
-// These PKEYs correspond to a device's status and problem code
-//
-DEFINE_PROPERTYKEY(PKEY_Device_DevNodeStatus,          0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 2);     // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_ProblemCode,            0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 3);     // DEVPROP_TYPE_UINT32
-
-//
-// Device properties
-// These PKEYs correspond to device relations
-//
-DEFINE_PROPERTYKEY(PKEY_Device_EjectionRelations,      0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 4);     // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_RemovalRelations,       0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 5);     // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_PowerRelations,         0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 6);     // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_BusRelations,           0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 7);     // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_Parent,                 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 8);     // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_Children,               0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 9);     // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_Siblings,               0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 10);    // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_TransportRelations,     0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 11);    // DEVPROP_TYPE_STRING_LIST
-
-//
-// Other Device properties
-//
-DEFINE_PROPERTYKEY(PKEY_Device_Reported,               0x80497100, 0x8c73, 0x48b9, 0xaa, 0xd9, 0xce, 0x38, 0x7e, 0x19, 0xc5, 0x6e, 2);     // DEVPROP_TYPE_BOOLEAN
-DEFINE_PROPERTYKEY(PKEY_Device_Legacy,                 0x80497100, 0x8c73, 0x48b9, 0xaa, 0xd9, 0xce, 0x38, 0x7e, 0x19, 0xc5, 0x6e, 3);     // DEVPROP_TYPE_BOOLEAN
-DEFINE_PROPERTYKEY(PKEY_Device_InstanceId,             0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 256);   // DEVPROP_TYPE_STRING
-
-DEFINE_PROPERTYKEY(PKEY_Device_ContainerId,            0x8c7ed206, 0x3f8a, 0x4827, 0xb3, 0xab, 0xae, 0x9e, 0x1f, 0xae, 0xfc, 0x6c, 2);     // DEVPROP_TYPE_GUID
-
-DEFINE_PROPERTYKEY(PKEY_Device_ModelId,                0x80d81ea6, 0x7473, 0x4b0c, 0x82, 0x16, 0xef, 0xc1, 0x1a, 0x2c, 0x4c, 0x8b, 2);     // DEVPROP_TYPE_GUID
-
-DEFINE_PROPERTYKEY(PKEY_Device_FriendlyNameAttributes, 0x80d81ea6, 0x7473, 0x4b0c, 0x82, 0x16, 0xef, 0xc1, 0x1a, 0x2c, 0x4c, 0x8b, 3);     // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_ManufacturerAttributes, 0x80d81ea6, 0x7473, 0x4b0c, 0x82, 0x16, 0xef, 0xc1, 0x1a, 0x2c, 0x4c, 0x8b, 4);     // DEVPROP_TYPE_UINT32
-
-DEFINE_PROPERTYKEY(PKEY_Device_PresenceNotForDevice,   0x80d81ea6, 0x7473, 0x4b0c, 0x82, 0x16, 0xef, 0xc1, 0x1a, 0x2c, 0x4c, 0x8b, 5);     // DEVPROP_TYPE_BOOLEAN
-
-
-DEFINE_PROPERTYKEY(PKEY_Numa_Proximity_Domain,         0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 1);     // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_DHP_Rebalance_Policy,   0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 2);     // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_Numa_Node,              0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 3);     // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_BusReportedDeviceDesc,  0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 4);     // DEVPROP_TYPE_STRING
-
-DEFINE_PROPERTYKEY(PKEY_Device_InstallInProgress,      0x83da6326, 0x97a6, 0x4088, 0x94, 0x53, 0xa1, 0x92, 0x3f, 0x57, 0x3b, 0x29, 9);     // DEVPROP_TYPE_BOOLEAN
-
-//
-// Device driver properties
-//
-DEFINE_PROPERTYKEY(PKEY_Device_DriverDate,             0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 2);      // DEVPROP_TYPE_FILETIME
-DEFINE_PROPERTYKEY(PKEY_Device_DriverVersion,          0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 3);      // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_DriverDesc,             0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 4);      // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_DriverInfPath,          0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 5);      // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_DriverInfSection,       0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 6);      // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_DriverInfSectionExt,    0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 7);      // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_MatchingDeviceId,       0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 8);      // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_DriverProvider,         0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 9);      // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_DriverPropPageProvider, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 10);     // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_DriverCoInstallers,     0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 11);     // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_Device_ResourcePickerTags,     0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 12);     // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_ResourcePickerExceptions, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 13); // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_Device_DriverRank,             0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 14);     // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_DriverLogoLevel,        0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 15);     // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_Device_NoConnectSound,         0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 17);     // DEVPROP_TYPE_BOOLEAN
-DEFINE_PROPERTYKEY(PKEY_Device_GenericDriverInstalled, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 18);     // DEVPROP_TYPE_BOOLEAN
-DEFINE_PROPERTYKEY(PKEY_Device_AdditionalSoftwareRequested, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 19);// DEVPROP_TYPE_BOOLEAN
-
-//
-// Device safe-removal properties
-//
-DEFINE_PROPERTYKEY(PKEY_Device_SafeRemovalRequired,    0xafd97640,  0x86a3, 0x4210, 0xb6, 0x7c, 0x28, 0x9c, 0x41, 0xaa, 0xbe, 0x55, 2);    // DEVPROP_TYPE_BOOLEAN
-DEFINE_PROPERTYKEY(PKEY_Device_SafeRemovalRequiredOverride, 0xafd97640,  0x86a3, 0x4210, 0xb6, 0x7c, 0x28, 0x9c, 0x41, 0xaa, 0xbe, 0x55, 3);// DEVPROP_TYPE_BOOLEAN
-
-
-//
-// Device properties that were set by the driver package that was installed
-// on the device.
-//
-DEFINE_PROPERTYKEY(PKEY_DrvPkg_Model,                  0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 2);     // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DrvPkg_VendorWebSite,          0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 3);     // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DrvPkg_DetailedDescription,    0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 4);     // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DrvPkg_DocumentationLink,      0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 5);     // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DrvPkg_Icon,                   0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 6);     // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_DrvPkg_BrandingIcon,           0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 7);     // DEVPROP_TYPE_STRING_LIST
-
-//
-// Device setup class properties
-// These PKEYs correspond to the old setupapi SPCRP_XXX properties
-//
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_UpperFilters,      0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 19);    // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_LowerFilters,      0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 20);    // DEVPROP_TYPE_STRING_LIST
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_Security,          0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 25);    // DEVPROP_TYPE_SECURITY_DESCRIPTOR
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_SecuritySDS,       0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 26);    // DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_DevType,           0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 27);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_Exclusive,         0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 28);    // DEVPROP_TYPE_UINT32
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_Characteristics,   0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 29);    // DEVPROP_TYPE_UINT32
-
-//
-// Device setup class properties
-// These PKEYs correspond to registry values under the device class GUID key
-//
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_Name,              0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 2);  // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_ClassName,         0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 3);  // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_Icon,              0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 4);  // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_ClassInstaller,    0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 5);  // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_PropPageProvider,  0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 6);  // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_NoInstallClass,    0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 7);  // DEVPROP_TYPE_BOOLEAN
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_NoDisplayClass,    0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 8);  // DEVPROP_TYPE_BOOLEAN
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_SilentInstall,     0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 9);  // DEVPROP_TYPE_BOOLEAN
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_NoUseClass,        0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 10); // DEVPROP_TYPE_BOOLEAN
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_DefaultService,    0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 11); // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_IconPath,          0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 12); // DEVPROP_TYPE_STRING_LIST
-
-//
-// Other Device setup class properties
-//
-DEFINE_PROPERTYKEY(PKEY_DeviceClass_ClassCoInstallers, 0x713d1703, 0xa2e2, 0x49f5, 0x92, 0x14, 0x56, 0x47, 0x2e, 0xf3, 0xda, 0x5c, 2); // DEVPROP_TYPE_STRING_LIST
-
-//
-// Device interface properties
-//
-DEFINE_PROPERTYKEY(PKEY_DeviceInterface_FriendlyName,  0x026e516e, 0xb814, 0x414b, 0x83, 0xcd, 0x85, 0x6d, 0x6f, 0xef, 0x48, 0x22, 2); // DEVPROP_TYPE_STRING
-DEFINE_PROPERTYKEY(PKEY_DeviceInterface_Enabled,       0x026e516e, 0xb814, 0x414b, 0x83, 0xcd, 0x85, 0x6d, 0x6f, 0xef, 0x48, 0x22, 3); // DEVPROP_TYPE_BOOLEAN
-DEFINE_PROPERTYKEY(PKEY_DeviceInterface_ClassGuid,     0x026e516e, 0xb814, 0x414b, 0x83, 0xcd, 0x85, 0x6d, 0x6f, 0xef, 0x48, 0x22, 4); // DEVPROP_TYPE_GUID
-
-//
-// Device interface class properties
-//
-DEFINE_PROPERTYKEY(PKEY_DeviceInterfaceClass_DefaultInterface,  0x14c83a99, 0x0b3f, 0x44b7, 0xbe, 0x4c, 0xa1, 0x78, 0xd3, 0x99, 0x05, 0x64, 2); // DEVPROP_TYPE_STRING
-
-
-
-

+ 0 - 38
source/AudioDecode/AudioDecoder/lib/RtAudio/include/ginclude.h

@@ -1,38 +0,0 @@
-#ifndef __gInclude__
-#define __gInclude__
-
-#if SGI 
-	#undef BEOS 
-	#undef MAC 
-	#undef WINDOWS
-	//
-	#define ASIO_BIG_ENDIAN 1
-	#define ASIO_CPU_MIPS 1
-#elif defined(_WIN32) || defined(_WIN64)
-	#undef BEOS 
-	#undef MAC 
-	#undef SGI
-	#define WINDOWS 1
-	#define ASIO_LITTLE_ENDIAN 1
-	#define ASIO_CPU_X86 1
-#elif BEOS
-	#undef MAC 
-	#undef SGI
-	#undef WINDOWS
-	#define ASIO_LITTLE_ENDIAN 1
-	#define ASIO_CPU_X86 1
-	//
-#else
-	#define MAC 1
-	#undef BEOS 
-	#undef WINDOWS
-	#undef SGI
-	#define ASIO_BIG_ENDIAN 1
-	#define ASIO_CPU_PPC 1
-#endif
-
-// always
-#define NATIVE_INT64 0
-#define IEEE754_64FLOAT 1
-
-#endif	// __gInclude__

+ 0 - 37
source/AudioDecode/AudioDecoder/lib/RtAudio/include/iasiodrv.h

@@ -1,37 +0,0 @@
-#include "asiosys.h"
-#include "asio.h"
-
-/* Forward Declarations */ 
-
-#ifndef __ASIODRIVER_FWD_DEFINED__
-#define __ASIODRIVER_FWD_DEFINED__
-typedef interface IASIO IASIO;
-#endif 	/* __ASIODRIVER_FWD_DEFINED__ */
-
-interface IASIO : public IUnknown
-{
-
-	virtual ASIOBool init(void *sysHandle) = 0;
-	virtual void getDriverName(char *name) = 0;	
-	virtual long getDriverVersion() = 0;
-	virtual void getErrorMessage(char *string) = 0;	
-	virtual ASIOError start() = 0;
-	virtual ASIOError stop() = 0;
-	virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0;
-	virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0;
-	virtual ASIOError getBufferSize(long *minSize, long *maxSize,
-		long *preferredSize, long *granularity) = 0;
-	virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0;
-	virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0;
-	virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0;
-	virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0;
-	virtual ASIOError setClockSource(long reference) = 0;
-	virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;
-	virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0;
-	virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
-		long bufferSize, ASIOCallbacks *callbacks) = 0;
-	virtual ASIOError disposeBuffers() = 0;
-	virtual ASIOError controlPanel() = 0;
-	virtual ASIOError future(long selector,void *opt) = 0;
-	virtual ASIOError outputReady() = 0;
-};

+ 0 - 572
source/AudioDecode/AudioDecoder/lib/RtAudio/include/iasiothiscallresolver.cpp

@@ -1,572 +0,0 @@
-/*
-	IASIOThiscallResolver.cpp see the comments in iasiothiscallresolver.h for
-    the top level description - this comment describes the technical details of
-    the implementation.
-
-    The latest version of this file is available from:
-    http://www.audiomulch.com/~rossb/code/calliasio
-
-    please email comments to Ross Bencina <rossb@audiomulch.com>
-
-    BACKGROUND
-
-    The IASIO interface declared in the Steinberg ASIO 2 SDK declares
-    functions with no explicit calling convention. This causes MSVC++ to default
-    to using the thiscall convention, which is a proprietary convention not
-    implemented by some non-microsoft compilers - notably borland BCC,
-    C++Builder, and gcc. MSVC++ is the defacto standard compiler used by
-    Steinberg. As a result of this situation, the ASIO sdk will compile with
-    any compiler, however attempting to execute the compiled code will cause a
-    crash due to different default calling conventions on non-Microsoft
-    compilers.
-
-    IASIOThiscallResolver solves the problem by providing an adapter class that
-    delegates to the IASIO interface using the correct calling convention
-    (thiscall). Due to the lack of support for thiscall in the Borland and GCC
-    compilers, the calls have been implemented in assembly language.
-
-    A number of macros are defined for thiscall function calls with different
-    numbers of parameters, with and without return values - it may be possible
-    to modify the format of these macros to make them work with other inline
-    assemblers.
-
-
-    THISCALL DEFINITION
-
-    A number of definitions of the thiscall calling convention are floating
-    around the internet. The following definition has been validated against
-    output from the MSVC++ compiler:
-
-    For non-vararg functions, thiscall works as follows: the object (this)
-    pointer is passed in ECX. All arguments are passed on the stack in
-    right to left order. The return value is placed in EAX. The callee
-    clears the passed arguments from the stack.
-
-
-    FINDING FUNCTION POINTERS FROM AN IASIO POINTER
-
-    The first field of a COM object is a pointer to its vtble. Thus a pointer
-    to an object implementing the IASIO interface also points to a pointer to
-    that object's vtbl. The vtble is a table of function pointers for all of
-    the virtual functions exposed by the implemented interfaces.
-
-    If we consider a variable declared as a pointer to IASO:
-
-    IASIO *theAsioDriver
-
-    theAsioDriver points to:
-
-    object implementing IASIO
-    {
-        IASIOvtbl *vtbl
-        other data
-    }
-
-    in other words, theAsioDriver points to a pointer to an IASIOvtbl
-
-    vtbl points to a table of function pointers:
-
-    IASIOvtbl ( interface IASIO : public IUnknown )
-    {
-    (IUnknown functions)
-    0   virtual HRESULT STDMETHODCALLTYPE (*QueryInterface)(REFIID riid, void **ppv) = 0;
-    4   virtual ULONG STDMETHODCALLTYPE (*AddRef)() = 0;
-    8   virtual ULONG STDMETHODCALLTYPE (*Release)() = 0;      
-
-    (IASIO functions)
-    12	virtual ASIOBool (*init)(void *sysHandle) = 0;
-    16	virtual void (*getDriverName)(char *name) = 0;
-    20	virtual long (*getDriverVersion)() = 0;
-    24	virtual void (*getErrorMessage)(char *string) = 0;
-    28	virtual ASIOError (*start)() = 0;
-    32	virtual ASIOError (*stop)() = 0;
-    36	virtual ASIOError (*getChannels)(long *numInputChannels, long *numOutputChannels) = 0;
-    40	virtual ASIOError (*getLatencies)(long *inputLatency, long *outputLatency) = 0;
-    44	virtual ASIOError (*getBufferSize)(long *minSize, long *maxSize,
-            long *preferredSize, long *granularity) = 0;
-    48	virtual ASIOError (*canSampleRate)(ASIOSampleRate sampleRate) = 0;
-    52	virtual ASIOError (*getSampleRate)(ASIOSampleRate *sampleRate) = 0;
-    56	virtual ASIOError (*setSampleRate)(ASIOSampleRate sampleRate) = 0;
-    60	virtual ASIOError (*getClockSources)(ASIOClockSource *clocks, long *numSources) = 0;
-    64	virtual ASIOError (*setClockSource)(long reference) = 0;
-    68	virtual ASIOError (*getSamplePosition)(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;
-    72	virtual ASIOError (*getChannelInfo)(ASIOChannelInfo *info) = 0;
-    76	virtual ASIOError (*createBuffers)(ASIOBufferInfo *bufferInfos, long numChannels,
-            long bufferSize, ASIOCallbacks *callbacks) = 0;
-    80	virtual ASIOError (*disposeBuffers)() = 0;
-    84	virtual ASIOError (*controlPanel)() = 0;
-    88	virtual ASIOError (*future)(long selector,void *opt) = 0;
-    92	virtual ASIOError (*outputReady)() = 0;
-    };
-
-    The numbers in the left column show the byte offset of each function ptr
-    from the beginning of the vtbl. These numbers are used in the code below
-    to select different functions.
-
-    In order to find the address of a particular function, theAsioDriver
-    must first be dereferenced to find the value of the vtbl pointer:
-
-    mov     eax, theAsioDriver
-    mov     edx, [theAsioDriver]  // edx now points to vtbl[0]
-
-    Then an offset must be added to the vtbl pointer to select a
-    particular function, for example vtbl+44 points to the slot containing
-    a pointer to the getBufferSize function.
-
-    Finally vtbl+x must be dereferenced to obtain the value of the function
-    pointer stored in that address:
-
-    call    [edx+44]    // call the function pointed to by
-                        // the value in the getBufferSize field of the vtbl
-
-
-    SEE ALSO
-
-    Martin Fay's OpenASIO DLL at http://www.martinfay.com solves the same
-    problem by providing a new COM interface which wraps IASIO with an
-    interface that uses portable calling conventions. OpenASIO must be compiled
-    with MSVC, and requires that you ship the OpenASIO DLL with your
-    application.
-
-    
-    ACKNOWLEDGEMENTS
-
-    Ross Bencina: worked out the thiscall details above, wrote the original
-    Borland asm macros, and a patch for asio.cpp (which is no longer needed).
-    Thanks to Martin Fay for introducing me to the issues discussed here,
-    and to Rene G. Ceballos for assisting with asm dumps from MSVC++.
-
-    Antti Silvast: converted the original calliasio to work with gcc and NASM
-    by implementing the asm code in a separate file.
-
-	Fraser Adams: modified the original calliasio containing the Borland inline
-    asm to add inline asm for gcc i.e. Intel syntax for Borland and AT&T syntax
-    for gcc. This seems a neater approach for gcc than to have a separate .asm
-    file and it means that we only need one version of the thiscall patch.
-
-    Fraser Adams: rewrote the original calliasio patch in the form of the
-    IASIOThiscallResolver class in order to avoid modifications to files from
-    the Steinberg SDK, which may have had potential licence issues.
-
-    Andrew Baldwin: contributed fixes for compatibility problems with more
-    recent versions of the gcc assembler.
-*/
-
-
-// We only need IASIOThiscallResolver at all if we are on Win32. For other
-// platforms we simply bypass the IASIOThiscallResolver definition to allow us
-// to be safely #include'd whatever the platform to keep client code portable
-#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN64)
-
-
-// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver
-// is not used.
-#if !defined(_MSC_VER)
-
-
-#include <new>
-#include <assert.h>
-
-// We have a mechanism in iasiothiscallresolver.h to ensure that asio.h is
-// #include'd before it in client code, we do NOT want to do this test here.
-#define iasiothiscallresolver_sourcefile 1
-#include "iasiothiscallresolver.h"
-#undef iasiothiscallresolver_sourcefile
-
-// iasiothiscallresolver.h redefines ASIOInit for clients, but we don't want
-// this macro defined in this translation unit.
-#undef ASIOInit
-
-
-// theAsioDriver is a global pointer to the current IASIO instance which the
-// ASIO SDK uses to perform all actions on the IASIO interface. We substitute
-// our own forwarding interface into this pointer.
-extern IASIO* theAsioDriver;
-
-
-// The following macros define the inline assembler for BORLAND first then gcc
-
-#if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)          
-
-
-#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )\
-    void *this_ = (thisPtr);                                                \
-    __asm {                                                                 \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-        mov     resultName, eax       ;                                     \
-    }
-
-
-#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )\
-    void *this_ = (thisPtr);                                                \
-    __asm {                                                                 \
-        mov     eax, param1           ;                                     \
-        push    eax                   ;                                     \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-    }
-
-
-#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )\
-    void *this_ = (thisPtr);                                                \
-    __asm {                                                                 \
-        mov     eax, param1           ;                                     \
-        push    eax                   ;                                     \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-        mov     resultName, eax       ;                                     \
-    }
-
-
-#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )\
-    void *this_ = (thisPtr);                                                \
-    void *doubleParamPtr_ (&param1);                                        \
-    __asm {                                                                 \
-        mov     eax, doubleParamPtr_  ;                                     \
-        push    [eax+4]               ;                                     \
-        push    [eax]                 ;                                     \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-        mov     resultName, eax       ;                                     \
-    }
-
-
-#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )\
-    void *this_ = (thisPtr);                                                \
-    __asm {                                                                 \
-        mov     eax, param2           ;                                     \
-        push    eax                   ;                                     \
-        mov     eax, param1           ;                                     \
-        push    eax                   ;                                     \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-        mov     resultName, eax       ;                                     \
-    }
-
-
-#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\
-    void *this_ = (thisPtr);                                                \
-    __asm {                                                                 \
-        mov     eax, param4           ;                                     \
-        push    eax                   ;                                     \
-        mov     eax, param3           ;                                     \
-        push    eax                   ;                                     \
-        mov     eax, param2           ;                                     \
-        push    eax                   ;                                     \
-        mov     eax, param1           ;                                     \
-        push    eax                   ;                                     \
-        mov     ecx, this_            ;                                     \
-        mov     eax, [ecx]            ;                                     \
-        call    [eax+funcOffset]      ;                                     \
-        mov     resultName, eax       ;                                     \
-    }
-
-
-#elif defined(__GNUC__)
-
-
-#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )                  \
-    __asm__ __volatile__ ("movl (%1), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx)\n\t"                  \
-                          :"=a"(resultName) /* Output Operands */           \
-                          :"c"(thisPtr)     /* Input Operands */            \
-                          : "%edx" /* Clobbered Registers */                \
-                         );                                                 \
-
-
-#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )                 \
-    __asm__ __volatile__ ("pushl %0\n\t"                                    \
-                          "movl (%1), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx)\n\t"                  \
-                          :                 /* Output Operands */           \
-                          :"r"(param1),     /* Input Operands */            \
-                           "c"(thisPtr)                                     \
-                          : "%edx" /* Clobbered Registers */                \
-                         );                                                 \
-
-
-#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )          \
-    __asm__ __volatile__ ("pushl %1\n\t"                                    \
-                          "movl (%2), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx)\n\t"                  \
-                          :"=a"(resultName) /* Output Operands */           \
-                          :"r"(param1),     /* Input Operands */            \
-                           "c"(thisPtr)                                     \
-                          : "%edx" /* Clobbered Registers */                \
-                          );                                                \
-
-
-#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )   \
-    do {                                                                    \
-    double param1f64 = param1; /* Cast explicitly to double */              \
-    double *param1f64Ptr = &param1f64; /* Make pointer to address */        \
-     __asm__ __volatile__ ("pushl 4(%1)\n\t"                                \
-                           "pushl (%1)\n\t"                                 \
-                           "movl (%2), %%edx\n\t"                           \
-                           "call *"#funcOffset"(%%edx);\n\t"                \
-                           : "=a"(resultName) /* Output Operands */         \
-                           : "r"(param1f64Ptr),  /* Input Operands */       \
-                           "c"(thisPtr),                                    \
-                           "m"(*param1f64Ptr) /* Using address */           \
-                           : "%edx" /* Clobbered Registers */               \
-                           );                                               \
-    } while (0);                                                            \
-
-
-#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )  \
-    __asm__ __volatile__ ("pushl %1\n\t"                                    \
-                          "pushl %2\n\t"                                    \
-                          "movl (%3), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx)\n\t"                  \
-                          :"=a"(resultName) /* Output Operands */           \
-                          :"r"(param2),     /* Input Operands */            \
-                           "r"(param1),                                     \
-                           "c"(thisPtr)                                     \
-                          : "%edx" /* Clobbered Registers */                \
-                          );                                                \
-
-
-#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\
-    __asm__ __volatile__ ("pushl %1\n\t"                                    \
-                          "pushl %2\n\t"                                    \
-                          "pushl %3\n\t"                                    \
-                          "pushl %4\n\t"                                    \
-                          "movl (%5), %%edx\n\t"                            \
-                          "call *"#funcOffset"(%%edx)\n\t"                  \
-                          :"=a"(resultName) /* Output Operands */           \
-                          :"r"(param4),     /* Input Operands  */           \
-                           "r"(param3),                                     \
-                           "r"(param2),                                     \
-                           "r"(param1),                                     \
-                           "c"(thisPtr)                                     \
-                          : "%edx" /* Clobbered Registers */                \
-                          );                                                \
-
-#endif
-
-
-
-// Our static singleton instance.
-IASIOThiscallResolver IASIOThiscallResolver::instance;
-
-// Constructor called to initialize static Singleton instance above. Note that
-// it is important not to clear that_ incase it has already been set by the call
-// to placement new in ASIOInit().
-IASIOThiscallResolver::IASIOThiscallResolver()
-{
-}
-
-// Constructor called from ASIOInit() below
-IASIOThiscallResolver::IASIOThiscallResolver(IASIO* that)
-: that_( that )
-{
-}
-
-// Implement IUnknown methods as assert(false). IASIOThiscallResolver is not
-// really a COM object, just a wrapper which will work with the ASIO SDK.
-// If you wanted to use ASIO without the SDK you might want to implement COM
-// aggregation in these methods.
-HRESULT STDMETHODCALLTYPE IASIOThiscallResolver::QueryInterface(REFIID riid, void **ppv)
-{
-    (void)riid;     // suppress unused variable warning
-
-    assert( false ); // this function should never be called by the ASIO SDK.
-
-    *ppv = NULL;
-    return E_NOINTERFACE;
-}
-
-ULONG STDMETHODCALLTYPE IASIOThiscallResolver::AddRef()
-{
-    assert( false ); // this function should never be called by the ASIO SDK.
-
-    return 1;
-}
-
-ULONG STDMETHODCALLTYPE IASIOThiscallResolver::Release()
-{
-    assert( false ); // this function should never be called by the ASIO SDK.
-    
-    return 1;
-}
-
-
-// Implement the IASIO interface methods by performing the vptr manipulation
-// described above then delegating to the real implementation.
-ASIOBool IASIOThiscallResolver::init(void *sysHandle)
-{
-    ASIOBool result;
-    CALL_THISCALL_1( result, that_, 12, sysHandle );
-    return result;
-}
-
-void IASIOThiscallResolver::getDriverName(char *name)
-{
-    CALL_VOID_THISCALL_1( that_, 16, name );
-}
-
-long IASIOThiscallResolver::getDriverVersion()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 20 );
-    return result;
-}
-
-void IASIOThiscallResolver::getErrorMessage(char *string)
-{
-     CALL_VOID_THISCALL_1( that_, 24, string );
-}
-
-ASIOError IASIOThiscallResolver::start()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 28 );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::stop()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 32 );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getChannels(long *numInputChannels, long *numOutputChannels)
-{
-    ASIOBool result;
-    CALL_THISCALL_2( result, that_, 36, numInputChannels, numOutputChannels );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getLatencies(long *inputLatency, long *outputLatency)
-{
-    ASIOBool result;
-    CALL_THISCALL_2( result, that_, 40, inputLatency, outputLatency );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getBufferSize(long *minSize, long *maxSize,
-        long *preferredSize, long *granularity)
-{
-    ASIOBool result;
-    CALL_THISCALL_4( result, that_, 44, minSize, maxSize, preferredSize, granularity );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::canSampleRate(ASIOSampleRate sampleRate)
-{
-    ASIOBool result;
-    CALL_THISCALL_1_DOUBLE( result, that_, 48, sampleRate );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getSampleRate(ASIOSampleRate *sampleRate)
-{
-    ASIOBool result;
-    CALL_THISCALL_1( result, that_, 52, sampleRate );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::setSampleRate(ASIOSampleRate sampleRate)
-{    
-    ASIOBool result;
-    CALL_THISCALL_1_DOUBLE( result, that_, 56, sampleRate );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getClockSources(ASIOClockSource *clocks, long *numSources)
-{
-    ASIOBool result;
-    CALL_THISCALL_2( result, that_, 60, clocks, numSources );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::setClockSource(long reference)
-{
-    ASIOBool result;
-    CALL_THISCALL_1( result, that_, 64, reference );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)
-{
-    ASIOBool result;
-    CALL_THISCALL_2( result, that_, 68, sPos, tStamp );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::getChannelInfo(ASIOChannelInfo *info)
-{
-    ASIOBool result;
-    CALL_THISCALL_1( result, that_, 72, info );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::createBuffers(ASIOBufferInfo *bufferInfos,
-        long numChannels, long bufferSize, ASIOCallbacks *callbacks)
-{
-    ASIOBool result;
-    CALL_THISCALL_4( result, that_, 76, bufferInfos, numChannels, bufferSize, callbacks );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::disposeBuffers()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 80 );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::controlPanel()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 84 );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::future(long selector,void *opt)
-{
-    ASIOBool result;
-    CALL_THISCALL_2( result, that_, 88, selector, opt );
-    return result;
-}
-
-ASIOError IASIOThiscallResolver::outputReady()
-{
-    ASIOBool result;
-    CALL_THISCALL_0( result, that_, 92 );
-    return result;
-}
-
-
-// Implement our substitute ASIOInit() method
-ASIOError IASIOThiscallResolver::ASIOInit(ASIODriverInfo *info)
-{
-    // To ensure that our instance's vptr is correctly constructed, even if
-    // ASIOInit is called prior to main(), we explicitly call its constructor
-    // (potentially over the top of an existing instance). Note that this is
-    // pretty ugly, and is only safe because IASIOThiscallResolver has no
-    // destructor and contains no objects with destructors.
-    new((void*)&instance) IASIOThiscallResolver( theAsioDriver );
-
-    // Interpose between ASIO client code and the real driver.
-    theAsioDriver = &instance;
-
-    // Note that we never need to switch theAsioDriver back to point to the
-    // real driver because theAsioDriver is reset to zero in ASIOExit().
-
-    // Delegate to the real ASIOInit
-	return ::ASIOInit(info);
-}
-
-
-#endif /* !defined(_MSC_VER) */
-
-#endif /* Win32 */
-

+ 0 - 202
source/AudioDecode/AudioDecoder/lib/RtAudio/include/iasiothiscallresolver.h

@@ -1,202 +0,0 @@
-// ****************************************************************************
-//
-// Changed:         I have modified this file slightly (includes) to work  with
-//                  RtAudio. RtAudio.cpp must include this file after asio.h.                                                    
-//
-// File:			IASIOThiscallResolver.h
-// Description:     The IASIOThiscallResolver class implements the IASIO
-//					interface and acts as a proxy to the real IASIO interface by
-//                  calling through its vptr table using the thiscall calling
-//                  convention. To put it another way, we interpose
-//                  IASIOThiscallResolver between ASIO SDK code and the driver.
-//                  This is necessary because most non-Microsoft compilers don't
-//                  implement the thiscall calling convention used by IASIO.
-//
-//					iasiothiscallresolver.cpp contains the background of this
-//					problem plus a technical description of the vptr
-//                  manipulations.
-//
-//					In order to use this mechanism one simply has to add
-//					iasiothiscallresolver.cpp to the list of files to compile
-//                  and #include <iasiothiscallresolver.h>
-//
-//					Note that this #include must come after the other ASIO SDK
-//                  #includes, for example:
-//
-//					#include <windows.h>
-//					#include <asiosys.h>
-//					#include <asio.h>
-//					#include <asiodrivers.h>
-//					#include <iasiothiscallresolver.h>
-//
-//					Actually the important thing is to #include
-//                  <iasiothiscallresolver.h> after <asio.h>. We have
-//                  incorporated a test to enforce this ordering.
-//
-//					The code transparently takes care of the interposition by
-//                  using macro substitution to intercept calls to ASIOInit()
-//                  and ASIOExit(). We save the original ASIO global
-//                  "theAsioDriver" in our "that" variable, and then set
-//                  "theAsioDriver" to equal our IASIOThiscallResolver instance.
-//
-// 					Whilst this method of resolving the thiscall problem requires
-//					the addition of #include <iasiothiscallresolver.h> to client
-//                  code it has the advantage that it does not break the terms
-//                  of the ASIO licence by publishing it. We are NOT modifying
-//                  any Steinberg code here, we are merely implementing the IASIO
-//					interface in the same way that we would need to do if we
-//					wished to provide an open source ASIO driver.
-//
-//					For compilation with MinGW -lole32 needs to be added to the
-//                  linker options. For BORLAND, linking with Import32.lib is
-//                  sufficient.
-//
-//					The dependencies are with: CoInitialize, CoUninitialize,
-//					CoCreateInstance, CLSIDFromString - used by asiolist.cpp
-//					and are required on Windows whether ThiscallResolver is used
-//					or not.
-//
-//					Searching for the above strings in the root library path
-//					of your compiler should enable the correct libraries to be
-//					identified if they aren't immediately obvious.
-//
-//                  Note that the current implementation of IASIOThiscallResolver
-//                  is not COM compliant - it does not correctly implement the
-//                  IUnknown interface. Implementing it is not necessary because
-//                  it is not called by parts of the ASIO SDK which call through
-//                  theAsioDriver ptr. The IUnknown methods are implemented as
-//                  assert(false) to ensure that the code fails if they are
-//                  ever called.
-// Restrictions:	None. Public Domain & Open Source distribute freely
-//					You may use IASIOThiscallResolver commercially as well as
-//                  privately.
-//					You the user assume the responsibility for the use of the
-//					files, binary or text, and there is no guarantee or warranty,
-//					expressed or implied, including but not limited to the
-//					implied warranties of merchantability and fitness for a
-//					particular purpose. You assume all responsibility and agree
-//					to hold no entity, copyright holder or distributors liable
-//					for any loss of data or inaccurate representations of data
-//					as a result of using IASIOThiscallResolver.
-// Version:         1.4 Added separate macro CALL_THISCALL_1_DOUBLE from
-//                  Andrew Baldwin, and volatile for whole gcc asm blocks,
-//                  both for compatibility with newer gcc versions. Cleaned up
-//                  Borland asm to use one less register.
-//                  1.3 Switched to including assert.h for better compatibility.
-//                  Wrapped entire .h and .cpp contents with a check for
-//                  _MSC_VER to provide better compatibility with MS compilers.
-//                  Changed Singleton implementation to use static instance
-//                  instead of freestore allocated instance. Removed ASIOExit
-//                  macro as it is no longer needed.
-//                  1.2 Removed semicolons from ASIOInit and ASIOExit macros to
-//                  allow them to be embedded in expressions (if statements).
-//                  Cleaned up some comments. Removed combase.c dependency (it
-//                  doesn't compile with BCB anyway) by stubbing IUnknown.
-//                  1.1 Incorporated comments from Ross Bencina including things
-//					such as changing name from ThiscallResolver to
-//					IASIOThiscallResolver, tidying up the constructor, fixing
-//					a bug in IASIOThiscallResolver::ASIOExit() and improving
-//					portability through the use of conditional compilation
-//					1.0 Initial working version.
-// Created:			6/09/2003
-// Authors:         Fraser Adams
-//                  Ross Bencina
-//                  Rene G. Ceballos
-//                  Martin Fay
-//                  Antti Silvast
-//                  Andrew Baldwin
-//
-// ****************************************************************************
-
-
-#ifndef included_iasiothiscallresolver_h
-#define included_iasiothiscallresolver_h
-
-// We only need IASIOThiscallResolver at all if we are on Win32. For other
-// platforms we simply bypass the IASIOThiscallResolver definition to allow us
-// to be safely #include'd whatever the platform to keep client code portable
-//#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
-#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN64)
-
-
-// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver
-// is not used.
-#if !defined(_MSC_VER)
-
-
-// The following is in order to ensure that this header is only included after
-// the other ASIO headers (except for the case of iasiothiscallresolver.cpp).
-// We need to do this because IASIOThiscallResolver works by eclipsing the
-// original definition of ASIOInit() with a macro (see below).
-#if !defined(iasiothiscallresolver_sourcefile)
-	#if !defined(__ASIO_H)
-	#error iasiothiscallresolver.h must be included AFTER asio.h
-	#endif
-#endif
-
-#include <windows.h>
-#include "iasiodrv.h" /* From ASIO SDK */
-
-
-class IASIOThiscallResolver : public IASIO {
-private:
-	IASIO* that_; // Points to the real IASIO
-
-	static IASIOThiscallResolver instance; // Singleton instance
-
-	// Constructors - declared private so construction is limited to
-    // our Singleton instance
-    IASIOThiscallResolver();
-	IASIOThiscallResolver(IASIO* that);
-public:
-
-    // Methods from the IUnknown interface. We don't fully implement IUnknown
-    // because the ASIO SDK never calls these methods through theAsioDriver ptr.
-    // These methods are implemented as assert(false).
-    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv);
-    virtual ULONG STDMETHODCALLTYPE AddRef();
-    virtual ULONG STDMETHODCALLTYPE Release();
-
-    // Methods from the IASIO interface, implemented as forwarning calls to that.
-	virtual ASIOBool init(void *sysHandle);
-	virtual void getDriverName(char *name);
-	virtual long getDriverVersion();
-	virtual void getErrorMessage(char *string);
-	virtual ASIOError start();
-	virtual ASIOError stop();
-	virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);
-	virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);
-	virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);
-	virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);
-	virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);
-	virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);
-	virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);
-	virtual ASIOError setClockSource(long reference);
-	virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp);
-	virtual ASIOError getChannelInfo(ASIOChannelInfo *info);
-	virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks);
-	virtual ASIOError disposeBuffers();
-	virtual ASIOError controlPanel();
-	virtual ASIOError future(long selector,void *opt);
-	virtual ASIOError outputReady();
-
-    // Class method, see ASIOInit() macro below.
-    static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit
-};
-
-
-// Replace calls to ASIOInit with our interposing version.
-// This macro enables us to perform thiscall resolution simply by #including
-// <iasiothiscallresolver.h> after the asio #includes (this file _must_ be
-// included _after_ the asio #includes)
-
-#define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name))
-
-
-#endif /* !defined(_MSC_VER) */
-
-#endif /* Win32 */
-
-#endif /* included_iasiothiscallresolver_h */
-
-

+ 0 - 1878
source/AudioDecode/AudioDecoder/lib/RtAudio/include/soundcard.h

@@ -1,1878 +0,0 @@
-/*
- * soundcard.h
- */
-
-/*-
- * Copyright by Hannu Savolainen 1993 / 4Front Technologies 1993-2006
- * Modified for the new FreeBSD sound driver by Luigi Rizzo, 1997
- *
- * Redistribution and use in source and binary forms, with or 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.
- *
- * $FreeBSD: src/sys/sys/soundcard.h,v 1.48 2006/11/26 11:55:48 netchild Exp $
- */
-
-/*
- * Unless coordinating changes with 4Front Technologies, do NOT make any
- * modifications to ioctl commands, types, etc. that would break
- * compatibility with the OSS API.
- */
-
-#ifndef _SYS_SOUNDCARD_H_
-#define _SYS_SOUNDCARD_H_
- /*
-  * If you make modifications to this file, please contact me before
-  * distributing the modified version. There is already enough
-  * diversity in the world.
-  *
-  * Regards,
-  * Hannu Savolainen
-  * hannu@voxware.pp.fi
-  *
-  **********************************************************************
-  * PS.	The Hacker's Guide to VoxWare available from
-  *     nic.funet.fi:pub/Linux/ALPHA/sound. The file is
-  *	snd-sdk-doc-0.1.ps.gz (gzipped postscript). It contains
-  *	some useful information about programming with VoxWare.
-  *	(NOTE! The pub/Linux/ALPHA/ directories are hidden. You have
-  *	to cd inside them before the files are accessible.)
-  **********************************************************************
-  */
-
-/*
- * SOUND_VERSION is only used by the voxware driver. Hopefully apps
- * should not depend on it, but rather look at the capabilities
- * of the driver in the kernel!
- */
-#define SOUND_VERSION  301
-#define VOXWARE		/* does this have any use ? */
-
-/*
- * Supported card ID numbers (Should be somewhere else? We keep
- * them here just for compativility with the old driver, but these
- * constants are of little or no use).
- */
-
-#define SNDCARD_ADLIB          1
-#define SNDCARD_SB             2
-#define SNDCARD_PAS            3
-#define SNDCARD_GUS            4
-#define SNDCARD_MPU401         5
-#define SNDCARD_SB16           6
-#define SNDCARD_SB16MIDI       7
-#define SNDCARD_UART6850       8
-#define SNDCARD_GUS16          9
-#define SNDCARD_MSS            10
-#define SNDCARD_PSS            11
-#define SNDCARD_SSCAPE         12
-#define SNDCARD_PSS_MPU        13
-#define SNDCARD_PSS_MSS        14
-#define SNDCARD_SSCAPE_MSS     15
-#define SNDCARD_TRXPRO         16
-#define SNDCARD_TRXPRO_SB      17
-#define SNDCARD_TRXPRO_MPU     18
-#define SNDCARD_MAD16          19
-#define SNDCARD_MAD16_MPU      20
-#define SNDCARD_CS4232         21
-#define SNDCARD_CS4232_MPU     22
-#define SNDCARD_MAUI           23
-#define SNDCARD_PSEUDO_MSS     24
-#define SNDCARD_AWE32          25
-#define SNDCARD_NSS            26
-#define SNDCARD_UART16550      27
-#define SNDCARD_OPL            28
-
-#include <sys/types.h>
-#include <machine/endian.h>
-#ifndef _IOWR
-#include <sys/ioccom.h>
-#endif  /* !_IOWR */
-
-/*
- * The first part of this file contains the new FreeBSD sound ioctl
- * interface. Tries to minimize the number of different ioctls, and
- * to be reasonably general.
- *
- * 970821: some of the new calls have not been implemented yet.
- */
-
-/*
- * the following three calls extend the generic file descriptor
- * interface. AIONWRITE is the dual of FIONREAD, i.e. returns the max
- * number of bytes for a write operation to be non-blocking.
- *
- * AIOGSIZE/AIOSSIZE are used to change the behaviour of the device,
- * from a character device (default) to a block device. In block mode,
- * (not to be confused with blocking mode) the main difference for the
- * application is that select() will return only when a complete
- * block can be read/written to the device, whereas in character mode
- * select will return true when one byte can be exchanged. For audio
- * devices, character mode makes select almost useless since one byte
- * will always be ready by the next sample time (which is often only a
- * handful of microseconds away).
- * Use a size of 0 or 1 to return to character mode.
- */
-#define	AIONWRITE   _IOR('A', 10, int)   /* get # bytes to write */
-struct snd_size {
-    int play_size;
-    int rec_size;
-};
-#define	AIOGSIZE    _IOR('A', 11, struct snd_size)/* read current blocksize */
-#define	AIOSSIZE    _IOWR('A', 11, struct snd_size)  /* sets blocksize */
-
-/*
- * The following constants define supported audio formats. The
- * encoding follows voxware conventions, i.e. 1 bit for each supported
- * format. We extend it by using bit 31 (RO) to indicate full-duplex
- * capability, and bit 29 (RO) to indicate that the card supports/
- * needs different formats on capture & playback channels.
- * Bit 29 (RW) is used to indicate/ask stereo.
- *
- * The number of bits required to store the sample is:
- *  o  4 bits for the IDA ADPCM format,
- *  o  8 bits for 8-bit formats, mu-law and A-law,
- *  o  16 bits for the 16-bit formats, and
- *  o  32 bits for the 24/32-bit formats.
- *  o  undefined for the MPEG audio format.
- */
-
-#define AFMT_QUERY	0x00000000	/* Return current format */
-#define AFMT_MU_LAW	0x00000001	/* Logarithmic mu-law */
-#define AFMT_A_LAW	0x00000002	/* Logarithmic A-law */
-#define AFMT_IMA_ADPCM	0x00000004	/* A 4:1 compressed format where 16-bit
-					 * squence represented using the
-					 * the average 4 bits per sample */
-#define AFMT_U8		0x00000008	/* Unsigned 8-bit */
-#define AFMT_S16_LE	0x00000010	/* Little endian signed 16-bit */
-#define AFMT_S16_BE	0x00000020	/* Big endian signed 16-bit */
-#define AFMT_S8		0x00000040	/* Signed 8-bit */
-#define AFMT_U16_LE	0x00000080	/* Little endian unsigned 16-bit */
-#define AFMT_U16_BE	0x00000100	/* Big endian unsigned 16-bit */
-#define AFMT_MPEG	0x00000200	/* MPEG MP2/MP3 audio */
-#define AFMT_AC3	0x00000400	/* Dolby Digital AC3 */
-
-#if _BYTE_ORDER == _LITTLE_ENDIAN
-#define AFMT_S16_NE	AFMT_S16_LE	/* native endian signed 16 */
-#else
-#define AFMT_S16_NE	AFMT_S16_BE
-#endif
-
-/*
- * 32-bit formats below used for 24-bit audio data where the data is stored
- * in the 24 most significant bits and the least significant bits are not used
- * (should be set to 0).
- */
-#define AFMT_S32_LE	0x00001000	/* Little endian signed 32-bit */
-#define AFMT_S32_BE	0x00002000	/* Big endian signed 32-bit */
-#define AFMT_U32_LE	0x00004000	/* Little endian unsigned 32-bit */
-#define AFMT_U32_BE	0x00008000	/* Big endian unsigned 32-bit */
-#define AFMT_S24_LE	0x00010000	/* Little endian signed 24-bit */
-#define AFMT_S24_BE	0x00020000	/* Big endian signed 24-bit */
-#define AFMT_U24_LE	0x00040000	/* Little endian unsigned 24-bit */
-#define AFMT_U24_BE	0x00080000	/* Big endian unsigned 24-bit */
-
-#define AFMT_STEREO	0x10000000	/* can do/want stereo	*/
-
-/*
- * the following are really capabilities
- */
-#define AFMT_WEIRD	0x20000000	/* weird hardware...	*/
-    /*
-     * AFMT_WEIRD reports that the hardware might need to operate
-     * with different formats in the playback and capture
-     * channels when operating in full duplex.
-     * As an example, SoundBlaster16 cards only support U8 in one
-     * direction and S16 in the other one, and applications should
-     * be aware of this limitation.
-     */
-#define AFMT_FULLDUPLEX	0x80000000	/* can do full duplex	*/
-
-/*
- * The following structure is used to get/set format and sampling rate.
- * While it would be better to have things such as stereo, bits per
- * sample, endiannes, etc split in different variables, it turns out
- * that formats are not that many, and not all combinations are possible.
- * So we followed the Voxware approach of associating one bit to each
- * format.
- */
-
-typedef struct _snd_chan_param {
-    u_long	play_rate;	/* sampling rate			*/
-    u_long	rec_rate;	/* sampling rate			*/
-    u_long	play_format;	/* everything describing the format	*/
-    u_long	rec_format;	/* everything describing the format	*/
-} snd_chan_param;
-#define	AIOGFMT    _IOR('f', 12, snd_chan_param)   /* get format */
-#define	AIOSFMT    _IOWR('f', 12, snd_chan_param)  /* sets format */
-
-/*
- * The following structure is used to get/set the mixer setting.
- * Up to 32 mixers are supported, each one with up to 32 channels.
- */
-typedef struct _snd_mix_param {
-    u_char	subdev;	/* which output				*/
-    u_char	line;	/* which input				*/
-    u_char	left,right; /* volumes, 0..255, 0 = mute	*/
-} snd_mix_param ;
-
-/* XXX AIOGMIX, AIOSMIX not implemented yet */
-#define AIOGMIX	_IOWR('A', 13, snd_mix_param)	/* return mixer status */
-#define AIOSMIX	_IOWR('A', 14, snd_mix_param)	/* sets mixer status   */
-
-/*
- * channel specifiers used in AIOSTOP and AIOSYNC
- */
-#define	AIOSYNC_PLAY	0x1	/* play chan */
-#define	AIOSYNC_CAPTURE	0x2	/* capture chan */
-/* AIOSTOP stop & flush a channel, returns the residual count */
-#define	AIOSTOP	_IOWR ('A', 15, int)
-
-/* alternate method used to notify the sync condition */
-#define	AIOSYNC_SIGNAL	0x100
-#define	AIOSYNC_SELECT	0x200
-
-/* what the 'pos' field refers to */
-#define AIOSYNC_READY	0x400
-#define AIOSYNC_FREE	0x800
-
-typedef struct _snd_sync_parm {
-    long chan ; /* play or capture channel, plus modifier */
-    long pos;
-} snd_sync_parm;
-#define	AIOSYNC	_IOWR ('A', 15, snd_sync_parm)	/* misc. synchronization */
-
-/*
- * The following is used to return device capabilities. If the structure
- * passed to the ioctl is zeroed, default values are returned for rate
- * and formats, a bitmap of available mixers is returned, and values
- * (inputs, different levels) for the first one are returned.
- *
- * If  formats, mixers, inputs are instantiated, then detailed info
- * are returned depending on the call.
- */
-typedef struct _snd_capabilities {
-    u_long	rate_min, rate_max;	/* min-max sampling rate */
-    u_long	formats;
-    u_long	bufsize; /* DMA buffer size */
-    u_long	mixers; /* bitmap of available mixers */
-    u_long	inputs; /* bitmap of available inputs (per mixer) */
-    u_short	left, right;	/* how many levels are supported */
-} snd_capabilities;
-#define AIOGCAP	_IOWR('A', 15, snd_capabilities)	/* get capabilities */
-
-/*
- * here is the old (Voxware) ioctl interface
- */
-
-/*
- * IOCTL Commands for /dev/sequencer
- */
-
-#define SNDCTL_SEQ_RESET	_IO  ('Q', 0)
-#define SNDCTL_SEQ_SYNC		_IO  ('Q', 1)
-#define SNDCTL_SYNTH_INFO	_IOWR('Q', 2, struct synth_info)
-#define SNDCTL_SEQ_CTRLRATE	_IOWR('Q', 3, int) /* Set/get timer res.(hz) */
-#define SNDCTL_SEQ_GETOUTCOUNT	_IOR ('Q', 4, int)
-#define SNDCTL_SEQ_GETINCOUNT	_IOR ('Q', 5, int)
-#define SNDCTL_SEQ_PERCMODE	_IOW ('Q', 6, int)
-#define SNDCTL_FM_LOAD_INSTR	_IOW ('Q', 7, struct sbi_instrument)	/* Valid for FM only */
-#define SNDCTL_SEQ_TESTMIDI	_IOW ('Q', 8, int)
-#define SNDCTL_SEQ_RESETSAMPLES	_IOW ('Q', 9, int)
-#define SNDCTL_SEQ_NRSYNTHS	_IOR ('Q',10, int)
-#define SNDCTL_SEQ_NRMIDIS	_IOR ('Q',11, int)
-#define SNDCTL_MIDI_INFO	_IOWR('Q',12, struct midi_info)
-#define SNDCTL_SEQ_THRESHOLD	_IOW ('Q',13, int)
-#define SNDCTL_SEQ_TRESHOLD	SNDCTL_SEQ_THRESHOLD	/* there was once a typo */
-#define SNDCTL_SYNTH_MEMAVL	_IOWR('Q',14, int) /* in=dev#, out=memsize */
-#define SNDCTL_FM_4OP_ENABLE	_IOW ('Q',15, int) /* in=dev# */
-#define SNDCTL_PMGR_ACCESS	_IOWR('Q',16, struct patmgr_info)
-#define SNDCTL_SEQ_PANIC	_IO  ('Q',17)
-#define SNDCTL_SEQ_OUTOFBAND	_IOW ('Q',18, struct seq_event_rec)
-#define SNDCTL_SEQ_GETTIME	_IOR ('Q',19, int)
-
-struct seq_event_rec {
-	u_char arr[8];
-};
-
-#define SNDCTL_TMR_TIMEBASE	_IOWR('T', 1, int)
-#define SNDCTL_TMR_START	_IO  ('T', 2)
-#define SNDCTL_TMR_STOP		_IO  ('T', 3)
-#define SNDCTL_TMR_CONTINUE	_IO  ('T', 4)
-#define SNDCTL_TMR_TEMPO	_IOWR('T', 5, int)
-#define SNDCTL_TMR_SOURCE	_IOWR('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	_IOW ('T', 7, int)
-#define SNDCTL_TMR_SELECT	_IOW ('T', 8, int)
-
-/*
- *	Endian aware patch key generation algorithm.
- */
-
-#if defined(_AIX) || defined(AIX)
-#  define _PATCHKEY(id) (0xfd00|id)
-#else
-#  define _PATCHKEY(id) ((id<<8)|0xfd)
-#endif
-
-/*
- *	Sample loading mechanism for internal synthesizers (/dev/sequencer)
- *	The following patch_info structure has been designed to support
- *	Gravis UltraSound. It tries to be universal format for uploading
- *	sample based patches but is probably too limited.
- */
-
-struct patch_info {
-/*		u_short key;		 Use GUS_PATCH here */
-	short key;		 /* Use GUS_PATCH here */
-#define GUS_PATCH	_PATCHKEY(0x04)
-#define OBSOLETE_GUS_PATCH	_PATCHKEY(0x02)
-
-	short device_no;	/* Synthesizer number */
-	short instr_no;		/* Midi pgm# */
-
-	u_long 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 */
-				/* 	(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 */
-/* Other bits must be zeroed */
-
-	long len;	/* Size of the wave data in bytes */
-	long 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.
- */
-
-	u_int base_freq;
-	u_long base_note;
-	u_long high_note;
-	u_long low_note;
-	int panning;	/* -128=left, 127=right */
-	int detuning;
-
-/*	New fields introduced in version 1.99.5	*/
-
-       /* Envelope. Enabled by mode bit WAVE_ENVELOPES	*/
-	u_char	env_rate[ 6 ];	 /* GUS HW ramping rate */
-	u_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
-	 */
-
-	u_char	tremolo_sweep;
-	u_char	tremolo_rate;
-	u_char	tremolo_depth;
-
-	u_char	vibrato_sweep;
-	u_char	vibrato_rate;
-	u_char	vibrato_depth;
-
-	int		scale_frequency;
-	u_int	scale_factor;		/* from 0 to 2048 or 0 to 2 */
-
-	int		volume;
-	int		spare[4];
-	char data[1];	/* The waveform data starts here */
-};
-
-struct sysex_info {
-	short key;		/* Use GUS_PATCH here */
-#define SYSEX_PATCH	_PATCHKEY(0x05)
-#define MAUI_PATCH	_PATCHKEY(0x06)
-	short device_no;	/* Synthesizer number */
-	long len;	/* Size of the sysex data in bytes */
-	u_char data[1];	/* Sysex data starts here */
-};
-
-/*
- * Patch management interface (/dev/sequencer, /dev/patmgr#)
- * Don't use these calls if you want to maintain compatibility with
- * the future versions of the driver.
- */
-
-#define PS_NO_PATCHES		0	/* No patch support on device */
-#define	PS_MGR_NOT_OK		1	/* Plain patch support (no mgr) */
-#define	PS_MGR_OK		2	/* Patch manager supported */
-#define	PS_MANAGED		3	/* Patch manager running */
-
-#define SNDCTL_PMGR_IFACE		_IOWR('P', 1, struct patmgr_info)
-
-/*
- * The patmgr_info is a fixed size structure which is used for two
- * different purposes. The intended use is for communication between
- * the application using /dev/sequencer and the patch manager daemon
- * associated with a synthesizer device (ioctl(SNDCTL_PMGR_ACCESS)).
- *
- * This structure is also used with ioctl(SNDCTL_PGMR_IFACE) which allows
- * a patch manager daemon to read and write device parameters. This
- * ioctl available through /dev/sequencer also. Avoid using it since it's
- * extremely hardware dependent. In addition access trough /dev/sequencer
- * may confuse the patch manager daemon.
- */
-
-struct patmgr_info {	/* Note! size must be < 4k since kmalloc() is used */
-	  u_long key;	/* Don't worry. Reserved for communication
-	  			   between the patch manager and the driver. */
-#define PM_K_EVENT		1 /* Event from the /dev/sequencer driver */
-#define PM_K_COMMAND		2 /* Request from an application */
-#define PM_K_RESPONSE		3 /* From patmgr to application */
-#define PM_ERROR		4 /* Error returned by the patmgr */
-	  int device;
-	  int command;
-
-/*
- * Commands 0x000 to 0xfff reserved for patch manager programs
- */
-#define PM_GET_DEVTYPE	1	/* Returns type of the patch mgr interface of dev */
-#define		PMTYPE_FM2	1	/* 2 OP fm */
-#define		PMTYPE_FM4	2	/* Mixed 4 or 2 op FM (OPL-3) */
-#define		PMTYPE_WAVE	3	/* Wave table synthesizer (GUS) */
-#define PM_GET_NRPGM	2	/* Returns max # of midi programs in parm1 */
-#define PM_GET_PGMMAP	3	/* Returns map of loaded midi programs in data8 */
-#define PM_GET_PGM_PATCHES 4	/* Return list of patches of a program (parm1) */
-#define PM_GET_PATCH	5	/* Return patch header of patch parm1 */
-#define PM_SET_PATCH	6	/* Set patch header of patch parm1 */
-#define PM_READ_PATCH	7	/* Read patch (wave) data */
-#define PM_WRITE_PATCH	8	/* Write patch (wave) data */
-
-/*
- * Commands 0x1000 to 0xffff are for communication between the patch manager
- * and the client
- */
-#define _PM_LOAD_PATCH	0x100
-
-/*
- * Commands above 0xffff reserved for device specific use
- */
-
-	long parm1;
-	long parm2;
-	long parm3;
-
-	union {
-		u_char data8[4000];
-		u_short data16[2000];
-		u_long data32[1000];
-		struct patch_info patch;
-	} data;
-};
-
-/*
- * When a patch manager daemon is present, it will be informed by the
- * driver when something important happens. For example when the
- * /dev/sequencer is opened or closed. A record with key == PM_K_EVENT is
- * returned. The command field contains the event type:
- */
-#define PM_E_OPENED		1	/* /dev/sequencer opened */
-#define PM_E_CLOSED		2	/* /dev/sequencer closed */
-#define PM_E_PATCH_RESET	3	/* SNDCTL_RESETSAMPLES called */
-#define PM_E_PATCH_LOADED	4	/* A patch has been loaded by appl */
-
-/*
- * /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.
- */
-#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
-
-/*
- *	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 - 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		CTL_DAMPER_PEDAL	/* Alias */
-#define CTL_HOLD		CTL_DAMPER_PEDAL	/* 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	CTL_DETUNE_DEPTH /* 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 */
-
-#define SEQ_BALANCE		11
-#define SEQ_VOLMODE             12
-
-/*
- * Volume mode decides 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 Gravis UltraSound use struct patch_info. Initialize the key field
- * to GUS_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 u_char sbi_instr_data[32];
-
-struct sbi_instrument {
-	u_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;	/* Reg. 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_AWE32		0x20
-
-	int	perc_mode;	/* No longer supported */
-	int	nr_voices;
-	int	nr_drums;	/* Obsolete field */
-	int	instr_bank_size;
-	u_long	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 {
-	char		name[30];
-	int		device;		/* 0-N. INITIALIZE BEFORE CALLING */
-	u_long	capabilities;	/* To be defined later */
-	int		dev_type;
-	int		dummies[18];	/* Reserve space */
-};
-
-/*
- * ioctl commands for the /dev/midi##
- */
-typedef struct {
-	u_char cmd;
-	char nr_args, nr_returns;
-	u_char data[30];
-} mpu_command_rec;
-
-#define SNDCTL_MIDI_PRETIME	_IOWR('m', 0, int)
-#define SNDCTL_MIDI_MPUMODE	_IOWR('m', 1, int)
-#define SNDCTL_MIDI_MPUCMD	_IOWR('m', 2, mpu_command_rec)
-#define MIOSPASSTHRU		_IOWR('m', 3, int)
-#define MIOGPASSTHRU		_IOWR('m', 4, int)
-
-/*
- * IOCTL commands for /dev/dsp and /dev/audio
- */
-
-#define SNDCTL_DSP_RESET	_IO  ('P', 0)
-#define SNDCTL_DSP_SYNC		_IO  ('P', 1)
-#define SNDCTL_DSP_SPEED	_IOWR('P', 2, int)
-#define SNDCTL_DSP_STEREO	_IOWR('P', 3, int)
-#define SNDCTL_DSP_GETBLKSIZE	_IOR('P', 4, int)
-#define SNDCTL_DSP_SETBLKSIZE   _IOW('P', 4, int)
-#define SNDCTL_DSP_SETFMT	_IOWR('P',5, int) /* Selects ONE fmt*/
-
-/*
- * SOUND_PCM_WRITE_CHANNELS is not that different
- * from SNDCTL_DSP_STEREO
- */
-#define SOUND_PCM_WRITE_CHANNELS	_IOWR('P', 6, int)
-#define SNDCTL_DSP_CHANNELS	SOUND_PCM_WRITE_CHANNELS
-#define SOUND_PCM_WRITE_FILTER	_IOWR('P', 7, int)
-#define SNDCTL_DSP_POST		_IO  ('P', 8)
-
-/*
- * SNDCTL_DSP_SETBLKSIZE and the following two calls mostly do
- * the same thing, i.e. set the block size used in DMA transfers.
- */
-#define SNDCTL_DSP_SUBDIVIDE	_IOWR('P', 9, int)
-#define SNDCTL_DSP_SETFRAGMENT	_IOWR('P',10, int)
-
-
-#define SNDCTL_DSP_GETFMTS	_IOR ('P',11, int) /* Returns a mask */
-/*
- * Buffer status queries.
- */
-typedef struct audio_buf_info {
-    int fragments;	/* # of avail. frags (partly used ones not counted) */
-    int fragstotal;	/* Total # of fragments allocated */
-    int fragsize;	/* Size of a fragment in bytes */
-
-    int bytes;	/* Avail. space in bytes (includes partly used fragments) */
-		/* Note! 'bytes' could be more than fragments*fragsize */
-} audio_buf_info;
-
-#define SNDCTL_DSP_GETOSPACE	_IOR ('P',12, audio_buf_info)
-#define SNDCTL_DSP_GETISPACE	_IOR ('P',13, audio_buf_info)
-
-/*
- * SNDCTL_DSP_NONBLOCK is the same (but less powerful, since the
- * action cannot be undone) of FIONBIO. The same can be achieved
- * by opening the device with O_NDELAY
- */
-#define SNDCTL_DSP_NONBLOCK	_IO  ('P',14)
-
-#define SNDCTL_DSP_GETCAPS	_IOR ('P',15, int)
-#define DSP_CAP_REVISION	0x000000ff /* revision level (0 to 255) */
-#define DSP_CAP_DUPLEX		0x00000100 /* Full duplex record/playback */
-#define DSP_CAP_REALTIME	0x00000200 /* Real time capability */
-#define DSP_CAP_BATCH		0x00000400
-    /*
-     * Device has some kind of internal buffers which may
-     * cause some delays and decrease precision of timing
-     */
-#define DSP_CAP_COPROC		0x00000800
-    /* Has a coprocessor, sometimes it's a DSP but usually not */
-#define DSP_CAP_TRIGGER		0x00001000 /* Supports SETTRIGGER */
-#define DSP_CAP_MMAP 0x00002000 /* Supports mmap() */
-
-/*
- * What do these function do ?
- */
-#define SNDCTL_DSP_GETTRIGGER	_IOR ('P',16, int)
-#define SNDCTL_DSP_SETTRIGGER	_IOW ('P',16, int)
-#define PCM_ENABLE_INPUT	0x00000001
-#define PCM_ENABLE_OUTPUT	0x00000002
-
-typedef struct count_info {
-	int bytes;	/* Total # of bytes processed */
-	int blocks;	/* # of fragment transitions since last time */
-	int ptr;	/* Current DMA pointer value */
-} count_info;
-
-/*
- * GETIPTR and GETISPACE are not that different... same for out.
- */
-#define SNDCTL_DSP_GETIPTR	_IOR ('P',17, count_info)
-#define SNDCTL_DSP_GETOPTR	_IOR ('P',18, count_info)
-
-typedef struct buffmem_desc {
-	caddr_t buffer;
-	int size;
-} buffmem_desc;
-
-#define SNDCTL_DSP_MAPINBUF	_IOR ('P', 19, buffmem_desc)
-#define SNDCTL_DSP_MAPOUTBUF	_IOR ('P', 20, buffmem_desc)
-#define SNDCTL_DSP_SETSYNCRO	_IO  ('P', 21)
-#define SNDCTL_DSP_SETDUPLEX	_IO  ('P', 22)
-#define SNDCTL_DSP_GETODELAY	_IOR ('P', 23, int)
-
-/*
- * I guess these are the readonly version of the same
- * functions that exist above as SNDCTL_DSP_...
- */
-#define SOUND_PCM_READ_RATE	_IOR ('P', 2, int)
-#define SOUND_PCM_READ_CHANNELS	_IOR ('P', 6, int)
-#define SOUND_PCM_READ_BITS	_IOR ('P', 5, int)
-#define SOUND_PCM_READ_FILTER	_IOR ('P', 7, int)
-
-/*
- * ioctl calls to be used in communication with coprocessors and
- * DSP chips.
- */
-
-typedef struct copr_buffer {
-	int command;	/* Set to 0 if not used */
-	int flags;
-#define CPF_NONE		0x0000
-#define CPF_FIRST		0x0001	/* First block */
-#define CPF_LAST		0x0002	/* Last block */
-	int len;
-	int offs;	/* If required by the device (0 if not used) */
-
-	u_char data[4000]; /* NOTE! 4000 is not 4k */
-} copr_buffer;
-
-typedef struct copr_debug_buf {
-	int command;	/* Used internally. Set to 0 */
-	int parm1;
-	int parm2;
-	int flags;
-	int len;	/* Length of data in bytes */
-} copr_debug_buf;
-
-typedef struct copr_msg {
-	int len;
-	u_char data[4000];
-} copr_msg;
-
-#define SNDCTL_COPR_RESET       _IO  ('C',  0)
-#define SNDCTL_COPR_LOAD	_IOWR('C',  1, copr_buffer)
-#define SNDCTL_COPR_RDATA	_IOWR('C',  2, copr_debug_buf)
-#define SNDCTL_COPR_RCODE	_IOWR('C',  3, copr_debug_buf)
-#define SNDCTL_COPR_WDATA	_IOW ('C',  4, copr_debug_buf)
-#define SNDCTL_COPR_WCODE	_IOW ('C',  5, copr_debug_buf)
-#define SNDCTL_COPR_RUN		_IOWR('C',  6, copr_debug_buf)
-#define SNDCTL_COPR_HALT	_IOWR('C',  7, copr_debug_buf)
-#define SNDCTL_COPR_SENDMSG	_IOW ('C',  8, copr_msg)
-#define SNDCTL_COPR_RCVMSG	_IOR ('C',  9, copr_msg)
-
-/*
- * IOCTL commands for /dev/mixer
- */
-
-/*
- * Mixer devices
- *
- * 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.
- */
-
-#define SOUND_MIXER_NRDEVICES	25
-#define SOUND_MIXER_VOLUME	0	/* Master output level */
-#define SOUND_MIXER_BASS	1	/* Treble level of all output channels */
-#define SOUND_MIXER_TREBLE	2	/* Bass level of all output channels */
-#define SOUND_MIXER_SYNTH	3	/* Volume of synthesier input */
-#define SOUND_MIXER_PCM		4	/* Output level for the audio device */
-#define SOUND_MIXER_SPEAKER	5	/* Output level for the PC speaker
-					 * signals */
-#define SOUND_MIXER_LINE	6	/* Volume level for the line in jack */
-#define SOUND_MIXER_MIC		7	/* Volume for the signal coming from
-					 * the microphone jack */
-#define SOUND_MIXER_CD		8	/* Volume level for the input signal
-					 * connected to the CD audio input */
-#define SOUND_MIXER_IMIX	9	/* Recording monitor. It controls the
-					 * output volume of the selected
-					 * recording sources while recording */
-#define SOUND_MIXER_ALTPCM	10	/* Volume of the alternative codec
-					 * device */
-#define SOUND_MIXER_RECLEV	11	/* Global recording level */
-#define SOUND_MIXER_IGAIN	12	/* Input gain */
-#define SOUND_MIXER_OGAIN	13	/* Output gain */
-/*
- * The AD1848 codec and compatibles have three line level inputs
- * (line, aux1 and aux2). Since each card manufacturer have assigned
- * different meanings to these inputs, it's inpractical to assign
- * specific meanings (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 (input) 1 */
-#define SOUND_MIXER_DIGITAL2    18      /* Digital (input) 2 */
-#define SOUND_MIXER_DIGITAL3    19      /* Digital (input) 3 */
-#define SOUND_MIXER_PHONEIN     20      /* Phone input */
-#define SOUND_MIXER_PHONEOUT    21      /* Phone output */
-#define SOUND_MIXER_VIDEO       22      /* Video/TV (audio) in */
-#define SOUND_MIXER_RADIO       23      /* Radio in */
-#define SOUND_MIXER_MONITOR     24      /* Monitor (usually mic) volume */
-
-
-/*
- * 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
-#define SOUND_MIXER_MUTE	28	/* 0 or 1 */
-#define SOUND_MIXER_ENHANCE	29	/* Enhanced stereo (0, 40, 60 or 80) */
-#define SOUND_MIXER_LOUD	30	/* 0 or 1 */
-
-/* Note!	Number 31 cannot be used since the sign bit is reserved */
-#define SOUND_MIXER_NONE        31
-
-#define SOUND_DEVICE_LABELS	{ \
-	"Vol  ", "Bass ", "Trebl", "Synth", "Pcm  ", "Spkr ", "Line ", \
-	"Mic  ", "CD   ", "Mix  ", "Pcm2 ", "Rec  ", "IGain", "OGain", \
-	"Line1", "Line2", "Line3", "Digital1", "Digital2", "Digital3", \
-	"PhoneIn", "PhoneOut", "Video", "Radio", "Monitor"}
-
-#define SOUND_DEVICE_NAMES	{ \
-	"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \
-	"mic", "cd", "mix", "pcm2", "rec", "igain", "ogain", \
-	"line1", "line2", "line3", "dig1", "dig2", "dig3", \
-	"phin", "phout", "video", "radio", "monitor"}
-
-/*	Device bitmask identifiers	*/
-
-#define SOUND_MIXER_RECSRC	0xff	/* 1 bit per recording source */
-#define SOUND_MIXER_DEVMASK	0xfe	/* 1 bit per supported device */
-#define SOUND_MIXER_RECMASK	0xfd	/* 1 bit per supp. recording source */
-#define SOUND_MIXER_CAPS	0xfc
-#define SOUND_CAP_EXCL_INPUT	0x00000001	/* Only 1 rec. src at a time */
-#define SOUND_MIXER_STEREODEVS	0xfb	/* Mixer channels supporting stereo */
-
-/*	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_PHONEIN      (1 << SOUND_MIXER_PHONEIN)
-#define SOUND_MASK_PHONEOUT     (1 << SOUND_MIXER_PHONEOUT)
-#define SOUND_MASK_RADIO        (1 << SOUND_MIXER_RADIO)
-#define SOUND_MASK_VIDEO        (1 << SOUND_MIXER_VIDEO)
-#define SOUND_MASK_MONITOR      (1 << SOUND_MIXER_MONITOR)
-
-/* 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)		_IOR('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)
-#define SOUND_MIXER_READ_DIGITAL1	MIXER_READ(SOUND_MIXER_DIGITAL1)
-#define SOUND_MIXER_READ_DIGITAL2	MIXER_READ(SOUND_MIXER_DIGITAL2)
-#define SOUND_MIXER_READ_DIGITAL3	MIXER_READ(SOUND_MIXER_DIGITAL3)
-#define SOUND_MIXER_READ_PHONEIN      	MIXER_READ(SOUND_MIXER_PHONEIN)
-#define SOUND_MIXER_READ_PHONEOUT	MIXER_READ(SOUND_MIXER_PHONEOUT)
-#define SOUND_MIXER_READ_RADIO		MIXER_READ(SOUND_MIXER_RADIO)
-#define SOUND_MIXER_READ_VIDEO		MIXER_READ(SOUND_MIXER_VIDEO)
-#define SOUND_MIXER_READ_MONITOR	MIXER_READ(SOUND_MIXER_MONITOR)
-
-/* 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)		_IOWR('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)
-#define SOUND_MIXER_WRITE_DIGITAL1	MIXER_WRITE(SOUND_MIXER_DIGITAL1)
-#define SOUND_MIXER_WRITE_DIGITAL2	MIXER_WRITE(SOUND_MIXER_DIGITAL2)
-#define SOUND_MIXER_WRITE_DIGITAL3	MIXER_WRITE(SOUND_MIXER_DIGITAL3)
-#define SOUND_MIXER_WRITE_PHONEIN      	MIXER_WRITE(SOUND_MIXER_PHONEIN)
-#define SOUND_MIXER_WRITE_PHONEOUT	MIXER_WRITE(SOUND_MIXER_PHONEOUT)
-#define SOUND_MIXER_WRITE_RADIO		MIXER_WRITE(SOUND_MIXER_RADIO)
-#define SOUND_MIXER_WRITE_VIDEO		MIXER_WRITE(SOUND_MIXER_VIDEO)
-#define SOUND_MIXER_WRITE_MONITOR	MIXER_WRITE(SOUND_MIXER_MONITOR)
-
-#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 {
-  char id[16];
-  char name[32];
-  int  modify_counter;
-  int fillers[10];
-} mixer_info;
-
-#define SOUND_MIXER_INFO		_IOR('M', 101, mixer_info)
-
-#define LEFT_CHN	0
-#define RIGHT_CHN	1
-
-/*
- * 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
-/*
- * 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
-
-#if (!defined(_KERNEL) && !defined(INKERNEL)) || 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.
- */
-
-#ifndef USE_SIMPLE_MACROS
-void seqbuf_dump(void);	/* This function must be provided by programs */
-
-/* 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)		\
-	u_char _seqbuf[len]; int _seqbuflen = len;int _seqbufptr = 0
-#define SEQ_USE_EXTBUF()		\
-	extern u_char _seqbuf[]; \
-	extern int _seqbuflen;extern int _seqbufptr
-#define SEQ_DECLAREBUF()		SEQ_USE_EXTBUF()
-#define SEQ_PM_DEFINES			struct patmgr_info _pm_info
-#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 (u_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
-
-#define PM_LOAD_PATCH(dev, bank, pgm)	\
-	(SEQ_DUMPBUF(), _pm_info.command = _PM_LOAD_PATCH, \
-	_pm_info.device=dev, _pm_info.data.data8[0]=pgm, \
-	_pm_info.parm1 = bank, _pm_info.parm2 = 1, \
-	ioctl(seqfd, SNDCTL_PMGR_ACCESS, &_pm_info))
-#define PM_LOAD_PATCHES(dev, bank, pgm) \
-	(SEQ_DUMPBUF(), _pm_info.command = _PM_LOAD_PATCH, \
-	_pm_info.device=dev, bcopy( pgm, _pm_info.data.data8,  128), \
-	_pm_info.parm1 = bank, _pm_info.parm2 = 128, \
-	ioctl(seqfd, SNDCTL_PMGR_ACCESS, &_pm_info))
-
-#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 i, l=(len); if (l>6)l=6;\
-	_SEQ_NEEDBUF(8);\
-	_seqbuf[_seqbufptr] = EV_SYSEX;\
-	for(i=0;i<l;i++)_seqbuf[_seqbufptr+i+1] = (buf)[i];\
-	for(i=l;i<6;i++)_seqbuf[_seqbufptr+i+1] = 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(dev, chn, patch) \
-	_CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0)
-
-#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);\
-	*(short *)&_seqbuf[_seqbufptr+5] = (value);\
-	_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;\
-	*(u_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;\
-	*(u_int *)&_seqbuf[_seqbufptr+4] = (parm); \
-	_SEQ_ADVBUF(8); \
-	}
-
-#define SEQ_PLAYAUDIO(devmask)		_LOCAL_EVENT(LOCL_STARTAUDIO, 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.
- */
-#define SEQ_WRPATCH(patchx, len)	{ \
-	if (_seqbufptr) seqbuf_dump(); \
-	if (write(seqfd, (char*)(patchx), len)==-1) \
-	   perror("Write patch: /dev/sequencer"); \
-	}
-
-#define SEQ_WRPATCH2(patchx, len)	\
-	( seqbuf_dump(), write(seqfd, (char*)(patchx), len) )
-
-#endif
-
-/*
- * Here I have moved all the aliases for ioctl names.
- */
-
-#define SNDCTL_DSP_SAMPLESIZE	SNDCTL_DSP_SETFMT
-#define SOUND_PCM_WRITE_BITS	SNDCTL_DSP_SETFMT
-#define SOUND_PCM_SETFMT	SNDCTL_DSP_SETFMT
-
-#define SOUND_PCM_WRITE_RATE	SNDCTL_DSP_SPEED
-#define SOUND_PCM_POST		SNDCTL_DSP_POST
-#define SOUND_PCM_RESET		SNDCTL_DSP_RESET
-#define SOUND_PCM_SYNC		SNDCTL_DSP_SYNC
-#define SOUND_PCM_SUBDIVIDE	SNDCTL_DSP_SUBDIVIDE
-#define SOUND_PCM_SETFRAGMENT	SNDCTL_DSP_SETFRAGMENT
-#define SOUND_PCM_GETFMTS	SNDCTL_DSP_GETFMTS
-#define SOUND_PCM_GETOSPACE	SNDCTL_DSP_GETOSPACE
-#define SOUND_PCM_GETISPACE	SNDCTL_DSP_GETISPACE
-#define SOUND_PCM_NONBLOCK	SNDCTL_DSP_NONBLOCK
-#define SOUND_PCM_GETCAPS	SNDCTL_DSP_GETCAPS
-#define SOUND_PCM_GETTRIGGER	SNDCTL_DSP_GETTRIGGER
-#define SOUND_PCM_SETTRIGGER	SNDCTL_DSP_SETTRIGGER
-#define SOUND_PCM_SETSYNCRO	SNDCTL_DSP_SETSYNCRO
-#define SOUND_PCM_GETIPTR	SNDCTL_DSP_GETIPTR
-#define SOUND_PCM_GETOPTR	SNDCTL_DSP_GETOPTR
-#define SOUND_PCM_MAPINBUF	SNDCTL_DSP_MAPINBUF
-#define SOUND_PCM_MAPOUTBUF	SNDCTL_DSP_MAPOUTBUF
-
-/***********************************************************************/
-
-/**
- * XXX OSSv4 defines -- some bits taken straight out of the new
- * sys/soundcard.h bundled with recent OSS releases.
- *
- * NB:  These macros and structures will be reorganized and inserted
- * 	in appropriate places throughout this file once the code begins
- * 	to take shape.
- *
- * @todo reorganize layout more like the 4Front version
- * @todo ask about maintaining __SIOWR vs. _IOWR ioctl cmd defines
- */
-
-/**
- * @note The @c OSSV4_EXPERIMENT macro is meant to wrap new development code
- * in the sound system relevant to adopting 4Front's OSSv4 specification.
- * Users should not enable this!  Really!
- */
-#if 0
-# define OSSV4_EXPERIMENT 1
-#else
-# undef OSSV4_EXPERIMENT
-#endif
-
-#ifdef SOUND_VERSION
-# undef SOUND_VERSION
-# define SOUND_VERSION	0x040000
-#endif	/* !SOUND_VERSION */
-
-#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];
-
-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;
-	long		play_errorparm;
-	long		rec_errorparm;
-	int		filler[16];
-} audio_errinfo;
-
-#define SNDCTL_DSP_GETPLAYVOL           _IOR ('P', 24, int)
-#define SNDCTL_DSP_SETPLAYVOL           _IOWR('P', 24, int)
-#define SNDCTL_DSP_GETERROR             _IOR ('P', 25, audio_errinfo)
-
-
-/*
- ****************************************************************************
- * Sync groups for audio devices
- */
-typedef struct oss_syncgroup
-{
-  int id;
-  int mode;
-  int filler[16];
-} oss_syncgroup;
-
-#define SNDCTL_DSP_SYNCGROUP            _IOWR('P', 28, oss_syncgroup)
-#define SNDCTL_DSP_SYNCSTART            _IOW ('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           _IOW ('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              _IO  ('P', 31)
-#define SNDCTL_DSP_SKIP                 _IO  ('P', 32)
-
-/*
- ****************************************************************************
- * Abort transfer (reset) functions for input and output
- */
-#define SNDCTL_DSP_HALT_INPUT		_IO  ('P', 33)
-#define SNDCTL_DSP_RESET_INPUT	SNDCTL_DSP_HALT_INPUT	/* Old name */
-#define SNDCTL_DSP_HALT_OUTPUT		_IO  ('P', 34)
-#define SNDCTL_DSP_RESET_OUTPUT	SNDCTL_DSP_HALT_OUTPUT	/* Old name */
-
-/*
- ****************************************************************************
- * Low water level control
- */
-#define SNDCTL_DSP_LOW_WATER		_IOW ('P', 34, int)
-
-/** @todo Get rid of OSS_NO_LONG_LONG references? */
-
-/*
- ****************************************************************************
- * 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		_IOR ('P', 35, oss_count_t)
-#define SNDCTL_DSP_CURRENT_OPTR		_IOR ('P', 36, oss_count_t)
-#endif
-
-/*
- ****************************************************************************
- * Interface for selecting recording sources and playback output routings.
- */
-#define SNDCTL_DSP_GET_RECSRC_NAMES     _IOR ('P', 37, oss_mixer_enuminfo)
-#define SNDCTL_DSP_GET_RECSRC           _IOR ('P', 38, int)
-#define SNDCTL_DSP_SET_RECSRC           _IOWR('P', 38, int)
-
-#define SNDCTL_DSP_GET_PLAYTGT_NAMES    _IOR ('P', 39, oss_mixer_enuminfo)
-#define SNDCTL_DSP_GET_PLAYTGT          _IOR ('P', 40, int)
-#define SNDCTL_DSP_SET_PLAYTGT          _IOWR('P', 40, int)
-#define SNDCTL_DSP_GETRECVOL            _IOR ('P', 41, int)
-#define SNDCTL_DSP_SETRECVOL            _IOWR('P', 41, int)
-
-/*
- ***************************************************************************
- * Some calls for setting the channel assignment with multi channel devices
- * (see the manual for details).                                                 */
-#define SNDCTL_DSP_GET_CHNORDER         _IOR ('P', 42, unsigned long long)
-#define SNDCTL_DSP_SET_CHNORDER         _IOWR('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
-
-#define MAX_PEAK_CHANNELS	128
-typedef unsigned short oss_peaks_t[MAX_PEAK_CHANNELS];
-#define SNDCTL_DSP_GETIPEAKS		_IOR('P', 43, oss_peaks_t)
-#define SNDCTL_DSP_GETOPEAKS		_IOR('P', 44, oss_peaks_t)
-#define SNDCTL_DSP_POLICY               _IOW('P', 45, int)    /* See the manual */
-
-/*
- * OSS_SYSIFO is obsolete. Use SNDCTL_SYSINFO insteads.
- */
-#define OSS_GETVERSION                  _IOR ('M', 118, int)
-
-/**
- * @brief	Argument for SNDCTL_SYSINFO ioctl.
- *
- * For use w/ the SNDCTL_SYSINFO ioctl available on audio (/dev/dsp*),
- * mixer, and MIDI devices.
- */
-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	filler[241];	/* 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 100) */
-#	define MIXT_STEREOSLIDER 5	/* Stereo slider (dual 0 to 100) */
-#	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	/* Mono atten. slider (0 to -144) */
-#	define MIXT_STEREODB	16	/* Stereo atten. slider (dual 0 to -144) */
-#	define MIXT_SLIDER	17	/* Slider (mono) with full integer range */
-#	define MIXT_3D		18
-
-  /* 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 */
-  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)
-
-/**
- * @brief	Argument for SNDCTL_AUDIOINFO ioctl.
- *
- * For use w/ the SNDCTL_AUDIOINFO ioctl available on audio (/dev/dsp*)
- * devices.
- */
-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;		/* DSP_CAP_INPUT, DSP_CAP_OUTPUT */
-	int	iformats;
-	int	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	real_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;	/* Sample rate limits */
-	int	max_rate;
-	int	min_channels;	/* Number of channels supported */
-	int	max_channels;
-	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;
-	unsigned int 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 (inside
-					   /dev) */
-	int filler[186];
-} 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
-  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;
-  int filler[254];		/* 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 */
-  int filler[244];
-} 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          _IOR ('X', 1, oss_sysinfo)
-#define OSS_SYSINFO             SNDCTL_SYSINFO /* Old name */
-
-#define SNDCTL_MIX_NRMIX	_IOR ('X', 2, int)
-#define SNDCTL_MIX_NREXT	_IOWR('X', 3, int)
-#define SNDCTL_MIX_EXTINFO	_IOWR('X', 4, oss_mixext)
-#define SNDCTL_MIX_READ		_IOWR('X', 5, oss_mixer_value)
-#define SNDCTL_MIX_WRITE	_IOWR('X', 6, oss_mixer_value)
-
-#define SNDCTL_AUDIOINFO	_IOWR('X', 7, oss_audioinfo)
-#define SNDCTL_MIX_ENUMINFO	_IOWR('X', 8, oss_mixer_enuminfo)
-#define SNDCTL_MIDIINFO		_IOWR('X', 9, oss_midi_info)
-#define SNDCTL_MIXERINFO	_IOWR('X',10, oss_mixerinfo)
-#define SNDCTL_CARDINFO		_IOWR('X',11, oss_card_info)
-
-/*
- * Few more "globally" available ioctl calls.
- */
-#define SNDCTL_SETSONG          _IOW ('Y', 2, oss_longname_t)
-#define SNDCTL_GETSONG          _IOR ('Y', 2, oss_longname_t)
-#define SNDCTL_SETNAME          _IOW ('Y', 3, oss_longname_t)
-#define SNDCTL_SETLABEL         _IOW ('Y', 4, oss_label_t)
-#define SNDCTL_GETLABEL         _IOR ('Y', 4, oss_label_t)
-
-#endif	/* !_SYS_SOUNDCARD_H_ */

+ 0 - 10637
source/AudioDecode/AudioDecoder/lib/RtAudio/src/RtAudio.cpp

@@ -1,10637 +0,0 @@
-/************************************************************************/
-/*! \class RtAudio
-    \brief Realtime audio i/o C++ classes.
-
-    RtAudio provides a common API (Application Programming Interface)
-    for realtime audio input/output across Linux (native ALSA, Jack,
-    and OSS), Macintosh OS X (CoreAudio and Jack), and Windows
-    (DirectSound, ASIO and WASAPI) operating systems.
-
-    RtAudio GitHub site: https://github.com/thestk/rtaudio
-    RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
-
-    RtAudio: realtime audio i/o C++ classes
-    Copyright (c) 2001-2019 Gary P. Scavone
-
-    Permission is hereby granted, free of charge, to any person
-    obtaining a copy of this software and associated documentation files
-    (the "Software"), to deal in the Software without restriction,
-    including without limitation the rights to use, copy, modify, merge,
-    publish, distribute, sublicense, and/or sell copies of the Software,
-    and to permit persons to whom the Software is furnished to do so,
-    subject to the following conditions:
-
-    The above copyright notice and this permission notice shall be
-    included in all copies or substantial portions of the Software.
-
-    Any person wishing to distribute modifications to the Software is
-    asked to send the modifications to the original developer so that
-    they can be incorporated into the canonical version.  This is,
-    however, not a binding provision of this license.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
-    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-/************************************************************************/
-
-// RtAudio: Version 5.1.0
-
-#include "RtAudio.h"
-#include <iostream>
-#include <cstdlib>
-#include <cstring>
-#include <climits>
-#include <cmath>
-#include <algorithm>
-
-// Static variable definitions.
-const unsigned int RtApi::MAX_SAMPLE_RATES = 14;
-const unsigned int RtApi::SAMPLE_RATES[] = {
-  4000, 5512, 8000, 9600, 11025, 16000, 22050,
-  32000, 44100, 48000, 88200, 96000, 176400, 192000
-};
-
-#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__)
-  #define MUTEX_INITIALIZE(A) InitializeCriticalSection(A)
-  #define MUTEX_DESTROY(A)    DeleteCriticalSection(A)
-  #define MUTEX_LOCK(A)       EnterCriticalSection(A)
-  #define MUTEX_UNLOCK(A)     LeaveCriticalSection(A)
-
-  #include "tchar.h"
-
-  static std::string convertCharPointerToStdString(const char *text)
-  {
-    return std::string(text);
-  }
-
-  static std::string convertCharPointerToStdString(const wchar_t *text)
-  {
-    int length = WideCharToMultiByte(CP_UTF8, 0, text, -1, NULL, 0, NULL, NULL);
-    std::string s( length-1, '\0' );
-    WideCharToMultiByte(CP_UTF8, 0, text, -1, &s[0], length, NULL, NULL);
-    return s;
-  }
-
-#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
-  // pthread API
-  #define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL)
-  #define MUTEX_DESTROY(A)    pthread_mutex_destroy(A)
-  #define MUTEX_LOCK(A)       pthread_mutex_lock(A)
-  #define MUTEX_UNLOCK(A)     pthread_mutex_unlock(A)
-#else
-  #define MUTEX_INITIALIZE(A) abs(*A) // dummy definitions
-  #define MUTEX_DESTROY(A)    abs(*A) // dummy definitions
-#endif
-
-// *************************************************** //
-//
-// RtAudio definitions.
-//
-// *************************************************** //
-
-std::string RtAudio :: getVersion( void )
-{
-  return RTAUDIO_VERSION;
-}
-
-// Define API names and display names.
-// Must be in same order as API enum.
-extern "C" {
-const char* rtaudio_api_names[][2] = {
-  { "unspecified" , "Unknown" },
-  { "alsa"        , "ALSA" },
-  { "pulse"       , "Pulse" },
-  { "oss"         , "OpenSoundSystem" },
-  { "jack"        , "Jack" },
-  { "core"        , "CoreAudio" },
-  { "wasapi"      , "WASAPI" },
-  { "asio"        , "ASIO" },
-  { "ds"          , "DirectSound" },
-  { "dummy"       , "Dummy" },
-};
-const unsigned int rtaudio_num_api_names = 
-  sizeof(rtaudio_api_names)/sizeof(rtaudio_api_names[0]);
-
-// The order here will control the order of RtAudio's API search in
-// the constructor.
-extern "C" const RtAudio::Api rtaudio_compiled_apis[] = {
-#if defined(__UNIX_JACK__)
-  RtAudio::UNIX_JACK,
-#endif
-#if defined(__LINUX_PULSE__)
-  RtAudio::LINUX_PULSE,
-#endif
-#if defined(__LINUX_ALSA__)
-  RtAudio::LINUX_ALSA,
-#endif
-#if defined(__LINUX_OSS__)
-  RtAudio::LINUX_OSS,
-#endif
-#if defined(__WINDOWS_ASIO__)
-  RtAudio::WINDOWS_ASIO,
-#endif
-#if defined(__WINDOWS_WASAPI__)
-  RtAudio::WINDOWS_WASAPI,
-#endif
-#if defined(__WINDOWS_DS__)
-  RtAudio::WINDOWS_DS,
-#endif
-#if defined(__MACOSX_CORE__)
-  RtAudio::MACOSX_CORE,
-#endif
-#if defined(__RTAUDIO_DUMMY__)
-  RtAudio::RTAUDIO_DUMMY,
-#endif
-  RtAudio::UNSPECIFIED,
-};
-extern "C" const unsigned int rtaudio_num_compiled_apis =
-  sizeof(rtaudio_compiled_apis)/sizeof(rtaudio_compiled_apis[0])-1;
-}
-
-// This is a compile-time check that rtaudio_num_api_names == RtAudio::NUM_APIS.
-// If the build breaks here, check that they match.
-template<bool b> class StaticAssert { private: StaticAssert() {} };
-template<> class StaticAssert<true>{ public: StaticAssert() {} };
-class StaticAssertions { StaticAssertions() {
-  StaticAssert<rtaudio_num_api_names == RtAudio::NUM_APIS>();
-}};
-
-void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis )
-{
-  apis = std::vector<RtAudio::Api>(rtaudio_compiled_apis,
-                                   rtaudio_compiled_apis + rtaudio_num_compiled_apis);
-}
-
-std::string RtAudio :: getApiName( RtAudio::Api api )
-{
-  if (api < 0 || api >= RtAudio::NUM_APIS)
-    return "";
-  return rtaudio_api_names[api][0];
-}
-
-std::string RtAudio :: getApiDisplayName( RtAudio::Api api )
-{
-  if (api < 0 || api >= RtAudio::NUM_APIS)
-    return "Unknown";
-  return rtaudio_api_names[api][1];
-}
-
-RtAudio::Api RtAudio :: getCompiledApiByName( const std::string &name )
-{
-  unsigned int i=0;
-  for (i = 0; i < rtaudio_num_compiled_apis; ++i)
-    if (name == rtaudio_api_names[rtaudio_compiled_apis[i]][0])
-      return rtaudio_compiled_apis[i];
-  return RtAudio::UNSPECIFIED;
-}
-
-void RtAudio :: openRtApi( RtAudio::Api api )
-{
-  if ( rtapi_ )
-    delete rtapi_;
-  rtapi_ = 0;
-
-#if defined(__UNIX_JACK__)
-  if ( api == UNIX_JACK )
-    rtapi_ = new RtApiJack();
-#endif
-#if defined(__LINUX_ALSA__)
-  if ( api == LINUX_ALSA )
-    rtapi_ = new RtApiAlsa();
-#endif
-#if defined(__LINUX_PULSE__)
-  if ( api == LINUX_PULSE )
-    rtapi_ = new RtApiPulse();
-#endif
-#if defined(__LINUX_OSS__)
-  if ( api == LINUX_OSS )
-    rtapi_ = new RtApiOss();
-#endif
-#if defined(__WINDOWS_ASIO__)
-  if ( api == WINDOWS_ASIO )
-    rtapi_ = new RtApiAsio();
-#endif
-#if defined(__WINDOWS_WASAPI__)
-  if ( api == WINDOWS_WASAPI )
-    rtapi_ = new RtApiWasapi();
-#endif
-#if defined(__WINDOWS_DS__)
-  if ( api == WINDOWS_DS )
-    rtapi_ = new RtApiDs();
-#endif
-#if defined(__MACOSX_CORE__)
-  if ( api == MACOSX_CORE )
-    rtapi_ = new RtApiCore();
-#endif
-#if defined(__RTAUDIO_DUMMY__)
-  if ( api == RTAUDIO_DUMMY )
-    rtapi_ = new RtApiDummy();
-#endif
-}
-
-RtAudio :: RtAudio( RtAudio::Api api )
-{
-  rtapi_ = 0;
-
-  if ( api != UNSPECIFIED ) {
-    // Attempt to open the specified API.
-    openRtApi( api );
-    if ( rtapi_ ) return;
-
-    // No compiled support for specified API value.  Issue a debug
-    // warning and continue as if no API was specified.
-    std::cerr << "\nRtAudio: no compiled support for specified API argument!\n" << std::endl;
-  }
-
-  // Iterate through the compiled APIs and return as soon as we find
-  // one with at least one device or we reach the end of the list.
-  std::vector< RtAudio::Api > apis;
-  getCompiledApi( apis );
-  for ( unsigned int i=0; i<apis.size(); i++ ) {
-    openRtApi( apis[i] );
-    if ( rtapi_ && rtapi_->getDeviceCount() ) break;
-  }
-
-  if ( rtapi_ ) return;
-
-  // It should not be possible to get here because the preprocessor
-  // definition __RTAUDIO_DUMMY__ is automatically defined if no
-  // API-specific definitions are passed to the compiler. But just in
-  // case something weird happens, we'll thow an error.
-  std::string errorText = "\nRtAudio: no compiled API support found ... critical error!!\n\n";
-  throw( RtAudioError( errorText, RtAudioError::UNSPECIFIED ) );
-}
-
-RtAudio :: ~RtAudio()
-{
-  if ( rtapi_ )
-    delete rtapi_;
-}
-
-void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters,
-                            RtAudio::StreamParameters *inputParameters,
-                            RtAudioFormat format, unsigned int sampleRate,
-                            unsigned int *bufferFrames,
-                            RtAudioCallback callback, void *userData,
-                            RtAudio::StreamOptions *options,
-                            RtAudioErrorCallback errorCallback )
-{
-  return rtapi_->openStream( outputParameters, inputParameters, format,
-                             sampleRate, bufferFrames, callback,
-                             userData, options, errorCallback );
-}
-
-// *************************************************** //
-//
-// Public RtApi definitions (see end of file for
-// private or protected utility functions).
-//
-// *************************************************** //
-
-RtApi :: RtApi()
-{
-  stream_.state = STREAM_CLOSED;
-  stream_.mode = UNINITIALIZED;
-  stream_.apiHandle = 0;
-  stream_.userBuffer[0] = 0;
-  stream_.userBuffer[1] = 0;
-  MUTEX_INITIALIZE( &stream_.mutex );
-  showWarnings_ = true;
-  firstErrorOccurred_ = false;
-}
-
-RtApi :: ~RtApi()
-{
-  MUTEX_DESTROY( &stream_.mutex );
-}
-
-void RtApi :: openStream( RtAudio::StreamParameters *oParams,
-                          RtAudio::StreamParameters *iParams,
-                          RtAudioFormat format, unsigned int sampleRate,
-                          unsigned int *bufferFrames,
-                          RtAudioCallback callback, void *userData,
-                          RtAudio::StreamOptions *options,
-                          RtAudioErrorCallback errorCallback )
-{
-  if ( stream_.state != STREAM_CLOSED ) {
-    errorText_ = "RtApi::openStream: a stream is already open!";
-    error( RtAudioError::INVALID_USE );
-    return;
-  }
-
-  // Clear stream information potentially left from a previously open stream.
-  clearStreamInfo();
-
-  if ( oParams && oParams->nChannels < 1 ) {
-    errorText_ = "RtApi::openStream: a non-NULL output StreamParameters structure cannot have an nChannels value less than one.";
-    error( RtAudioError::INVALID_USE );
-    return;
-  }
-
-  if ( iParams && iParams->nChannels < 1 ) {
-    errorText_ = "RtApi::openStream: a non-NULL input StreamParameters structure cannot have an nChannels value less than one.";
-    error( RtAudioError::INVALID_USE );
-    return;
-  }
-
-  if ( oParams == NULL && iParams == NULL ) {
-    errorText_ = "RtApi::openStream: input and output StreamParameters structures are both NULL!";
-    error( RtAudioError::INVALID_USE );
-    return;
-  }
-
-  if ( formatBytes(format) == 0 ) {
-    errorText_ = "RtApi::openStream: 'format' parameter value is undefined.";
-    error( RtAudioError::INVALID_USE );
-    return;
-  }
-
-  unsigned int nDevices = getDeviceCount();
-  unsigned int oChannels = 0;
-  if ( oParams ) {
-    oChannels = oParams->nChannels;
-    if ( oParams->deviceId >= nDevices ) {
-      errorText_ = "RtApi::openStream: output device parameter value is invalid.";
-      error( RtAudioError::INVALID_USE );
-      return;
-    }
-  }
-
-  unsigned int iChannels = 0;
-  if ( iParams ) {
-    iChannels = iParams->nChannels;
-    if ( iParams->deviceId >= nDevices ) {
-      errorText_ = "RtApi::openStream: input device parameter value is invalid.";
-      error( RtAudioError::INVALID_USE );
-      return;
-    }
-  }
-
-  bool result;
-
-  if ( oChannels > 0 ) {
-
-    result = probeDeviceOpen( oParams->deviceId, OUTPUT, oChannels, oParams->firstChannel,
-                              sampleRate, format, bufferFrames, options );
-    if ( result == false ) {
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
-    }
-  }
-
-  if ( iChannels > 0 ) {
-
-    result = probeDeviceOpen( iParams->deviceId, INPUT, iChannels, iParams->firstChannel,
-                              sampleRate, format, bufferFrames, options );
-    if ( result == false ) {
-      if ( oChannels > 0 ) closeStream();
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
-    }
-  }
-
-  stream_.callbackInfo.callback = (void *) callback;
-  stream_.callbackInfo.userData = userData;
-  stream_.callbackInfo.errorCallback = (void *) errorCallback;
-
-  if ( options ) options->numberOfBuffers = stream_.nBuffers;
-  stream_.state = STREAM_STOPPED;
-}
-
-unsigned int RtApi :: getDefaultInputDevice( void )
-{
-  // Should be implemented in subclasses if possible.
-  return 0;
-}
-
-unsigned int RtApi :: getDefaultOutputDevice( void )
-{
-  // Should be implemented in subclasses if possible.
-  return 0;
-}
-
-void RtApi :: closeStream( void )
-{
-  // MUST be implemented in subclasses!
-  return;
-}
-
-bool RtApi :: probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/,
-                               unsigned int /*firstChannel*/, unsigned int /*sampleRate*/,
-                               RtAudioFormat /*format*/, unsigned int * /*bufferSize*/,
-                               RtAudio::StreamOptions * /*options*/ )
-{
-  // MUST be implemented in subclasses!
-  return FAILURE;
-}
-
-void RtApi :: tickStreamTime( void )
-{
-  // Subclasses that do not provide their own implementation of
-  // getStreamTime should call this function once per buffer I/O to
-  // provide basic stream time support.
-
-  stream_.streamTime += ( stream_.bufferSize * 1.0 / stream_.sampleRate );
-
-#if defined( HAVE_GETTIMEOFDAY )
-  gettimeofday( &stream_.lastTickTimestamp, NULL );
-#endif
-}
-
-long RtApi :: getStreamLatency( void )
-{
-  verifyStream();
-
-  long totalLatency = 0;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX )
-    totalLatency = stream_.latency[0];
-  if ( stream_.mode == INPUT || stream_.mode == DUPLEX )
-    totalLatency += stream_.latency[1];
-
-  return totalLatency;
-}
-
-double RtApi :: getStreamTime( void )
-{
-  verifyStream();
-
-#if defined( HAVE_GETTIMEOFDAY )
-  // Return a very accurate estimate of the stream time by
-  // adding in the elapsed time since the last tick.
-  struct timeval then;
-  struct timeval now;
-
-  if ( stream_.state != STREAM_RUNNING || stream_.streamTime == 0.0 )
-    return stream_.streamTime;
-
-  gettimeofday( &now, NULL );
-  then = stream_.lastTickTimestamp;
-  return stream_.streamTime +
-    ((now.tv_sec + 0.000001 * now.tv_usec) -
-     (then.tv_sec + 0.000001 * then.tv_usec));     
-#else
-  return stream_.streamTime;
-#endif
-}
-
-void RtApi :: setStreamTime( double time )
-{
-  verifyStream();
-
-  if ( time >= 0.0 )
-    stream_.streamTime = time;
-#if defined( HAVE_GETTIMEOFDAY )
-  gettimeofday( &stream_.lastTickTimestamp, NULL );
-#endif
-}
-
-unsigned int RtApi :: getStreamSampleRate( void )
-{
- verifyStream();
-
- return stream_.sampleRate;
-}
-
-
-// *************************************************** //
-//
-// OS/API-specific methods.
-//
-// *************************************************** //
-
-#if defined(__MACOSX_CORE__)
-
-// The OS X CoreAudio API is designed to use a separate callback
-// procedure for each of its audio devices.  A single RtAudio duplex
-// stream using two different devices is supported here, though it
-// cannot be guaranteed to always behave correctly because we cannot
-// synchronize these two callbacks.
-//
-// A property listener is installed for over/underrun information.
-// However, no functionality is currently provided to allow property
-// listeners to trigger user handlers because it is unclear what could
-// be done if a critical stream parameter (buffer size, sample rate,
-// device disconnect) notification arrived.  The listeners entail
-// quite a bit of extra code and most likely, a user program wouldn't
-// be prepared for the result anyway.  However, we do provide a flag
-// to the client callback function to inform of an over/underrun.
-
-// A structure to hold various information related to the CoreAudio API
-// implementation.
-struct CoreHandle {
-  AudioDeviceID id[2];    // device ids
-#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
-  AudioDeviceIOProcID procId[2];
-#endif
-  UInt32 iStream[2];      // device stream index (or first if using multiple)
-  UInt32 nStreams[2];     // number of streams to use
-  bool xrun[2];
-  char *deviceBuffer;
-  pthread_cond_t condition;
-  int drainCounter;       // Tracks callback counts when draining
-  bool internalDrain;     // Indicates if stop is initiated from callback or not.
-
-  CoreHandle()
-    :deviceBuffer(0), drainCounter(0), internalDrain(false) { nStreams[0] = 1; nStreams[1] = 1; id[0] = 0; id[1] = 0; xrun[0] = false; xrun[1] = false; }
-};
-
-RtApiCore:: RtApiCore()
-{
-#if defined( AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER )
-  // This is a largely undocumented but absolutely necessary
-  // requirement starting with OS-X 10.6.  If not called, queries and
-  // updates to various audio device properties are not handled
-  // correctly.
-  CFRunLoopRef theRunLoop = NULL;
-  AudioObjectPropertyAddress property = { kAudioHardwarePropertyRunLoop,
-                                          kAudioObjectPropertyScopeGlobal,
-                                          kAudioObjectPropertyElementMaster };
-  OSStatus result = AudioObjectSetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop);
-  if ( result != noErr ) {
-    errorText_ = "RtApiCore::RtApiCore: error setting run loop property!";
-    error( RtAudioError::WARNING );
-  }
-#endif
-}
-
-RtApiCore :: ~RtApiCore()
-{
-  // The subclass destructor gets called before the base class
-  // destructor, so close an existing stream before deallocating
-  // apiDeviceId memory.
-  if ( stream_.state != STREAM_CLOSED ) closeStream();
-}
-
-unsigned int RtApiCore :: getDeviceCount( void )
-{
-  // Find out how many audio devices there are, if any.
-  UInt32 dataSize;
-  AudioObjectPropertyAddress propertyAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
-  OSStatus result = AudioObjectGetPropertyDataSize( kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize );
-  if ( result != noErr ) {
-    errorText_ = "RtApiCore::getDeviceCount: OS-X error getting device info!";
-    error( RtAudioError::WARNING );
-    return 0;
-  }
-
-  return dataSize / sizeof( AudioDeviceID );
-}
-
-unsigned int RtApiCore :: getDefaultInputDevice( void )
-{
-  unsigned int nDevices = getDeviceCount();
-  if ( nDevices <= 1 ) return 0;
-
-  AudioDeviceID id;
-  UInt32 dataSize = sizeof( AudioDeviceID );
-  AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
-  OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, &id );
-  if ( result != noErr ) {
-    errorText_ = "RtApiCore::getDefaultInputDevice: OS-X system error getting device.";
-    error( RtAudioError::WARNING );
-    return 0;
-  }
-
-  dataSize *= nDevices;
-  AudioDeviceID deviceList[ nDevices ];
-  property.mSelector = kAudioHardwarePropertyDevices;
-  result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, (void *) &deviceList );
-  if ( result != noErr ) {
-    errorText_ = "RtApiCore::getDefaultInputDevice: OS-X system error getting device IDs.";
-    error( RtAudioError::WARNING );
-    return 0;
-  }
-
-  for ( unsigned int i=0; i<nDevices; i++ )
-    if ( id == deviceList[i] ) return i;
-
-  errorText_ = "RtApiCore::getDefaultInputDevice: No default device found!";
-  error( RtAudioError::WARNING );
-  return 0;
-}
-
-unsigned int RtApiCore :: getDefaultOutputDevice( void )
-{
-  unsigned int nDevices = getDeviceCount();
-  if ( nDevices <= 1 ) return 0;
-
-  AudioDeviceID id;
-  UInt32 dataSize = sizeof( AudioDeviceID );
-  AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
-  OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, &id );
-  if ( result != noErr ) {
-    errorText_ = "RtApiCore::getDefaultOutputDevice: OS-X system error getting device.";
-    error( RtAudioError::WARNING );
-    return 0;
-  }
-
-  dataSize = sizeof( AudioDeviceID ) * nDevices;
-  AudioDeviceID deviceList[ nDevices ];
-  property.mSelector = kAudioHardwarePropertyDevices;
-  result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, (void *) &deviceList );
-  if ( result != noErr ) {
-    errorText_ = "RtApiCore::getDefaultOutputDevice: OS-X system error getting device IDs.";
-    error( RtAudioError::WARNING );
-    return 0;
-  }
-
-  for ( unsigned int i=0; i<nDevices; i++ )
-    if ( id == deviceList[i] ) return i;
-
-  errorText_ = "RtApiCore::getDefaultOutputDevice: No default device found!";
-  error( RtAudioError::WARNING );
-  return 0;
-}
-
-RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
-{
-  RtAudio::DeviceInfo info;
-  info.probed = false;
-
-  // Get device ID
-  unsigned int nDevices = getDeviceCount();
-  if ( nDevices == 0 ) {
-    errorText_ = "RtApiCore::getDeviceInfo: no devices found!";
-    error( RtAudioError::INVALID_USE );
-    return info;
-  }
-
-  if ( device >= nDevices ) {
-    errorText_ = "RtApiCore::getDeviceInfo: device ID is invalid!";
-    error( RtAudioError::INVALID_USE );
-    return info;
-  }
-
-  AudioDeviceID deviceList[ nDevices ];
-  UInt32 dataSize = sizeof( AudioDeviceID ) * nDevices;
-  AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
-                                          kAudioObjectPropertyScopeGlobal,
-                                          kAudioObjectPropertyElementMaster };
-  OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property,
-                                                0, NULL, &dataSize, (void *) &deviceList );
-  if ( result != noErr ) {
-    errorText_ = "RtApiCore::getDeviceInfo: OS-X system error getting device IDs.";
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  AudioDeviceID id = deviceList[ device ];
-
-  // Get the device name.
-  info.name.erase();
-  CFStringRef cfname;
-  dataSize = sizeof( CFStringRef );
-  property.mSelector = kAudioObjectPropertyManufacturer;
-  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &cfname );
-  if ( result != noErr ) {
-    errorStream_ << "RtApiCore::probeDeviceInfo: system error (" << getErrorCode( result ) << ") getting device manufacturer.";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  //const char *mname = CFStringGetCStringPtr( cfname, CFStringGetSystemEncoding() );
-  int length = CFStringGetLength(cfname);
-  char *mname = (char *)malloc(length * 3 + 1);
-#if defined( UNICODE ) || defined( _UNICODE )
-  CFStringGetCString(cfname, mname, length * 3 + 1, kCFStringEncodingUTF8);
-#else
-  CFStringGetCString(cfname, mname, length * 3 + 1, CFStringGetSystemEncoding());
-#endif
-  info.name.append( (const char *)mname, strlen(mname) );
-  info.name.append( ": " );
-  CFRelease( cfname );
-  free(mname);
-
-  property.mSelector = kAudioObjectPropertyName;
-  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &cfname );
-  if ( result != noErr ) {
-    errorStream_ << "RtApiCore::probeDeviceInfo: system error (" << getErrorCode( result ) << ") getting device name.";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  //const char *name = CFStringGetCStringPtr( cfname, CFStringGetSystemEncoding() );
-  length = CFStringGetLength(cfname);
-  char *name = (char *)malloc(length * 3 + 1);
-#if defined( UNICODE ) || defined( _UNICODE )
-  CFStringGetCString(cfname, name, length * 3 + 1, kCFStringEncodingUTF8);
-#else
-  CFStringGetCString(cfname, name, length * 3 + 1, CFStringGetSystemEncoding());
-#endif
-  info.name.append( (const char *)name, strlen(name) );
-  CFRelease( cfname );
-  free(name);
-
-  // Get the output stream "configuration".
-  AudioBufferList	*bufferList = nil;
-  property.mSelector = kAudioDevicePropertyStreamConfiguration;
-  property.mScope = kAudioDevicePropertyScopeOutput;
-  //  property.mElement = kAudioObjectPropertyElementWildcard;
-  dataSize = 0;
-  result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
-  if ( result != noErr || dataSize == 0 ) {
-    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting output stream configuration info for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Allocate the AudioBufferList.
-  bufferList = (AudioBufferList *) malloc( dataSize );
-  if ( bufferList == NULL ) {
-    errorText_ = "RtApiCore::getDeviceInfo: memory error allocating output AudioBufferList.";
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );
-  if ( result != noErr || dataSize == 0 ) {
-    free( bufferList );
-    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting output stream configuration for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Get output channel information.
-  unsigned int i, nStreams = bufferList->mNumberBuffers;
-  for ( i=0; i<nStreams; i++ )
-    info.outputChannels += bufferList->mBuffers[i].mNumberChannels;
-  free( bufferList );
-
-  // Get the input stream "configuration".
-  property.mScope = kAudioDevicePropertyScopeInput;
-  result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
-  if ( result != noErr || dataSize == 0 ) {
-    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting input stream configuration info for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Allocate the AudioBufferList.
-  bufferList = (AudioBufferList *) malloc( dataSize );
-  if ( bufferList == NULL ) {
-    errorText_ = "RtApiCore::getDeviceInfo: memory error allocating input AudioBufferList.";
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );
-  if (result != noErr || dataSize == 0) {
-    free( bufferList );
-    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting input stream configuration for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Get input channel information.
-  nStreams = bufferList->mNumberBuffers;
-  for ( i=0; i<nStreams; i++ )
-    info.inputChannels += bufferList->mBuffers[i].mNumberChannels;
-  free( bufferList );
-
-  // If device opens for both playback and capture, we determine the channels.
-  if ( info.outputChannels > 0 && info.inputChannels > 0 )
-    info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-
-  // Probe the device sample rates.
-  bool isInput = false;
-  if ( info.outputChannels == 0 ) isInput = true;
-
-  // Determine the supported sample rates.
-  property.mSelector = kAudioDevicePropertyAvailableNominalSampleRates;
-  if ( isInput == false ) property.mScope = kAudioDevicePropertyScopeOutput;
-  result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
-  if ( result != kAudioHardwareNoError || dataSize == 0 ) {
-    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting sample rate info.";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  UInt32 nRanges = dataSize / sizeof( AudioValueRange );
-  AudioValueRange rangeList[ nRanges ];
-  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &rangeList );
-  if ( result != kAudioHardwareNoError ) {
-    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting sample rates.";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // The sample rate reporting mechanism is a bit of a mystery.  It
-  // seems that it can either return individual rates or a range of
-  // rates.  I assume that if the min / max range values are the same,
-  // then that represents a single supported rate and if the min / max
-  // range values are different, the device supports an arbitrary
-  // range of values (though there might be multiple ranges, so we'll
-  // use the most conservative range).
-  Float64 minimumRate = 1.0, maximumRate = 10000000000.0;
-  bool haveValueRange = false;
-  info.sampleRates.clear();
-  for ( UInt32 i=0; i<nRanges; i++ ) {
-    if ( rangeList[i].mMinimum == rangeList[i].mMaximum ) {
-      unsigned int tmpSr = (unsigned int) rangeList[i].mMinimum;
-      info.sampleRates.push_back( tmpSr );
-
-      if ( !info.preferredSampleRate || ( tmpSr <= 48000 && tmpSr > info.preferredSampleRate ) )
-        info.preferredSampleRate = tmpSr;
-
-    } else {
-      haveValueRange = true;
-      if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum;
-      if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum;
-    }
-  }
-
-  if ( haveValueRange ) {
-    for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
-      if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate ) {
-        info.sampleRates.push_back( SAMPLE_RATES[k] );
-
-        if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
-          info.preferredSampleRate = SAMPLE_RATES[k];
-      }
-    }
-  }
-
-  // Sort and remove any redundant values
-  std::sort( info.sampleRates.begin(), info.sampleRates.end() );
-  info.sampleRates.erase( unique( info.sampleRates.begin(), info.sampleRates.end() ), info.sampleRates.end() );
-
-  if ( info.sampleRates.size() == 0 ) {
-    errorStream_ << "RtApiCore::probeDeviceInfo: No supported sample rates found for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // CoreAudio always uses 32-bit floating point data for PCM streams.
-  // Thus, any other "physical" formats supported by the device are of
-  // no interest to the client.
-  info.nativeFormats = RTAUDIO_FLOAT32;
-
-  if ( info.outputChannels > 0 )
-    if ( getDefaultOutputDevice() == device ) info.isDefaultOutput = true;
-  if ( info.inputChannels > 0 )
-    if ( getDefaultInputDevice() == device ) info.isDefaultInput = true;
-
-  info.probed = true;
-  return info;
-}
-
-static OSStatus callbackHandler( AudioDeviceID inDevice,
-                                 const AudioTimeStamp* /*inNow*/,
-                                 const AudioBufferList* inInputData,
-                                 const AudioTimeStamp* /*inInputTime*/,
-                                 AudioBufferList* outOutputData,
-                                 const AudioTimeStamp* /*inOutputTime*/,
-                                 void* infoPointer )
-{
-  CallbackInfo *info = (CallbackInfo *) infoPointer;
-
-  RtApiCore *object = (RtApiCore *) info->object;
-  if ( object->callbackEvent( inDevice, inInputData, outOutputData ) == false )
-    return kAudioHardwareUnspecifiedError;
-  else
-    return kAudioHardwareNoError;
-}
-
-static OSStatus xrunListener( AudioObjectID /*inDevice*/,
-                              UInt32 nAddresses,
-                              const AudioObjectPropertyAddress properties[],
-                              void* handlePointer )
-{
-  CoreHandle *handle = (CoreHandle *) handlePointer;
-  for ( UInt32 i=0; i<nAddresses; i++ ) {
-    if ( properties[i].mSelector == kAudioDeviceProcessorOverload ) {
-      if ( properties[i].mScope == kAudioDevicePropertyScopeInput )
-        handle->xrun[1] = true;
-      else
-        handle->xrun[0] = true;
-    }
-  }
-
-  return kAudioHardwareNoError;
-}
-
-static OSStatus rateListener( AudioObjectID inDevice,
-                              UInt32 /*nAddresses*/,
-                              const AudioObjectPropertyAddress /*properties*/[],
-                              void* ratePointer )
-{
-  Float64 *rate = (Float64 *) ratePointer;
-  UInt32 dataSize = sizeof( Float64 );
-  AudioObjectPropertyAddress property = { kAudioDevicePropertyNominalSampleRate,
-                                          kAudioObjectPropertyScopeGlobal,
-                                          kAudioObjectPropertyElementMaster };
-  AudioObjectGetPropertyData( inDevice, &property, 0, NULL, &dataSize, rate );
-  return kAudioHardwareNoError;
-}
-
-bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
-                                   unsigned int firstChannel, unsigned int sampleRate,
-                                   RtAudioFormat format, unsigned int *bufferSize,
-                                   RtAudio::StreamOptions *options )
-{
-  // Get device ID
-  unsigned int nDevices = getDeviceCount();
-  if ( nDevices == 0 ) {
-    // This should not happen because a check is made before this function is called.
-    errorText_ = "RtApiCore::probeDeviceOpen: no devices found!";
-    return FAILURE;
-  }
-
-  if ( device >= nDevices ) {
-    // This should not happen because a check is made before this function is called.
-    errorText_ = "RtApiCore::probeDeviceOpen: device ID is invalid!";
-    return FAILURE;
-  }
-
-  AudioDeviceID deviceList[ nDevices ];
-  UInt32 dataSize = sizeof( AudioDeviceID ) * nDevices;
-  AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
-                                          kAudioObjectPropertyScopeGlobal,
-                                          kAudioObjectPropertyElementMaster };
-  OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property,
-                                                0, NULL, &dataSize, (void *) &deviceList );
-  if ( result != noErr ) {
-    errorText_ = "RtApiCore::probeDeviceOpen: OS-X system error getting device IDs.";
-    return FAILURE;
-  }
-
-  AudioDeviceID id = deviceList[ device ];
-
-  // Setup for stream mode.
-  bool isInput = false;
-  if ( mode == INPUT ) {
-    isInput = true;
-    property.mScope = kAudioDevicePropertyScopeInput;
-  }
-  else
-    property.mScope = kAudioDevicePropertyScopeOutput;
-
-  // Get the stream "configuration".
-  AudioBufferList	*bufferList = nil;
-  dataSize = 0;
-  property.mSelector = kAudioDevicePropertyStreamConfiguration;
-  result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
-  if ( result != noErr || dataSize == 0 ) {
-    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream configuration info for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Allocate the AudioBufferList.
-  bufferList = (AudioBufferList *) malloc( dataSize );
-  if ( bufferList == NULL ) {
-    errorText_ = "RtApiCore::probeDeviceOpen: memory error allocating AudioBufferList.";
-    return FAILURE;
-  }
-
-  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );
-  if (result != noErr || dataSize == 0) {
-    free( bufferList );
-    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream configuration for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Search for one or more streams that contain the desired number of
-  // channels. CoreAudio devices can have an arbitrary number of
-  // streams and each stream can have an arbitrary number of channels.
-  // For each stream, a single buffer of interleaved samples is
-  // provided.  RtAudio prefers the use of one stream of interleaved
-  // data or multiple consecutive single-channel streams.  However, we
-  // now support multiple consecutive multi-channel streams of
-  // interleaved data as well.
-  UInt32 iStream, offsetCounter = firstChannel;
-  UInt32 nStreams = bufferList->mNumberBuffers;
-  bool monoMode = false;
-  bool foundStream = false;
-
-  // First check that the device supports the requested number of
-  // channels.
-  UInt32 deviceChannels = 0;
-  for ( iStream=0; iStream<nStreams; iStream++ )
-    deviceChannels += bufferList->mBuffers[iStream].mNumberChannels;
-
-  if ( deviceChannels < ( channels + firstChannel ) ) {
-    free( bufferList );
-    errorStream_ << "RtApiCore::probeDeviceOpen: the device (" << device << ") does not support the requested channel count.";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Look for a single stream meeting our needs.
-  UInt32 firstStream, streamCount = 1, streamChannels = 0, channelOffset = 0;
-  for ( iStream=0; iStream<nStreams; iStream++ ) {
-    streamChannels = bufferList->mBuffers[iStream].mNumberChannels;
-    if ( streamChannels >= channels + offsetCounter ) {
-      firstStream = iStream;
-      channelOffset = offsetCounter;
-      foundStream = true;
-      break;
-    }
-    if ( streamChannels > offsetCounter ) break;
-    offsetCounter -= streamChannels;
-  }
-
-  // If we didn't find a single stream above, then we should be able
-  // to meet the channel specification with multiple streams.
-  if ( foundStream == false ) {
-    monoMode = true;
-    offsetCounter = firstChannel;
-    for ( iStream=0; iStream<nStreams; iStream++ ) {
-      streamChannels = bufferList->mBuffers[iStream].mNumberChannels;
-      if ( streamChannels > offsetCounter ) break;
-      offsetCounter -= streamChannels;
-    }
-
-    firstStream = iStream;
-    channelOffset = offsetCounter;
-    Int32 channelCounter = channels + offsetCounter - streamChannels;
-
-    if ( streamChannels > 1 ) monoMode = false;
-    while ( channelCounter > 0 ) {
-      streamChannels = bufferList->mBuffers[++iStream].mNumberChannels;
-      if ( streamChannels > 1 ) monoMode = false;
-      channelCounter -= streamChannels;
-      streamCount++;
-    }
-  }
-
-  free( bufferList );
-
-  // Determine the buffer size.
-  AudioValueRange	bufferRange;
-  dataSize = sizeof( AudioValueRange );
-  property.mSelector = kAudioDevicePropertyBufferFrameSizeRange;
-  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &bufferRange );
-
-  if ( result != noErr ) {
-    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting buffer size range for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  if ( bufferRange.mMinimum > *bufferSize ) *bufferSize = (unsigned long) bufferRange.mMinimum;
-  else if ( bufferRange.mMaximum < *bufferSize ) *bufferSize = (unsigned long) bufferRange.mMaximum;
-  if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) *bufferSize = (unsigned long) bufferRange.mMinimum;
-
-  // Set the buffer size.  For multiple streams, I'm assuming we only
-  // need to make this setting for the master channel.
-  UInt32 theSize = (UInt32) *bufferSize;
-  dataSize = sizeof( UInt32 );
-  property.mSelector = kAudioDevicePropertyBufferFrameSize;
-  result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &theSize );
-
-  if ( result != noErr ) {
-    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting the buffer size for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // If attempting to setup a duplex stream, the bufferSize parameter
-  // MUST be the same in both directions!
-  *bufferSize = theSize;
-  if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) {
-    errorStream_ << "RtApiCore::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << device << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  stream_.bufferSize = *bufferSize;
-  stream_.nBuffers = 1;
-
-  // Try to set "hog" mode ... it's not clear to me this is working.
-  if ( options && options->flags & RTAUDIO_HOG_DEVICE ) {
-    pid_t hog_pid;
-    dataSize = sizeof( hog_pid );
-    property.mSelector = kAudioDevicePropertyHogMode;
-    result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &hog_pid );
-    if ( result != noErr ) {
-      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting 'hog' state!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    if ( hog_pid != getpid() ) {
-      hog_pid = getpid();
-      result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &hog_pid );
-      if ( result != noErr ) {
-        errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting 'hog' state!";
-        errorText_ = errorStream_.str();
-        return FAILURE;
-      }
-    }
-  }
-
-  // Check and if necessary, change the sample rate for the device.
-  Float64 nominalRate;
-  dataSize = sizeof( Float64 );
-  property.mSelector = kAudioDevicePropertyNominalSampleRate;
-  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &nominalRate );
-  if ( result != noErr ) {
-    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting current sample rate.";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Only change the sample rate if off by more than 1 Hz.
-  if ( fabs( nominalRate - (double)sampleRate ) > 1.0 ) {
-
-    // Set a property listener for the sample rate change
-    Float64 reportedRate = 0.0;
-    AudioObjectPropertyAddress tmp = { kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
-    result = AudioObjectAddPropertyListener( id, &tmp, rateListener, (void *) &reportedRate );
-    if ( result != noErr ) {
-      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate property listener for device (" << device << ").";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    nominalRate = (Float64) sampleRate;
-    result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &nominalRate );
-    if ( result != noErr ) {
-      AudioObjectRemovePropertyListener( id, &tmp, rateListener, (void *) &reportedRate );
-      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate for device (" << device << ").";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    // Now wait until the reported nominal rate is what we just set.
-    UInt32 microCounter = 0;
-    while ( reportedRate != nominalRate ) {
-      microCounter += 5000;
-      if ( microCounter > 5000000 ) break;
-      usleep( 5000 );
-    }
-
-    // Remove the property listener.
-    AudioObjectRemovePropertyListener( id, &tmp, rateListener, (void *) &reportedRate );
-
-    if ( microCounter > 5000000 ) {
-      errorStream_ << "RtApiCore::probeDeviceOpen: timeout waiting for sample rate update for device (" << device << ").";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-  }
-
-  // Now set the stream format for all streams.  Also, check the
-  // physical format of the device and change that if necessary.
-  AudioStreamBasicDescription	description;
-  dataSize = sizeof( AudioStreamBasicDescription );
-  property.mSelector = kAudioStreamPropertyVirtualFormat;
-  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &description );
-  if ( result != noErr ) {
-    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream format for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Set the sample rate and data format id.  However, only make the
-  // change if the sample rate is not within 1.0 of the desired
-  // rate and the format is not linear pcm.
-  bool updateFormat = false;
-  if ( fabs( description.mSampleRate - (Float64)sampleRate ) > 1.0 ) {
-    description.mSampleRate = (Float64) sampleRate;
-    updateFormat = true;
-  }
-
-  if ( description.mFormatID != kAudioFormatLinearPCM ) {
-    description.mFormatID = kAudioFormatLinearPCM;
-    updateFormat = true;
-  }
-
-  if ( updateFormat ) {
-    result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &description );
-    if ( result != noErr ) {
-      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate or data format for device (" << device << ").";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-  }
-
-  // Now check the physical format.
-  property.mSelector = kAudioStreamPropertyPhysicalFormat;
-  result = AudioObjectGetPropertyData( id, &property, 0, NULL,  &dataSize, &description );
-  if ( result != noErr ) {
-    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream physical format for device (" << device << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  //std::cout << "Current physical stream format:" << std::endl;
-  //std::cout << "   mBitsPerChan = " << description.mBitsPerChannel << std::endl;
-  //std::cout << "   aligned high = " << (description.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (description.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl;
-  //std::cout << "   bytesPerFrame = " << description.mBytesPerFrame << std::endl;
-  //std::cout << "   sample rate = " << description.mSampleRate << std::endl;
-
-  if ( description.mFormatID != kAudioFormatLinearPCM || description.mBitsPerChannel < 16 ) {
-    description.mFormatID = kAudioFormatLinearPCM;
-    //description.mSampleRate = (Float64) sampleRate;
-    AudioStreamBasicDescription	testDescription = description;
-    UInt32 formatFlags;
-
-    // We'll try higher bit rates first and then work our way down.
-    std::vector< std::pair<UInt32, UInt32>  > physicalFormats;
-    formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsFloat) & ~kLinearPCMFormatFlagIsSignedInteger;
-    physicalFormats.push_back( std::pair<Float32, UInt32>( 32, formatFlags ) );
-    formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat;
-    physicalFormats.push_back( std::pair<Float32, UInt32>( 32, formatFlags ) );
-    physicalFormats.push_back( std::pair<Float32, UInt32>( 24, formatFlags ) );   // 24-bit packed
-    formatFlags &= ~( kAudioFormatFlagIsPacked | kAudioFormatFlagIsAlignedHigh );
-    physicalFormats.push_back( std::pair<Float32, UInt32>( 24.2, formatFlags ) ); // 24-bit in 4 bytes, aligned low
-    formatFlags |= kAudioFormatFlagIsAlignedHigh;
-    physicalFormats.push_back( std::pair<Float32, UInt32>( 24.4, formatFlags ) ); // 24-bit in 4 bytes, aligned high
-    formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat;
-    physicalFormats.push_back( std::pair<Float32, UInt32>( 16, formatFlags ) );
-    physicalFormats.push_back( std::pair<Float32, UInt32>( 8, formatFlags ) );
-
-    bool setPhysicalFormat = false;
-    for( unsigned int i=0; i<physicalFormats.size(); i++ ) {
-      testDescription = description;
-      testDescription.mBitsPerChannel = (UInt32) physicalFormats[i].first;
-      testDescription.mFormatFlags = physicalFormats[i].second;
-      if ( (24 == (UInt32)physicalFormats[i].first) && ~( physicalFormats[i].second & kAudioFormatFlagIsPacked ) )
-        testDescription.mBytesPerFrame =  4 * testDescription.mChannelsPerFrame;
-      else
-        testDescription.mBytesPerFrame =  testDescription.mBitsPerChannel/8 * testDescription.mChannelsPerFrame;
-      testDescription.mBytesPerPacket = testDescription.mBytesPerFrame * testDescription.mFramesPerPacket;
-      result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &testDescription );
-      if ( result == noErr ) {
-        setPhysicalFormat = true;
-        //std::cout << "Updated physical stream format:" << std::endl;
-        //std::cout << "   mBitsPerChan = " << testDescription.mBitsPerChannel << std::endl;
-        //std::cout << "   aligned high = " << (testDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (testDescription.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl;
-        //std::cout << "   bytesPerFrame = " << testDescription.mBytesPerFrame << std::endl;
-        //std::cout << "   sample rate = " << testDescription.mSampleRate << std::endl;
-        break;
-      }
-    }
-
-    if ( !setPhysicalFormat ) {
-      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting physical data format for device (" << device << ").";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-  } // done setting virtual/physical formats.
-
-  // Get the stream / device latency.
-  UInt32 latency;
-  dataSize = sizeof( UInt32 );
-  property.mSelector = kAudioDevicePropertyLatency;
-  if ( AudioObjectHasProperty( id, &property ) == true ) {
-    result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &latency );
-    if ( result == kAudioHardwareNoError ) stream_.latency[ mode ] = latency;
-    else {
-      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting device latency for device (" << device << ").";
-      errorText_ = errorStream_.str();
-      error( RtAudioError::WARNING );
-    }
-  }
-
-  // Byte-swapping: According to AudioHardware.h, the stream data will
-  // always be presented in native-endian format, so we should never
-  // need to byte swap.
-  stream_.doByteSwap[mode] = false;
-
-  // From the CoreAudio documentation, PCM data must be supplied as
-  // 32-bit floats.
-  stream_.userFormat = format;
-  stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
-
-  if ( streamCount == 1 )
-    stream_.nDeviceChannels[mode] = description.mChannelsPerFrame;
-  else // multiple streams
-    stream_.nDeviceChannels[mode] = channels;
-  stream_.nUserChannels[mode] = channels;
-  stream_.channelOffset[mode] = channelOffset;  // offset within a CoreAudio stream
-  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
-  else stream_.userInterleaved = true;
-  stream_.deviceInterleaved[mode] = true;
-  if ( monoMode == true ) stream_.deviceInterleaved[mode] = false;
-
-  // Set flags for buffer conversion.
-  stream_.doConvertBuffer[mode] = false;
-  if ( stream_.userFormat != stream_.deviceFormat[mode] )
-    stream_.doConvertBuffer[mode] = true;
-  if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
-    stream_.doConvertBuffer[mode] = true;
-  if ( streamCount == 1 ) {
-    if ( stream_.nUserChannels[mode] > 1 &&
-         stream_.userInterleaved != stream_.deviceInterleaved[mode] )
-      stream_.doConvertBuffer[mode] = true;
-  }
-  else if ( monoMode && stream_.userInterleaved )
-    stream_.doConvertBuffer[mode] = true;
-
-  // Allocate our CoreHandle structure for the stream.
-  CoreHandle *handle = 0;
-  if ( stream_.apiHandle == 0 ) {
-    try {
-      handle = new CoreHandle;
-    }
-    catch ( std::bad_alloc& ) {
-      errorText_ = "RtApiCore::probeDeviceOpen: error allocating CoreHandle memory.";
-      goto error;
-    }
-
-    if ( pthread_cond_init( &handle->condition, NULL ) ) {
-      errorText_ = "RtApiCore::probeDeviceOpen: error initializing pthread condition variable.";
-      goto error;
-    }
-    stream_.apiHandle = (void *) handle;
-  }
-  else
-    handle = (CoreHandle *) stream_.apiHandle;
-  handle->iStream[mode] = firstStream;
-  handle->nStreams[mode] = streamCount;
-  handle->id[mode] = id;
-
-  // Allocate necessary internal buffers.
-  unsigned long bufferBytes;
-  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
-  //  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
-  stream_.userBuffer[mode] = (char *) malloc( bufferBytes * sizeof(char) );
-  memset( stream_.userBuffer[mode], 0, bufferBytes * sizeof(char) );
-  if ( stream_.userBuffer[mode] == NULL ) {
-    errorText_ = "RtApiCore::probeDeviceOpen: error allocating user buffer memory.";
-    goto error;
-  }
-
-  // If possible, we will make use of the CoreAudio stream buffers as
-  // "device buffers".  However, we can't do this if using multiple
-  // streams.
-  if ( stream_.doConvertBuffer[mode] && handle->nStreams[mode] > 1 ) {
-
-    bool makeBuffer = true;
-    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
-    if ( mode == INPUT ) {
-      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
-        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
-        if ( bufferBytes <= bytesOut ) makeBuffer = false;
-      }
-    }
-
-    if ( makeBuffer ) {
-      bufferBytes *= *bufferSize;
-      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
-      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
-      if ( stream_.deviceBuffer == NULL ) {
-        errorText_ = "RtApiCore::probeDeviceOpen: error allocating device buffer memory.";
-        goto error;
-      }
-    }
-  }
-
-  stream_.sampleRate = sampleRate;
-  stream_.device[mode] = device;
-  stream_.state = STREAM_STOPPED;
-  stream_.callbackInfo.object = (void *) this;
-
-  // Setup the buffer conversion information structure.
-  if ( stream_.doConvertBuffer[mode] ) {
-    if ( streamCount > 1 ) setConvertInfo( mode, 0 );
-    else setConvertInfo( mode, channelOffset );
-  }
-
-  if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] == device )
-    // Only one callback procedure per device.
-    stream_.mode = DUPLEX;
-  else {
-#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
-    result = AudioDeviceCreateIOProcID( id, callbackHandler, (void *) &stream_.callbackInfo, &handle->procId[mode] );
-#else
-    // deprecated in favor of AudioDeviceCreateIOProcID()
-    result = AudioDeviceAddIOProc( id, callbackHandler, (void *) &stream_.callbackInfo );
-#endif
-    if ( result != noErr ) {
-      errorStream_ << "RtApiCore::probeDeviceOpen: system error setting callback for device (" << device << ").";
-      errorText_ = errorStream_.str();
-      goto error;
-    }
-    if ( stream_.mode == OUTPUT && mode == INPUT )
-      stream_.mode = DUPLEX;
-    else
-      stream_.mode = mode;
-  }
-
-  // Setup the device property listener for over/underload.
-  property.mSelector = kAudioDeviceProcessorOverload;
-  property.mScope = kAudioObjectPropertyScopeGlobal;
-  result = AudioObjectAddPropertyListener( id, &property, xrunListener, (void *) handle );
-
-  return SUCCESS;
-
- error:
-  if ( handle ) {
-    pthread_cond_destroy( &handle->condition );
-    delete handle;
-    stream_.apiHandle = 0;
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  stream_.state = STREAM_CLOSED;
-  return FAILURE;
-}
-
-void RtApiCore :: closeStream( void )
-{
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiCore::closeStream(): no open stream to close!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-    if (handle) {
-      AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
-        kAudioObjectPropertyScopeGlobal,
-        kAudioObjectPropertyElementMaster };
-
-      property.mSelector = kAudioDeviceProcessorOverload;
-      property.mScope = kAudioObjectPropertyScopeGlobal;
-      if (AudioObjectRemovePropertyListener( handle->id[0], &property, xrunListener, (void *) handle ) != noErr) {
-        errorText_ = "RtApiCore::closeStream(): error removing property listener!";
-        error( RtAudioError::WARNING );
-      }
-    }
-    if ( stream_.state == STREAM_RUNNING )
-      AudioDeviceStop( handle->id[0], callbackHandler );
-#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
-    AudioDeviceDestroyIOProcID( handle->id[0], handle->procId[0] );
-#else
-    // deprecated in favor of AudioDeviceDestroyIOProcID()
-    AudioDeviceRemoveIOProc( handle->id[0], callbackHandler );
-#endif
-  }
-
-  if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
-    if (handle) {
-      AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
-        kAudioObjectPropertyScopeGlobal,
-        kAudioObjectPropertyElementMaster };
-
-      property.mSelector = kAudioDeviceProcessorOverload;
-      property.mScope = kAudioObjectPropertyScopeGlobal;
-      if (AudioObjectRemovePropertyListener( handle->id[1], &property, xrunListener, (void *) handle ) != noErr) {
-        errorText_ = "RtApiCore::closeStream(): error removing property listener!";
-        error( RtAudioError::WARNING );
-      }
-    }
-    if ( stream_.state == STREAM_RUNNING )
-      AudioDeviceStop( handle->id[1], callbackHandler );
-#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
-    AudioDeviceDestroyIOProcID( handle->id[1], handle->procId[1] );
-#else
-    // deprecated in favor of AudioDeviceDestroyIOProcID()
-    AudioDeviceRemoveIOProc( handle->id[1], callbackHandler );
-#endif
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  // Destroy pthread condition variable.
-  pthread_cond_destroy( &handle->condition );
-  delete handle;
-  stream_.apiHandle = 0;
-
-  stream_.mode = UNINITIALIZED;
-  stream_.state = STREAM_CLOSED;
-}
-
-void RtApiCore :: startStream( void )
-{
-  verifyStream();
-  if ( stream_.state == STREAM_RUNNING ) {
-    errorText_ = "RtApiCore::startStream(): the stream is already running!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  #if defined( HAVE_GETTIMEOFDAY )
-  gettimeofday( &stream_.lastTickTimestamp, NULL );
-  #endif
-
-  OSStatus result = noErr;
-  CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
-    result = AudioDeviceStart( handle->id[0], callbackHandler );
-    if ( result != noErr ) {
-      errorStream_ << "RtApiCore::startStream: system error (" << getErrorCode( result ) << ") starting callback procedure on device (" << stream_.device[0] << ").";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
-  if ( stream_.mode == INPUT ||
-       ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
-
-    result = AudioDeviceStart( handle->id[1], callbackHandler );
-    if ( result != noErr ) {
-      errorStream_ << "RtApiCore::startStream: system error starting input callback procedure on device (" << stream_.device[1] << ").";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
-  handle->drainCounter = 0;
-  handle->internalDrain = false;
-  stream_.state = STREAM_RUNNING;
-
- unlock:
-  if ( result == noErr ) return;
-  error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiCore :: stopStream( void )
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiCore::stopStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  OSStatus result = noErr;
-  CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
-    if ( handle->drainCounter == 0 ) {
-      handle->drainCounter = 2;
-      pthread_cond_wait( &handle->condition, &stream_.mutex ); // block until signaled
-    }
-
-    result = AudioDeviceStop( handle->id[0], callbackHandler );
-    if ( result != noErr ) {
-      errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode( result ) << ") stopping callback procedure on device (" << stream_.device[0] << ").";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
-  if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
-
-    result = AudioDeviceStop( handle->id[1], callbackHandler );
-    if ( result != noErr ) {
-      errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode( result ) << ") stopping input callback procedure on device (" << stream_.device[1] << ").";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
-  stream_.state = STREAM_STOPPED;
-
- unlock:
-  if ( result == noErr ) return;
-  error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiCore :: abortStream( void )
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiCore::abortStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
-  handle->drainCounter = 2;
-
-  stopStream();
-}
-
-// This function will be called by a spawned thread when the user
-// callback function signals that the stream should be stopped or
-// aborted.  It is better to handle it this way because the
-// callbackEvent() function probably should return before the AudioDeviceStop()
-// function is called.
-static void *coreStopStream( void *ptr )
-{
-  CallbackInfo *info = (CallbackInfo *) ptr;
-  RtApiCore *object = (RtApiCore *) info->object;
-
-  object->stopStream();
-  pthread_exit( NULL );
-}
-
-bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
-                                 const AudioBufferList *inBufferList,
-                                 const AudioBufferList *outBufferList )
-{
-  if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!";
-    error( RtAudioError::WARNING );
-    return FAILURE;
-  }
-
-  CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
-  CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
-
-  // Check if we were draining the stream and signal is finished.
-  if ( handle->drainCounter > 3 ) {
-    ThreadHandle threadId;
-
-    stream_.state = STREAM_STOPPING;
-    if ( handle->internalDrain == true )
-      pthread_create( &threadId, NULL, coreStopStream, info );
-    else // external call to stopStream()
-      pthread_cond_signal( &handle->condition );
-    return SUCCESS;
-  }
-
-  AudioDeviceID outputDevice = handle->id[0];
-
-  // Invoke user callback to get fresh output data UNLESS we are
-  // draining stream or duplex mode AND the input/output devices are
-  // different AND this function is called for the input device.
-  if ( handle->drainCounter == 0 && ( stream_.mode != DUPLEX || deviceId == outputDevice ) ) {
-    RtAudioCallback callback = (RtAudioCallback) info->callback;
-    double streamTime = getStreamTime();
-    RtAudioStreamStatus status = 0;
-    if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
-      status |= RTAUDIO_OUTPUT_UNDERFLOW;
-      handle->xrun[0] = false;
-    }
-    if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
-      status |= RTAUDIO_INPUT_OVERFLOW;
-      handle->xrun[1] = false;
-    }
-
-    int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
-                                  stream_.bufferSize, streamTime, status, info->userData );
-    if ( cbReturnValue == 2 ) {
-      stream_.state = STREAM_STOPPING;
-      handle->drainCounter = 2;
-      abortStream();
-      return SUCCESS;
-    }
-    else if ( cbReturnValue == 1 ) {
-      handle->drainCounter = 1;
-      handle->internalDrain = true;
-    }
-  }
-
-  if ( stream_.mode == OUTPUT || ( stream_.mode == DUPLEX && deviceId == outputDevice ) ) {
-
-    if ( handle->drainCounter > 1 ) { // write zeros to the output stream
-
-      if ( handle->nStreams[0] == 1 ) {
-        memset( outBufferList->mBuffers[handle->iStream[0]].mData,
-                0,
-                outBufferList->mBuffers[handle->iStream[0]].mDataByteSize );
-      }
-      else { // fill multiple streams with zeros
-        for ( unsigned int i=0; i<handle->nStreams[0]; i++ ) {
-          memset( outBufferList->mBuffers[handle->iStream[0]+i].mData,
-                  0,
-                  outBufferList->mBuffers[handle->iStream[0]+i].mDataByteSize );
-        }
-      }
-    }
-    else if ( handle->nStreams[0] == 1 ) {
-      if ( stream_.doConvertBuffer[0] ) { // convert directly to CoreAudio stream buffer
-        convertBuffer( (char *) outBufferList->mBuffers[handle->iStream[0]].mData,
-                       stream_.userBuffer[0], stream_.convertInfo[0] );
-      }
-      else { // copy from user buffer
-        memcpy( outBufferList->mBuffers[handle->iStream[0]].mData,
-                stream_.userBuffer[0],
-                outBufferList->mBuffers[handle->iStream[0]].mDataByteSize );
-      }
-    }
-    else { // fill multiple streams
-      Float32 *inBuffer = (Float32 *) stream_.userBuffer[0];
-      if ( stream_.doConvertBuffer[0] ) {
-        convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] );
-        inBuffer = (Float32 *) stream_.deviceBuffer;
-      }
-
-      if ( stream_.deviceInterleaved[0] == false ) { // mono mode
-        UInt32 bufferBytes = outBufferList->mBuffers[handle->iStream[0]].mDataByteSize;
-        for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) {
-          memcpy( outBufferList->mBuffers[handle->iStream[0]+i].mData,
-                  (void *)&inBuffer[i*stream_.bufferSize], bufferBytes );
-        }
-      }
-      else { // fill multiple multi-channel streams with interleaved data
-        UInt32 streamChannels, channelsLeft, inJump, outJump, inOffset;
-        Float32 *out, *in;
-
-        bool inInterleaved = ( stream_.userInterleaved ) ? true : false;
-        UInt32 inChannels = stream_.nUserChannels[0];
-        if ( stream_.doConvertBuffer[0] ) {
-          inInterleaved = true; // device buffer will always be interleaved for nStreams > 1 and not mono mode
-          inChannels = stream_.nDeviceChannels[0];
-        }
-
-        if ( inInterleaved ) inOffset = 1;
-        else inOffset = stream_.bufferSize;
-
-        channelsLeft = inChannels;
-        for ( unsigned int i=0; i<handle->nStreams[0]; i++ ) {
-          in = inBuffer;
-          out = (Float32 *) outBufferList->mBuffers[handle->iStream[0]+i].mData;
-          streamChannels = outBufferList->mBuffers[handle->iStream[0]+i].mNumberChannels;
-
-          outJump = 0;
-          // Account for possible channel offset in first stream
-          if ( i == 0 && stream_.channelOffset[0] > 0 ) {
-            streamChannels -= stream_.channelOffset[0];
-            outJump = stream_.channelOffset[0];
-            out += outJump;
-          }
-
-          // Account for possible unfilled channels at end of the last stream
-          if ( streamChannels > channelsLeft ) {
-            outJump = streamChannels - channelsLeft;
-            streamChannels = channelsLeft;
-          }
-
-          // Determine input buffer offsets and skips
-          if ( inInterleaved ) {
-            inJump = inChannels;
-            in += inChannels - channelsLeft;
-          }
-          else {
-            inJump = 1;
-            in += (inChannels - channelsLeft) * inOffset;
-          }
-
-          for ( unsigned int i=0; i<stream_.bufferSize; i++ ) {
-            for ( unsigned int j=0; j<streamChannels; j++ ) {
-              *out++ = in[j*inOffset];
-            }
-            out += outJump;
-            in += inJump;
-          }
-          channelsLeft -= streamChannels;
-        }
-      }
-    }
-  }
-
-  // Don't bother draining input
-  if ( handle->drainCounter ) {
-    handle->drainCounter++;
-    goto unlock;
-  }
-
-  AudioDeviceID inputDevice;
-  inputDevice = handle->id[1];
-  if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && deviceId == inputDevice ) ) {
-
-    if ( handle->nStreams[1] == 1 ) {
-      if ( stream_.doConvertBuffer[1] ) { // convert directly from CoreAudio stream buffer
-        convertBuffer( stream_.userBuffer[1],
-                       (char *) inBufferList->mBuffers[handle->iStream[1]].mData,
-                       stream_.convertInfo[1] );
-      }
-      else { // copy to user buffer
-        memcpy( stream_.userBuffer[1],
-                inBufferList->mBuffers[handle->iStream[1]].mData,
-                inBufferList->mBuffers[handle->iStream[1]].mDataByteSize );
-      }
-    }
-    else { // read from multiple streams
-      Float32 *outBuffer = (Float32 *) stream_.userBuffer[1];
-      if ( stream_.doConvertBuffer[1] ) outBuffer = (Float32 *) stream_.deviceBuffer;
-
-      if ( stream_.deviceInterleaved[1] == false ) { // mono mode
-        UInt32 bufferBytes = inBufferList->mBuffers[handle->iStream[1]].mDataByteSize;
-        for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) {
-          memcpy( (void *)&outBuffer[i*stream_.bufferSize],
-                  inBufferList->mBuffers[handle->iStream[1]+i].mData, bufferBytes );
-        }
-      }
-      else { // read from multiple multi-channel streams
-        UInt32 streamChannels, channelsLeft, inJump, outJump, outOffset;
-        Float32 *out, *in;
-
-        bool outInterleaved = ( stream_.userInterleaved ) ? true : false;
-        UInt32 outChannels = stream_.nUserChannels[1];
-        if ( stream_.doConvertBuffer[1] ) {
-          outInterleaved = true; // device buffer will always be interleaved for nStreams > 1 and not mono mode
-          outChannels = stream_.nDeviceChannels[1];
-        }
-
-        if ( outInterleaved ) outOffset = 1;
-        else outOffset = stream_.bufferSize;
-
-        channelsLeft = outChannels;
-        for ( unsigned int i=0; i<handle->nStreams[1]; i++ ) {
-          out = outBuffer;
-          in = (Float32 *) inBufferList->mBuffers[handle->iStream[1]+i].mData;
-          streamChannels = inBufferList->mBuffers[handle->iStream[1]+i].mNumberChannels;
-
-          inJump = 0;
-          // Account for possible channel offset in first stream
-          if ( i == 0 && stream_.channelOffset[1] > 0 ) {
-            streamChannels -= stream_.channelOffset[1];
-            inJump = stream_.channelOffset[1];
-            in += inJump;
-          }
-
-          // Account for possible unread channels at end of the last stream
-          if ( streamChannels > channelsLeft ) {
-            inJump = streamChannels - channelsLeft;
-            streamChannels = channelsLeft;
-          }
-
-          // Determine output buffer offsets and skips
-          if ( outInterleaved ) {
-            outJump = outChannels;
-            out += outChannels - channelsLeft;
-          }
-          else {
-            outJump = 1;
-            out += (outChannels - channelsLeft) * outOffset;
-          }
-
-          for ( unsigned int i=0; i<stream_.bufferSize; i++ ) {
-            for ( unsigned int j=0; j<streamChannels; j++ ) {
-              out[j*outOffset] = *in++;
-            }
-            out += outJump;
-            in += inJump;
-          }
-          channelsLeft -= streamChannels;
-        }
-      }
-      
-      if ( stream_.doConvertBuffer[1] ) { // convert from our internal "device" buffer
-        convertBuffer( stream_.userBuffer[1],
-                       stream_.deviceBuffer,
-                       stream_.convertInfo[1] );
-      }
-    }
-  }
-
- unlock:
-  //MUTEX_UNLOCK( &stream_.mutex );
-
-  // Make sure to only tick duplex stream time once if using two devices
-  if ( stream_.mode != DUPLEX || (stream_.mode == DUPLEX && handle->id[0] != handle->id[1] && deviceId == handle->id[0] ) )
-    RtApi::tickStreamTime();
-  
-  return SUCCESS;
-}
-
-const char* RtApiCore :: getErrorCode( OSStatus code )
-{
-  switch( code ) {
-
-  case kAudioHardwareNotRunningError:
-    return "kAudioHardwareNotRunningError";
-
-  case kAudioHardwareUnspecifiedError:
-    return "kAudioHardwareUnspecifiedError";
-
-  case kAudioHardwareUnknownPropertyError:
-    return "kAudioHardwareUnknownPropertyError";
-
-  case kAudioHardwareBadPropertySizeError:
-    return "kAudioHardwareBadPropertySizeError";
-
-  case kAudioHardwareIllegalOperationError:
-    return "kAudioHardwareIllegalOperationError";
-
-  case kAudioHardwareBadObjectError:
-    return "kAudioHardwareBadObjectError";
-
-  case kAudioHardwareBadDeviceError:
-    return "kAudioHardwareBadDeviceError";
-
-  case kAudioHardwareBadStreamError:
-    return "kAudioHardwareBadStreamError";
-
-  case kAudioHardwareUnsupportedOperationError:
-    return "kAudioHardwareUnsupportedOperationError";
-
-  case kAudioDeviceUnsupportedFormatError:
-    return "kAudioDeviceUnsupportedFormatError";
-
-  case kAudioDevicePermissionsError:
-    return "kAudioDevicePermissionsError";
-
-  default:
-    return "CoreAudio unknown error";
-  }
-}
-
-  //******************** End of __MACOSX_CORE__ *********************//
-#endif
-
-#if defined(__UNIX_JACK__)
-
-// JACK is a low-latency audio server, originally written for the
-// GNU/Linux operating system and now also ported to OS-X. It can
-// connect a number of different applications to an audio device, as
-// well as allowing them to share audio between themselves.
-//
-// When using JACK with RtAudio, "devices" refer to JACK clients that
-// have ports connected to the server.  The JACK server is typically
-// started in a terminal as follows:
-//
-// .jackd -d alsa -d hw:0
-//
-// or through an interface program such as qjackctl.  Many of the
-// parameters normally set for a stream are fixed by the JACK server
-// and can be specified when the JACK server is started.  In
-// particular,
-//
-// .jackd -d alsa -d hw:0 -r 44100 -p 512 -n 4
-//
-// specifies a sample rate of 44100 Hz, a buffer size of 512 sample
-// frames, and number of buffers = 4.  Once the server is running, it
-// is not possible to override these values.  If the values are not
-// specified in the command-line, the JACK server uses default values.
-//
-// The JACK server does not have to be running when an instance of
-// RtApiJack is created, though the function getDeviceCount() will
-// report 0 devices found until JACK has been started.  When no
-// devices are available (i.e., the JACK server is not running), a
-// stream cannot be opened.
-
-#include <jack/jack.h>
-#include <unistd.h>
-#include <cstdio>
-
-// A structure to hold various information related to the Jack API
-// implementation.
-struct JackHandle {
-  jack_client_t *client;
-  jack_port_t **ports[2];
-  std::string deviceName[2];
-  bool xrun[2];
-  pthread_cond_t condition;
-  int drainCounter;       // Tracks callback counts when draining
-  bool internalDrain;     // Indicates if stop is initiated from callback or not.
-
-  JackHandle()
-    :client(0), drainCounter(0), internalDrain(false) { ports[0] = 0; ports[1] = 0; xrun[0] = false; xrun[1] = false; }
-};
-
-#if !defined(__RTAUDIO_DEBUG__)
-static void jackSilentError( const char * ) {};
-#endif
-
-RtApiJack :: RtApiJack()
-    :shouldAutoconnect_(true) {
-  // Nothing to do here.
-#if !defined(__RTAUDIO_DEBUG__)
-  // Turn off Jack's internal error reporting.
-  jack_set_error_function( &jackSilentError );
-#endif
-}
-
-RtApiJack :: ~RtApiJack()
-{
-  if ( stream_.state != STREAM_CLOSED ) closeStream();
-}
-
-unsigned int RtApiJack :: getDeviceCount( void )
-{
-  // See if we can become a jack client.
-  jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption;
-  jack_status_t *status = NULL;
-  jack_client_t *client = jack_client_open( "RtApiJackCount", options, status );
-  if ( client == 0 ) return 0;
-
-  const char **ports;
-  std::string port, previousPort;
-  unsigned int nChannels = 0, nDevices = 0;
-  ports = jack_get_ports( client, NULL, JACK_DEFAULT_AUDIO_TYPE, 0 );
-  if ( ports ) {
-    // Parse the port names up to the first colon (:).
-    size_t iColon = 0;
-    do {
-      port = (char *) ports[ nChannels ];
-      iColon = port.find(":");
-      if ( iColon != std::string::npos ) {
-        port = port.substr( 0, iColon + 1 );
-        if ( port != previousPort ) {
-          nDevices++;
-          previousPort = port;
-        }
-      }
-    } while ( ports[++nChannels] );
-    free( ports );
-  }
-
-  jack_client_close( client );
-  return nDevices;
-}
-
-RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device )
-{
-  RtAudio::DeviceInfo info;
-  info.probed = false;
-
-  jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption
-  jack_status_t *status = NULL;
-  jack_client_t *client = jack_client_open( "RtApiJackInfo", options, status );
-  if ( client == 0 ) {
-    errorText_ = "RtApiJack::getDeviceInfo: Jack server not found or connection error!";
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  const char **ports;
-  std::string port, previousPort;
-  unsigned int nPorts = 0, nDevices = 0;
-  ports = jack_get_ports( client, NULL, JACK_DEFAULT_AUDIO_TYPE, 0 );
-  if ( ports ) {
-    // Parse the port names up to the first colon (:).
-    size_t iColon = 0;
-    do {
-      port = (char *) ports[ nPorts ];
-      iColon = port.find(":");
-      if ( iColon != std::string::npos ) {
-        port = port.substr( 0, iColon );
-        if ( port != previousPort ) {
-          if ( nDevices == device ) info.name = port;
-          nDevices++;
-          previousPort = port;
-        }
-      }
-    } while ( ports[++nPorts] );
-    free( ports );
-  }
-
-  if ( device >= nDevices ) {
-    jack_client_close( client );
-    errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!";
-    error( RtAudioError::INVALID_USE );
-    return info;
-  }
-
-  // Get the current jack server sample rate.
-  info.sampleRates.clear();
-
-  info.preferredSampleRate = jack_get_sample_rate( client );
-  info.sampleRates.push_back( info.preferredSampleRate );
-
-  // Count the available ports containing the client name as device
-  // channels.  Jack "input ports" equal RtAudio output channels.
-  unsigned int nChannels = 0;
-  ports = jack_get_ports( client, info.name.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput );
-  if ( ports ) {
-    while ( ports[ nChannels ] ) nChannels++;
-    free( ports );
-    info.outputChannels = nChannels;
-  }
-
-  // Jack "output ports" equal RtAudio input channels.
-  nChannels = 0;
-  ports = jack_get_ports( client, info.name.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput );
-  if ( ports ) {
-    while ( ports[ nChannels ] ) nChannels++;
-    free( ports );
-    info.inputChannels = nChannels;
-  }
-
-  if ( info.outputChannels == 0 && info.inputChannels == 0 ) {
-    jack_client_close(client);
-    errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!";
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // If device opens for both playback and capture, we determine the channels.
-  if ( info.outputChannels > 0 && info.inputChannels > 0 )
-    info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-
-  // Jack always uses 32-bit floats.
-  info.nativeFormats = RTAUDIO_FLOAT32;
-
-  // Jack doesn't provide default devices so we'll use the first available one.
-  if ( device == 0 && info.outputChannels > 0 )
-    info.isDefaultOutput = true;
-  if ( device == 0 && info.inputChannels > 0 )
-    info.isDefaultInput = true;
-
-  jack_client_close(client);
-  info.probed = true;
-  return info;
-}
-
-static int jackCallbackHandler( jack_nframes_t nframes, void *infoPointer )
-{
-  CallbackInfo *info = (CallbackInfo *) infoPointer;
-
-  RtApiJack *object = (RtApiJack *) info->object;
-  if ( object->callbackEvent( (unsigned long) nframes ) == false ) return 1;
-
-  return 0;
-}
-
-// This function will be called by a spawned thread when the Jack
-// server signals that it is shutting down.  It is necessary to handle
-// it this way because the jackShutdown() function must return before
-// the jack_deactivate() function (in closeStream()) will return.
-static void *jackCloseStream( void *ptr )
-{
-  CallbackInfo *info = (CallbackInfo *) ptr;
-  RtApiJack *object = (RtApiJack *) info->object;
-
-  object->closeStream();
-
-  pthread_exit( NULL );
-}
-static void jackShutdown( void *infoPointer )
-{
-  CallbackInfo *info = (CallbackInfo *) infoPointer;
-  RtApiJack *object = (RtApiJack *) info->object;
-
-  // Check current stream state.  If stopped, then we'll assume this
-  // was called as a result of a call to RtApiJack::stopStream (the
-  // deactivation of a client handle causes this function to be called).
-  // If not, we'll assume the Jack server is shutting down or some
-  // other problem occurred and we should close the stream.
-  if ( object->isStreamRunning() == false ) return;
-
-  ThreadHandle threadId;
-  pthread_create( &threadId, NULL, jackCloseStream, info );
-  std::cerr << "\nRtApiJack: the Jack server is shutting down this client ... stream stopped and closed!!\n" << std::endl;
-}
-
-static int jackXrun( void *infoPointer )
-{
-  JackHandle *handle = *((JackHandle **) infoPointer);
-
-  if ( handle->ports[0] ) handle->xrun[0] = true;
-  if ( handle->ports[1] ) handle->xrun[1] = true;
-
-  return 0;
-}
-
-bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
-                                   unsigned int firstChannel, unsigned int sampleRate,
-                                   RtAudioFormat format, unsigned int *bufferSize,
-                                   RtAudio::StreamOptions *options )
-{
-  JackHandle *handle = (JackHandle *) stream_.apiHandle;
-
-  // Look for jack server and try to become a client (only do once per stream).
-  jack_client_t *client = 0;
-  if ( mode == OUTPUT || ( mode == INPUT && stream_.mode != OUTPUT ) ) {
-    jack_options_t jackoptions = (jack_options_t) ( JackNoStartServer ); //JackNullOption;
-    jack_status_t *status = NULL;
-    if ( options && !options->streamName.empty() )
-      client = jack_client_open( options->streamName.c_str(), jackoptions, status );
-    else
-      client = jack_client_open( "RtApiJack", jackoptions, status );
-    if ( client == 0 ) {
-      errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!";
-      error( RtAudioError::WARNING );
-      return FAILURE;
-    }
-  }
-  else {
-    // The handle must have been created on an earlier pass.
-    client = handle->client;
-  }
-
-  const char **ports;
-  std::string port, previousPort, deviceName;
-  unsigned int nPorts = 0, nDevices = 0;
-  ports = jack_get_ports( client, NULL, JACK_DEFAULT_AUDIO_TYPE, 0 );
-  if ( ports ) {
-    // Parse the port names up to the first colon (:).
-    size_t iColon = 0;
-    do {
-      port = (char *) ports[ nPorts ];
-      iColon = port.find(":");
-      if ( iColon != std::string::npos ) {
-        port = port.substr( 0, iColon );
-        if ( port != previousPort ) {
-          if ( nDevices == device ) deviceName = port;
-          nDevices++;
-          previousPort = port;
-        }
-      }
-    } while ( ports[++nPorts] );
-    free( ports );
-  }
-
-  if ( device >= nDevices ) {
-    errorText_ = "RtApiJack::probeDeviceOpen: device ID is invalid!";
-    return FAILURE;
-  }
-
-  unsigned long flag = JackPortIsInput;
-  if ( mode == INPUT ) flag = JackPortIsOutput;
-
-  if ( ! (options && (options->flags & RTAUDIO_JACK_DONT_CONNECT)) ) {
-    // Count the available ports containing the client name as device
-    // channels.  Jack "input ports" equal RtAudio output channels.
-    unsigned int nChannels = 0;
-    ports = jack_get_ports( client, deviceName.c_str(), JACK_DEFAULT_AUDIO_TYPE, flag );
-    if ( ports ) {
-      while ( ports[ nChannels ] ) nChannels++;
-      free( ports );
-    }
-    // Compare the jack ports for specified client to the requested number of channels.
-    if ( nChannels < (channels + firstChannel) ) {
-      errorStream_ << "RtApiJack::probeDeviceOpen: requested number of channels (" << channels << ") + offset (" << firstChannel << ") not found for specified device (" << device << ":" << deviceName << ").";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-  }
-
-  // Check the jack server sample rate.
-  unsigned int jackRate = jack_get_sample_rate( client );
-  if ( sampleRate != jackRate ) {
-    jack_client_close( client );
-    errorStream_ << "RtApiJack::probeDeviceOpen: the requested sample rate (" << sampleRate << ") is different than the JACK server rate (" << jackRate << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-  stream_.sampleRate = jackRate;
-
-  // Get the latency of the JACK port.
-  ports = jack_get_ports( client, deviceName.c_str(), JACK_DEFAULT_AUDIO_TYPE, flag );
-  if ( ports[ firstChannel ] ) {
-    // Added by Ge Wang
-    jack_latency_callback_mode_t cbmode = (mode == INPUT ? JackCaptureLatency : JackPlaybackLatency);
-    // the range (usually the min and max are equal)
-    jack_latency_range_t latrange; latrange.min = latrange.max = 0;
-    // get the latency range
-    jack_port_get_latency_range( jack_port_by_name( client, ports[firstChannel] ), cbmode, &latrange );
-    // be optimistic, use the min!
-    stream_.latency[mode] = latrange.min;
-    //stream_.latency[mode] = jack_port_get_latency( jack_port_by_name( client, ports[ firstChannel ] ) );
-  }
-  free( ports );
-
-  // The jack server always uses 32-bit floating-point data.
-  stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
-  stream_.userFormat = format;
-
-  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
-  else stream_.userInterleaved = true;
-
-  // Jack always uses non-interleaved buffers.
-  stream_.deviceInterleaved[mode] = false;
-
-  // Jack always provides host byte-ordered data.
-  stream_.doByteSwap[mode] = false;
-
-  // Get the buffer size.  The buffer size and number of buffers
-  // (periods) is set when the jack server is started.
-  stream_.bufferSize = (int) jack_get_buffer_size( client );
-  *bufferSize = stream_.bufferSize;
-
-  stream_.nDeviceChannels[mode] = channels;
-  stream_.nUserChannels[mode] = channels;
-
-  // Set flags for buffer conversion.
-  stream_.doConvertBuffer[mode] = false;
-  if ( stream_.userFormat != stream_.deviceFormat[mode] )
-    stream_.doConvertBuffer[mode] = true;
-  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
-       stream_.nUserChannels[mode] > 1 )
-    stream_.doConvertBuffer[mode] = true;
-
-  // Allocate our JackHandle structure for the stream.
-  if ( handle == 0 ) {
-    try {
-      handle = new JackHandle;
-    }
-    catch ( std::bad_alloc& ) {
-      errorText_ = "RtApiJack::probeDeviceOpen: error allocating JackHandle memory.";
-      goto error;
-    }
-
-    if ( pthread_cond_init(&handle->condition, NULL) ) {
-      errorText_ = "RtApiJack::probeDeviceOpen: error initializing pthread condition variable.";
-      goto error;
-    }
-    stream_.apiHandle = (void *) handle;
-    handle->client = client;
-  }
-  handle->deviceName[mode] = deviceName;
-
-  // Allocate necessary internal buffers.
-  unsigned long bufferBytes;
-  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
-  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
-  if ( stream_.userBuffer[mode] == NULL ) {
-    errorText_ = "RtApiJack::probeDeviceOpen: error allocating user buffer memory.";
-    goto error;
-  }
-
-  if ( stream_.doConvertBuffer[mode] ) {
-
-    bool makeBuffer = true;
-    if ( mode == OUTPUT )
-      bufferBytes = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
-    else { // mode == INPUT
-      bufferBytes = stream_.nDeviceChannels[1] * formatBytes( stream_.deviceFormat[1] );
-      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
-        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]);
-        if ( bufferBytes < bytesOut ) makeBuffer = false;
-      }
-    }
-
-    if ( makeBuffer ) {
-      bufferBytes *= *bufferSize;
-      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
-      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
-      if ( stream_.deviceBuffer == NULL ) {
-        errorText_ = "RtApiJack::probeDeviceOpen: error allocating device buffer memory.";
-        goto error;
-      }
-    }
-  }
-
-  // Allocate memory for the Jack ports (channels) identifiers.
-  handle->ports[mode] = (jack_port_t **) malloc ( sizeof (jack_port_t *) * channels );
-  if ( handle->ports[mode] == NULL )  {
-    errorText_ = "RtApiJack::probeDeviceOpen: error allocating port memory.";
-    goto error;
-  }
-
-  stream_.device[mode] = device;
-  stream_.channelOffset[mode] = firstChannel;
-  stream_.state = STREAM_STOPPED;
-  stream_.callbackInfo.object = (void *) this;
-
-  if ( stream_.mode == OUTPUT && mode == INPUT )
-    // We had already set up the stream for output.
-    stream_.mode = DUPLEX;
-  else {
-    stream_.mode = mode;
-    jack_set_process_callback( handle->client, jackCallbackHandler, (void *) &stream_.callbackInfo );
-    jack_set_xrun_callback( handle->client, jackXrun, (void *) &stream_.apiHandle );
-    jack_on_shutdown( handle->client, jackShutdown, (void *) &stream_.callbackInfo );
-  }
-
-  // Register our ports.
-  char label[64];
-  if ( mode == OUTPUT ) {
-    for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) {
-      snprintf( label, 64, "outport %d", i );
-      handle->ports[0][i] = jack_port_register( handle->client, (const char *)label,
-                                                JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
-    }
-  }
-  else {
-    for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) {
-      snprintf( label, 64, "inport %d", i );
-      handle->ports[1][i] = jack_port_register( handle->client, (const char *)label,
-                                                JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 );
-    }
-  }
-
-  // Setup the buffer conversion information structure.  We don't use
-  // buffers to do channel offsets, so we override that parameter
-  // here.
-  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, 0 );
-
-  if ( options && options->flags & RTAUDIO_JACK_DONT_CONNECT ) shouldAutoconnect_ = false;
-
-  return SUCCESS;
-
- error:
-  if ( handle ) {
-    pthread_cond_destroy( &handle->condition );
-    jack_client_close( handle->client );
-
-    if ( handle->ports[0] ) free( handle->ports[0] );
-    if ( handle->ports[1] ) free( handle->ports[1] );
-
-    delete handle;
-    stream_.apiHandle = 0;
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  return FAILURE;
-}
-
-void RtApiJack :: closeStream( void )
-{
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiJack::closeStream(): no open stream to close!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  JackHandle *handle = (JackHandle *) stream_.apiHandle;
-  if ( handle ) {
-
-    if ( stream_.state == STREAM_RUNNING )
-      jack_deactivate( handle->client );
-
-    jack_client_close( handle->client );
-  }
-
-  if ( handle ) {
-    if ( handle->ports[0] ) free( handle->ports[0] );
-    if ( handle->ports[1] ) free( handle->ports[1] );
-    pthread_cond_destroy( &handle->condition );
-    delete handle;
-    stream_.apiHandle = 0;
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  stream_.mode = UNINITIALIZED;
-  stream_.state = STREAM_CLOSED;
-}
-
-void RtApiJack :: startStream( void )
-{
-  verifyStream();
-  if ( stream_.state == STREAM_RUNNING ) {
-    errorText_ = "RtApiJack::startStream(): the stream is already running!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  #if defined( HAVE_GETTIMEOFDAY )
-  gettimeofday( &stream_.lastTickTimestamp, NULL );
-  #endif
-
-  JackHandle *handle = (JackHandle *) stream_.apiHandle;
-  int result = jack_activate( handle->client );
-  if ( result ) {
-    errorText_ = "RtApiJack::startStream(): unable to activate JACK client!";
-    goto unlock;
-  }
-
-  const char **ports;
-
-  // Get the list of available ports.
-  if ( shouldAutoconnect_ && (stream_.mode == OUTPUT || stream_.mode == DUPLEX) ) {
-    result = 1;
-    ports = jack_get_ports( handle->client, handle->deviceName[0].c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput);
-    if ( ports == NULL) {
-      errorText_ = "RtApiJack::startStream(): error determining available JACK input ports!";
-      goto unlock;
-    }
-
-    // Now make the port connections.  Since RtAudio wasn't designed to
-    // allow the user to select particular channels of a device, we'll
-    // just open the first "nChannels" ports with offset.
-    for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) {
-      result = 1;
-      if ( ports[ stream_.channelOffset[0] + i ] )
-        result = jack_connect( handle->client, jack_port_name( handle->ports[0][i] ), ports[ stream_.channelOffset[0] + i ] );
-      if ( result ) {
-        free( ports );
-        errorText_ = "RtApiJack::startStream(): error connecting output ports!";
-        goto unlock;
-      }
-    }
-    free(ports);
-  }
-
-  if ( shouldAutoconnect_ && (stream_.mode == INPUT || stream_.mode == DUPLEX) ) {
-    result = 1;
-    ports = jack_get_ports( handle->client, handle->deviceName[1].c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput );
-    if ( ports == NULL) {
-      errorText_ = "RtApiJack::startStream(): error determining available JACK output ports!";
-      goto unlock;
-    }
-
-    // Now make the port connections.  See note above.
-    for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) {
-      result = 1;
-      if ( ports[ stream_.channelOffset[1] + i ] )
-        result = jack_connect( handle->client, ports[ stream_.channelOffset[1] + i ], jack_port_name( handle->ports[1][i] ) );
-      if ( result ) {
-        free( ports );
-        errorText_ = "RtApiJack::startStream(): error connecting input ports!";
-        goto unlock;
-      }
-    }
-    free(ports);
-  }
-
-  handle->drainCounter = 0;
-  handle->internalDrain = false;
-  stream_.state = STREAM_RUNNING;
-
- unlock:
-  if ( result == 0 ) return;
-  error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiJack :: stopStream( void )
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiJack::stopStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  JackHandle *handle = (JackHandle *) stream_.apiHandle;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
-    if ( handle->drainCounter == 0 ) {
-      handle->drainCounter = 2;
-      pthread_cond_wait( &handle->condition, &stream_.mutex ); // block until signaled
-    }
-  }
-
-  jack_deactivate( handle->client );
-  stream_.state = STREAM_STOPPED;
-}
-
-void RtApiJack :: abortStream( void )
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiJack::abortStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  JackHandle *handle = (JackHandle *) stream_.apiHandle;
-  handle->drainCounter = 2;
-
-  stopStream();
-}
-
-// This function will be called by a spawned thread when the user
-// callback function signals that the stream should be stopped or
-// aborted.  It is necessary to handle it this way because the
-// callbackEvent() function must return before the jack_deactivate()
-// function will return.
-static void *jackStopStream( void *ptr )
-{
-  CallbackInfo *info = (CallbackInfo *) ptr;
-  RtApiJack *object = (RtApiJack *) info->object;
-
-  object->stopStream();
-  pthread_exit( NULL );
-}
-
-bool RtApiJack :: callbackEvent( unsigned long nframes )
-{
-  if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!";
-    error( RtAudioError::WARNING );
-    return FAILURE;
-  }
-  if ( stream_.bufferSize != nframes ) {
-    errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size has changed ... cannot process!";
-    error( RtAudioError::WARNING );
-    return FAILURE;
-  }
-
-  CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
-  JackHandle *handle = (JackHandle *) stream_.apiHandle;
-
-  // Check if we were draining the stream and signal is finished.
-  if ( handle->drainCounter > 3 ) {
-    ThreadHandle threadId;
-
-    stream_.state = STREAM_STOPPING;
-    if ( handle->internalDrain == true )
-      pthread_create( &threadId, NULL, jackStopStream, info );
-    else
-      pthread_cond_signal( &handle->condition );
-    return SUCCESS;
-  }
-
-  // Invoke user callback first, to get fresh output data.
-  if ( handle->drainCounter == 0 ) {
-    RtAudioCallback callback = (RtAudioCallback) info->callback;
-    double streamTime = getStreamTime();
-    RtAudioStreamStatus status = 0;
-    if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
-      status |= RTAUDIO_OUTPUT_UNDERFLOW;
-      handle->xrun[0] = false;
-    }
-    if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
-      status |= RTAUDIO_INPUT_OVERFLOW;
-      handle->xrun[1] = false;
-    }
-    int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
-                                  stream_.bufferSize, streamTime, status, info->userData );
-    if ( cbReturnValue == 2 ) {
-      stream_.state = STREAM_STOPPING;
-      handle->drainCounter = 2;
-      ThreadHandle id;
-      pthread_create( &id, NULL, jackStopStream, info );
-      return SUCCESS;
-    }
-    else if ( cbReturnValue == 1 ) {
-      handle->drainCounter = 1;
-      handle->internalDrain = true;
-    }
-  }
-
-  jack_default_audio_sample_t *jackbuffer;
-  unsigned long bufferBytes = nframes * sizeof( jack_default_audio_sample_t );
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
-    if ( handle->drainCounter > 1 ) { // write zeros to the output stream
-
-      for ( unsigned int i=0; i<stream_.nDeviceChannels[0]; i++ ) {
-        jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes );
-        memset( jackbuffer, 0, bufferBytes );
-      }
-
-    }
-    else if ( stream_.doConvertBuffer[0] ) {
-
-      convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] );
-
-      for ( unsigned int i=0; i<stream_.nDeviceChannels[0]; i++ ) {
-        jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes );
-        memcpy( jackbuffer, &stream_.deviceBuffer[i*bufferBytes], bufferBytes );
-      }
-    }
-    else { // no buffer conversion
-      for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) {
-        jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes );
-        memcpy( jackbuffer, &stream_.userBuffer[0][i*bufferBytes], bufferBytes );
-      }
-    }
-  }
-
-  // Don't bother draining input
-  if ( handle->drainCounter ) {
-    handle->drainCounter++;
-    goto unlock;
-  }
-
-  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
-    if ( stream_.doConvertBuffer[1] ) {
-      for ( unsigned int i=0; i<stream_.nDeviceChannels[1]; i++ ) {
-        jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[1][i], (jack_nframes_t) nframes );
-        memcpy( &stream_.deviceBuffer[i*bufferBytes], jackbuffer, bufferBytes );
-      }
-      convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
-    }
-    else { // no buffer conversion
-      for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) {
-        jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[1][i], (jack_nframes_t) nframes );
-        memcpy( &stream_.userBuffer[1][i*bufferBytes], jackbuffer, bufferBytes );
-      }
-    }
-  }
-
- unlock:
-  RtApi::tickStreamTime();
-  return SUCCESS;
-}
-  //******************** End of __UNIX_JACK__ *********************//
-#endif
-
-#if defined(__WINDOWS_ASIO__) // ASIO API on Windows
-
-// The ASIO API is designed around a callback scheme, so this
-// implementation is similar to that used for OS-X CoreAudio and Linux
-// Jack.  The primary constraint with ASIO is that it only allows
-// access to a single driver at a time.  Thus, it is not possible to
-// have more than one simultaneous RtAudio stream.
-//
-// This implementation also requires a number of external ASIO files
-// and a few global variables.  The ASIO callback scheme does not
-// allow for the passing of user data, so we must create a global
-// pointer to our callbackInfo structure.
-//
-// On unix systems, we make use of a pthread condition variable.
-// Since there is no equivalent in Windows, I hacked something based
-// on information found in
-// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html.
-
-#include "asiosys.h"
-#include "asio.h"
-#include "iasiothiscallresolver.h"
-#include "asiodrivers.h"
-#include <cmath>
-
-static AsioDrivers drivers;
-static ASIOCallbacks asioCallbacks;
-static ASIODriverInfo driverInfo;
-static CallbackInfo *asioCallbackInfo;
-static bool asioXRun;
-
-struct AsioHandle {
-  int drainCounter;       // Tracks callback counts when draining
-  bool internalDrain;     // Indicates if stop is initiated from callback or not.
-  ASIOBufferInfo *bufferInfos;
-  HANDLE condition;
-
-  AsioHandle()
-    :drainCounter(0), internalDrain(false), bufferInfos(0) {}
-};
-
-// Function declarations (definitions at end of section)
-static const char* getAsioErrorString( ASIOError result );
-static void sampleRateChanged( ASIOSampleRate sRate );
-static long asioMessages( long selector, long value, void* message, double* opt );
-
-RtApiAsio :: RtApiAsio()
-{
-  // ASIO cannot run on a multi-threaded appartment. You can call
-  // CoInitialize beforehand, but it must be for appartment threading
-  // (in which case, CoInitilialize will return S_FALSE here).
-  coInitialized_ = false;
-  HRESULT hr = CoInitialize( NULL ); 
-  if ( FAILED(hr) ) {
-    errorText_ = "RtApiAsio::ASIO requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)";
-    error( RtAudioError::WARNING );
-  }
-  coInitialized_ = true;
-
-  drivers.removeCurrentDriver();
-  driverInfo.asioVersion = 2;
-
-  // See note in DirectSound implementation about GetDesktopWindow().
-  driverInfo.sysRef = GetForegroundWindow();
-}
-
-RtApiAsio :: ~RtApiAsio()
-{
-  if ( stream_.state != STREAM_CLOSED ) closeStream();
-  if ( coInitialized_ ) CoUninitialize();
-}
-
-unsigned int RtApiAsio :: getDeviceCount( void )
-{
-  return (unsigned int) drivers.asioGetNumDev();
-}
-
-RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device )
-{
-  RtAudio::DeviceInfo info;
-  info.probed = false;
-
-  // Get device ID
-  unsigned int nDevices = getDeviceCount();
-  if ( nDevices == 0 ) {
-    errorText_ = "RtApiAsio::getDeviceInfo: no devices found!";
-    error( RtAudioError::INVALID_USE );
-    return info;
-  }
-
-  if ( device >= nDevices ) {
-    errorText_ = "RtApiAsio::getDeviceInfo: device ID is invalid!";
-    error( RtAudioError::INVALID_USE );
-    return info;
-  }
-
-  // If a stream is already open, we cannot probe other devices.  Thus, use the saved results.
-  if ( stream_.state != STREAM_CLOSED ) {
-    if ( device >= devices_.size() ) {
-      errorText_ = "RtApiAsio::getDeviceInfo: device ID was not present before stream was opened.";
-      error( RtAudioError::WARNING );
-      return info;
-    }
-    return devices_[ device ];
-  }
-
-  char driverName[32];
-  ASIOError result = drivers.asioGetDriverName( (int) device, driverName, 32 );
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::getDeviceInfo: unable to get driver name (" << getAsioErrorString( result ) << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  info.name = driverName;
-
-  if ( !drivers.loadDriver( driverName ) ) {
-    errorStream_ << "RtApiAsio::getDeviceInfo: unable to load driver (" << driverName << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  result = ASIOInit( &driverInfo );
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") initializing driver (" << driverName << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Determine the device channel information.
-  long inputChannels, outputChannels;
-  result = ASIOGetChannels( &inputChannels, &outputChannels );
-  if ( result != ASE_OK ) {
-    drivers.removeCurrentDriver();
-    errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  info.outputChannels = outputChannels;
-  info.inputChannels = inputChannels;
-  if ( info.outputChannels > 0 && info.inputChannels > 0 )
-    info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-
-  // Determine the supported sample rates.
-  info.sampleRates.clear();
-  for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
-    result = ASIOCanSampleRate( (ASIOSampleRate) SAMPLE_RATES[i] );
-    if ( result == ASE_OK ) {
-      info.sampleRates.push_back( SAMPLE_RATES[i] );
-
-      if ( !info.preferredSampleRate || ( SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate ) )
-        info.preferredSampleRate = SAMPLE_RATES[i];
-    }
-  }
-
-  // Determine supported data types ... just check first channel and assume rest are the same.
-  ASIOChannelInfo channelInfo;
-  channelInfo.channel = 0;
-  channelInfo.isInput = true;
-  if ( info.inputChannels <= 0 ) channelInfo.isInput = false;
-  result = ASIOGetChannelInfo( &channelInfo );
-  if ( result != ASE_OK ) {
-    drivers.removeCurrentDriver();
-    errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") getting driver channel info (" << driverName << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  info.nativeFormats = 0;
-  if ( channelInfo.type == ASIOSTInt16MSB || channelInfo.type == ASIOSTInt16LSB )
-    info.nativeFormats |= RTAUDIO_SINT16;
-  else if ( channelInfo.type == ASIOSTInt32MSB || channelInfo.type == ASIOSTInt32LSB )
-    info.nativeFormats |= RTAUDIO_SINT32;
-  else if ( channelInfo.type == ASIOSTFloat32MSB || channelInfo.type == ASIOSTFloat32LSB )
-    info.nativeFormats |= RTAUDIO_FLOAT32;
-  else if ( channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB )
-    info.nativeFormats |= RTAUDIO_FLOAT64;
-  else if ( channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB )
-    info.nativeFormats |= RTAUDIO_SINT24;
-
-  if ( info.outputChannels > 0 )
-    if ( getDefaultOutputDevice() == device ) info.isDefaultOutput = true;
-  if ( info.inputChannels > 0 )
-    if ( getDefaultInputDevice() == device ) info.isDefaultInput = true;
-
-  info.probed = true;
-  drivers.removeCurrentDriver();
-  return info;
-}
-
-static void bufferSwitch( long index, ASIOBool /*processNow*/ )
-{
-  RtApiAsio *object = (RtApiAsio *) asioCallbackInfo->object;
-  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,
-                                   RtAudio::StreamOptions *options )
-{////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-  bool isDuplexInput =  mode == INPUT && stream_.mode == OUTPUT;
-
-  // For ASIO, a duplex stream MUST use the same driver.
-  if ( isDuplexInput && stream_.device[0] != device ) {
-    errorText_ = "RtApiAsio::probeDeviceOpen: an ASIO duplex stream must use the same device for input and output!";
-    return FAILURE;
-  }
-
-  char driverName[32];
-  ASIOError result = drivers.asioGetDriverName( (int) device, driverName, 32 );
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: unable to get driver name (" << getAsioErrorString( result ) << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Only load the driver once for duplex stream.
-  if ( !isDuplexInput ) {
-    // 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();
-
-    if ( !drivers.loadDriver( driverName ) ) {
-      errorStream_ << "RtApiAsio::probeDeviceOpen: unable to load driver (" << driverName << ").";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    result = ASIOInit( &driverInfo );
-    if ( result != ASE_OK ) {
-      errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") initializing driver (" << driverName << ").";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-  }
-
-  // keep them before any "goto error", they are used for error cleanup + goto device boundary checks
-  bool buffersAllocated = false;
-  AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
-  unsigned int nChannels;
-
-
-  // Check the device channel count.
-  long inputChannels, outputChannels;
-  result = ASIOGetChannels( &inputChannels, &outputChannels );
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
-    errorText_ = errorStream_.str();
-    goto error;
-  }
-
-  if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) ||
-       ( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ").";
-    errorText_ = errorStream_.str();
-    goto error;
-  }
-  stream_.nDeviceChannels[mode] = channels;
-  stream_.nUserChannels[mode] = channels;
-  stream_.channelOffset[mode] = firstChannel;
-
-  // Verify the sample rate is supported.
-  result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate );
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ").";
-    errorText_ = errorStream_.str();
-    goto error;
-  }
-
-  // Get the current sample rate
-  ASIOSampleRate currentRate;
-  result = ASIOGetSampleRate( &currentRate );
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate.";
-    errorText_ = errorStream_.str();
-    goto error;
-  }
-
-  // Set the sample rate only if necessary
-  if ( currentRate != sampleRate ) {
-    result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate );
-    if ( result != ASE_OK ) {
-      errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ").";
-      errorText_ = errorStream_.str();
-      goto error;
-    }
-  }
-
-  // Determine the driver data type.
-  ASIOChannelInfo channelInfo;
-  channelInfo.channel = 0;
-  if ( mode == OUTPUT ) channelInfo.isInput = false;
-  else channelInfo.isInput = true;
-  result = ASIOGetChannelInfo( &channelInfo );
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format.";
-    errorText_ = errorStream_.str();
-    goto error;
-  }
-
-  // Assuming WINDOWS host is always little-endian.
-  stream_.doByteSwap[mode] = false;
-  stream_.userFormat = format;
-  stream_.deviceFormat[mode] = 0;
-  if ( channelInfo.type == ASIOSTInt16MSB || channelInfo.type == ASIOSTInt16LSB ) {
-    stream_.deviceFormat[mode] = RTAUDIO_SINT16;
-    if ( channelInfo.type == ASIOSTInt16MSB ) stream_.doByteSwap[mode] = true;
-  }
-  else if ( channelInfo.type == ASIOSTInt32MSB || channelInfo.type == ASIOSTInt32LSB ) {
-    stream_.deviceFormat[mode] = RTAUDIO_SINT32;
-    if ( channelInfo.type == ASIOSTInt32MSB ) stream_.doByteSwap[mode] = true;
-  }
-  else if ( channelInfo.type == ASIOSTFloat32MSB || channelInfo.type == ASIOSTFloat32LSB ) {
-    stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
-    if ( channelInfo.type == ASIOSTFloat32MSB ) stream_.doByteSwap[mode] = true;
-  }
-  else if ( channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB ) {
-    stream_.deviceFormat[mode] = RTAUDIO_FLOAT64;
-    if ( channelInfo.type == ASIOSTFloat64MSB ) stream_.doByteSwap[mode] = true;
-  }
-  else if ( channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB ) {
-    stream_.deviceFormat[mode] = RTAUDIO_SINT24;
-    if ( channelInfo.type == ASIOSTInt24MSB ) stream_.doByteSwap[mode] = true;
-  }
-
-  if ( stream_.deviceFormat[mode] == 0 ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio.";
-    errorText_ = errorStream_.str();
-    goto error;
-  }
-
-  // Set the buffer size.  For a duplex stream, this will end up
-  // setting the buffer size based on the input constraints, which
-  // should be ok.
-  long minSize, maxSize, preferSize, granularity;
-  result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity );
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size.";
-    errorText_ = errorStream_.str();
-    goto error;
-  }
-
-  if ( isDuplexInput ) {
-    // When this is the duplex input (output was opened before), then we have to use the same
-    // buffersize as the output, because it might use the preferred buffer size, which most
-    // likely wasn't passed as input to this. The buffer sizes have to be identically anyway,
-    // So instead of throwing an error, make them equal. The caller uses the reference
-    // to the "bufferSize" param as usual to set up processing buffers.
-
-    *bufferSize = stream_.bufferSize;
-
-  } else {
-    if ( *bufferSize == 0 ) *bufferSize = preferSize;
-    else if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
-    else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
-    else if ( granularity == -1 ) {
-      // Make sure bufferSize is a power of two.
-      int log2_of_min_size = 0;
-      int log2_of_max_size = 0;
-
-      for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) {
-        if ( minSize & ((long)1 << i) ) log2_of_min_size = i;
-        if ( maxSize & ((long)1 << i) ) log2_of_max_size = i;
-      }
-
-      long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) );
-      int min_delta_num = log2_of_min_size;
-
-      for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) {
-        long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) );
-        if (current_delta < min_delta) {
-          min_delta = current_delta;
-          min_delta_num = i;
-        }
-      }
-
-      *bufferSize = ( (unsigned int)1 << min_delta_num );
-      if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
-      else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
-    }
-    else if ( granularity != 0 ) {
-      // Set to an even multiple of granularity, rounding up.
-      *bufferSize = (*bufferSize + granularity-1) / granularity * granularity;
-    }
-  }
-
-  /*
-  // we don't use it anymore, see above!
-  // Just left it here for the case...
-  if ( isDuplexInput && stream_.bufferSize != *bufferSize ) {
-    errorText_ = "RtApiAsio::probeDeviceOpen: input/output buffersize discrepancy!";
-    goto error;
-  }
-  */
-
-  stream_.bufferSize = *bufferSize;
-  stream_.nBuffers = 2;
-
-  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
-  else stream_.userInterleaved = true;
-
-  // ASIO always uses non-interleaved buffers.
-  stream_.deviceInterleaved[mode] = false;
-
-  // Allocate, if necessary, our AsioHandle structure for the stream.
-  if ( handle == 0 ) {
-    try {
-      handle = new AsioHandle;
-    }
-    catch ( std::bad_alloc& ) {
-      errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory.";
-      goto error;
-    }
-    handle->bufferInfos = 0;
-
-    // Create a manual-reset event.
-    handle->condition = CreateEvent( NULL,   // no security
-                                     TRUE,   // manual-reset
-                                     FALSE,  // non-signaled initially
-                                     NULL ); // unnamed
-    stream_.apiHandle = (void *) handle;
-  }
-
-  // Create the ASIO internal buffers.  Since RtAudio sets up input
-  // and output separately, we'll have to dispose of previously
-  // created output buffers for a duplex stream.
-  if ( mode == INPUT && stream_.mode == OUTPUT ) {
-    ASIODisposeBuffers();
-    if ( handle->bufferInfos ) free( handle->bufferInfos );
-  }
-
-  // Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure.
-  unsigned int i;
-  nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
-  handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) );
-  if ( handle->bufferInfos == NULL ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ").";
-    errorText_ = errorStream_.str();
-    goto error;
-  }
-
-  ASIOBufferInfo *infos;
-  infos = handle->bufferInfos;
-  for ( i=0; i<stream_.nDeviceChannels[0]; i++, infos++ ) {
-    infos->isInput = ASIOFalse;
-    infos->channelNum = i + stream_.channelOffset[0];
-    infos->buffers[0] = infos->buffers[1] = 0;
-  }
-  for ( i=0; i<stream_.nDeviceChannels[1]; i++, infos++ ) {
-    infos->isInput = ASIOTrue;
-    infos->channelNum = i + stream_.channelOffset[1];
-    infos->buffers[0] = infos->buffers[1] = 0;
-  }
-
-  // prepare for callbacks
-  stream_.sampleRate = sampleRate;
-  stream_.device[mode] = device;
-  stream_.mode = isDuplexInput ? DUPLEX : mode;
-
-  // store this class instance before registering callbacks, that are going to use it
-  asioCallbackInfo = &stream_.callbackInfo;
-  stream_.callbackInfo.object = (void *) this;
-
-  // Set up the ASIO callback structure and create the ASIO data buffers.
-  asioCallbacks.bufferSwitch = &bufferSwitch;
-  asioCallbacks.sampleRateDidChange = &sampleRateChanged;
-  asioCallbacks.asioMessage = &asioMessages;
-  asioCallbacks.bufferSwitchTimeInfo = NULL;
-  result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
-  if ( result != ASE_OK ) {
-    // Standard method failed. This can happen with strict/misbehaving drivers that return valid buffer size ranges
-    // but only accept the preferred buffer size as parameter for ASIOCreateBuffers (e.g. Creative's ASIO driver).
-    // In that case, let's be naïve and try that instead.
-    *bufferSize = preferSize;
-    stream_.bufferSize = *bufferSize;
-    result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
-  }
-
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers.";
-    errorText_ = errorStream_.str();
-    goto error;
-  }
-  buffersAllocated = true;  
-  stream_.state = STREAM_STOPPED;
-
-  // Set flags for buffer conversion.
-  stream_.doConvertBuffer[mode] = false;
-  if ( stream_.userFormat != stream_.deviceFormat[mode] )
-    stream_.doConvertBuffer[mode] = true;
-  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
-       stream_.nUserChannels[mode] > 1 )
-    stream_.doConvertBuffer[mode] = true;
-
-  // Allocate necessary internal buffers
-  unsigned long bufferBytes;
-  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
-  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
-  if ( stream_.userBuffer[mode] == NULL ) {
-    errorText_ = "RtApiAsio::probeDeviceOpen: error allocating user buffer memory.";
-    goto error;
-  }
-
-  if ( stream_.doConvertBuffer[mode] ) {
-
-    bool makeBuffer = true;
-    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
-    if ( isDuplexInput && stream_.deviceBuffer ) {
-      unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
-      if ( bufferBytes <= bytesOut ) makeBuffer = false;
-    }
-
-    if ( makeBuffer ) {
-      bufferBytes *= *bufferSize;
-      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
-      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
-      if ( stream_.deviceBuffer == NULL ) {
-        errorText_ = "RtApiAsio::probeDeviceOpen: error allocating device buffer memory.";
-        goto error;
-      }
-    }
-  }
-
-  // Determine device latencies
-  long inputLatency, outputLatency;
-  result = ASIOGetLatencies( &inputLatency, &outputLatency );
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting latency.";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING); // warn but don't fail
-  }
-  else {
-    stream_.latency[0] = outputLatency;
-    stream_.latency[1] = inputLatency;
-  }
-
-  // Setup the buffer conversion information structure.  We don't use
-  // buffers to do channel offsets, so we override that parameter
-  // here.
-  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, 0 );
-
-  return SUCCESS;
-
- error:
-  if ( !isDuplexInput ) {
-    // the cleanup for error in the duplex input, is done by RtApi::openStream
-    // So we clean up for single channel only
-
-    if ( buffersAllocated )
-      ASIODisposeBuffers();
-
-    drivers.removeCurrentDriver();
-
-    if ( handle ) {
-      CloseHandle( handle->condition );
-      if ( handle->bufferInfos )
-        free( handle->bufferInfos );
-
-      delete handle;
-      stream_.apiHandle = 0;
-    }
-
-
-    if ( stream_.userBuffer[mode] ) {
-      free( stream_.userBuffer[mode] );
-      stream_.userBuffer[mode] = 0;
-    }
-
-    if ( stream_.deviceBuffer ) {
-      free( stream_.deviceBuffer );
-      stream_.deviceBuffer = 0;
-    }
-  }
-
-  return FAILURE;
-}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void RtApiAsio :: closeStream()
-{
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiAsio::closeStream(): no open stream to close!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  if ( stream_.state == STREAM_RUNNING ) {
-    stream_.state = STREAM_STOPPED;
-    ASIOStop();
-  }
-  ASIODisposeBuffers();
-  drivers.removeCurrentDriver();
-
-  AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
-  if ( handle ) {
-    CloseHandle( handle->condition );
-    if ( handle->bufferInfos )
-      free( handle->bufferInfos );
-    delete handle;
-    stream_.apiHandle = 0;
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  stream_.mode = UNINITIALIZED;
-  stream_.state = STREAM_CLOSED;
-}
-
-bool stopThreadCalled = false;
-
-void RtApiAsio :: startStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_RUNNING ) {
-    errorText_ = "RtApiAsio::startStream(): the stream is already running!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  #if defined( HAVE_GETTIMEOFDAY )
-  gettimeofday( &stream_.lastTickTimestamp, NULL );
-  #endif
-
-  AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
-  ASIOError result = ASIOStart();
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::startStream: error (" << getAsioErrorString( result ) << ") starting device.";
-    errorText_ = errorStream_.str();
-    goto unlock;
-  }
-
-  handle->drainCounter = 0;
-  handle->internalDrain = false;
-  ResetEvent( handle->condition );
-  stream_.state = STREAM_RUNNING;
-  asioXRun = false;
-
- unlock:
-  stopThreadCalled = false;
-
-  if ( result == ASE_OK ) return;
-  error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiAsio :: stopStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiAsio::stopStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-    if ( handle->drainCounter == 0 ) {
-      handle->drainCounter = 2;
-      WaitForSingleObject( handle->condition, INFINITE );  // block until signaled
-    }
-  }
-
-  stream_.state = STREAM_STOPPED;
-
-  ASIOError result = ASIOStop();
-  if ( result != ASE_OK ) {
-    errorStream_ << "RtApiAsio::stopStream: error (" << getAsioErrorString( result ) << ") stopping device.";
-    errorText_ = errorStream_.str();
-  }
-
-  if ( result == ASE_OK ) return;
-  error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiAsio :: abortStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiAsio::abortStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  // The following lines were commented-out because some behavior was
-  // noted where the device buffers need to be zeroed to avoid
-  // continuing sound, even when the device buffers are completely
-  // disposed.  So now, calling abort is the same as calling stop.
-  // AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
-  // handle->drainCounter = 2;
-  stopStream();
-}
-
-// This function will be called by a spawned thread when the user
-// callback function signals that the stream should be stopped or
-// aborted.  It is necessary to handle it this way because the
-// callbackEvent() function must return before the ASIOStop()
-// function will return.
-static unsigned __stdcall asioStopStream( void *ptr )
-{
-  CallbackInfo *info = (CallbackInfo *) ptr;
-  RtApiAsio *object = (RtApiAsio *) info->object;
-
-  object->stopStream();
-  _endthreadex( 0 );
-  return 0;
-}
-
-bool RtApiAsio :: callbackEvent( long bufferIndex )
-{
-  if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiAsio::callbackEvent(): the stream is closed ... this shouldn't happen!";
-    error( RtAudioError::WARNING );
-    return FAILURE;
-  }
-
-  CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
-  AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
-
-  // Check if we were draining the stream and signal if finished.
-  if ( handle->drainCounter > 3 ) {
-
-    stream_.state = STREAM_STOPPING;
-    if ( handle->internalDrain == false )
-      SetEvent( handle->condition );
-    else { // spawn a thread to stop the stream
-      unsigned threadId;
-      stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &asioStopStream,
-                                                    &stream_.callbackInfo, 0, &threadId );
-    }
-    return SUCCESS;
-  }
-
-  // Invoke user callback to get fresh output data UNLESS we are
-  // draining stream.
-  if ( handle->drainCounter == 0 ) {
-    RtAudioCallback callback = (RtAudioCallback) info->callback;
-    double streamTime = getStreamTime();
-    RtAudioStreamStatus status = 0;
-    if ( stream_.mode != INPUT && asioXRun == true ) {
-      status |= RTAUDIO_OUTPUT_UNDERFLOW;
-      asioXRun = false;
-    }
-    if ( stream_.mode != OUTPUT && asioXRun == true ) {
-      status |= RTAUDIO_INPUT_OVERFLOW;
-      asioXRun = false;
-    }
-    int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
-                                     stream_.bufferSize, streamTime, status, info->userData );
-    if ( cbReturnValue == 2 ) {
-      stream_.state = STREAM_STOPPING;
-      handle->drainCounter = 2;
-      unsigned threadId;
-      stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &asioStopStream,
-                                                    &stream_.callbackInfo, 0, &threadId );
-      return SUCCESS;
-    }
-    else if ( cbReturnValue == 1 ) {
-      handle->drainCounter = 1;
-      handle->internalDrain = true;
-    }
-  }
-
-  unsigned int nChannels, bufferBytes, i, j;
-  nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
-    bufferBytes = stream_.bufferSize * formatBytes( stream_.deviceFormat[0] );
-
-    if ( handle->drainCounter > 1 ) { // write zeros to the output stream
-
-      for ( i=0, j=0; i<nChannels; i++ ) {
-        if ( handle->bufferInfos[i].isInput != ASIOTrue )
-          memset( handle->bufferInfos[i].buffers[bufferIndex], 0, bufferBytes );
-      }
-
-    }
-    else if ( stream_.doConvertBuffer[0] ) {
-
-      convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] );
-      if ( stream_.doByteSwap[0] )
-        byteSwapBuffer( stream_.deviceBuffer,
-                        stream_.bufferSize * stream_.nDeviceChannels[0],
-                        stream_.deviceFormat[0] );
-
-      for ( i=0, j=0; i<nChannels; i++ ) {
-        if ( handle->bufferInfos[i].isInput != ASIOTrue )
-          memcpy( handle->bufferInfos[i].buffers[bufferIndex],
-                  &stream_.deviceBuffer[j++*bufferBytes], bufferBytes );
-      }
-
-    }
-    else {
-
-      if ( stream_.doByteSwap[0] )
-        byteSwapBuffer( stream_.userBuffer[0],
-                        stream_.bufferSize * stream_.nUserChannels[0],
-                        stream_.userFormat );
-
-      for ( i=0, j=0; i<nChannels; i++ ) {
-        if ( handle->bufferInfos[i].isInput != ASIOTrue )
-          memcpy( handle->bufferInfos[i].buffers[bufferIndex],
-                  &stream_.userBuffer[0][bufferBytes*j++], bufferBytes );
-      }
-
-    }
-  }
-
-  // Don't bother draining input
-  if ( handle->drainCounter ) {
-    handle->drainCounter++;
-    goto unlock;
-  }
-
-  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
-    bufferBytes = stream_.bufferSize * formatBytes(stream_.deviceFormat[1]);
-
-    if (stream_.doConvertBuffer[1]) {
-
-      // Always interleave ASIO input data.
-      for ( i=0, j=0; i<nChannels; i++ ) {
-        if ( handle->bufferInfos[i].isInput == ASIOTrue )
-          memcpy( &stream_.deviceBuffer[j++*bufferBytes],
-                  handle->bufferInfos[i].buffers[bufferIndex],
-                  bufferBytes );
-      }
-
-      if ( stream_.doByteSwap[1] )
-        byteSwapBuffer( stream_.deviceBuffer,
-                        stream_.bufferSize * stream_.nDeviceChannels[1],
-                        stream_.deviceFormat[1] );
-      convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
-
-    }
-    else {
-      for ( i=0, j=0; i<nChannels; i++ ) {
-        if ( handle->bufferInfos[i].isInput == ASIOTrue ) {
-          memcpy( &stream_.userBuffer[1][bufferBytes*j++],
-                  handle->bufferInfos[i].buffers[bufferIndex],
-                  bufferBytes );
-        }
-      }
-
-      if ( stream_.doByteSwap[1] )
-        byteSwapBuffer( stream_.userBuffer[1],
-                        stream_.bufferSize * stream_.nUserChannels[1],
-                        stream_.userFormat );
-    }
-  }
-
- unlock:
-  // The following call was suggested by Malte Clasen.  While the API
-  // documentation indicates it should not be required, some device
-  // drivers apparently do not function correctly without it.
-  ASIOOutputReady();
-
-  RtApi::tickStreamTime();
-  return SUCCESS;
-}
-
-static void sampleRateChanged( ASIOSampleRate sRate )
-{
-  // The ASIO documentation says that this usually only happens during
-  // external sync.  Audio processing is not stopped by the driver,
-  // actual sample rate might not have even changed, maybe only the
-  // sample rate status of an AES/EBU or S/PDIF digital input at the
-  // audio device.
-
-  RtApi *object = (RtApi *) asioCallbackInfo->object;
-  try {
-    object->stopStream();
-  }
-  catch ( RtAudioError &exception ) {
-    std::cerr << "\nRtApiAsio: sampleRateChanged() error (" << exception.getMessage() << ")!\n" << std::endl;
-    return;
-  }
-
-  std::cerr << "\nRtApiAsio: driver reports sample rate changed to " << sRate << " ... stream stopped!!!\n" << std::endl;
-}
-
-static long asioMessages( long selector, long value, void* /*message*/, double* /*opt*/ )
-{
-  long ret = 0;
-
-  switch( selector ) {
-  case kAsioSelectorSupported:
-    if ( value == kAsioResetRequest
-         || value == kAsioEngineVersion
-         || value == kAsioResyncRequest
-         || value == kAsioLatenciesChanged
-         // The following three were added for ASIO 2.0, you don't
-         // necessarily have to support them.
-         || value == kAsioSupportsTimeInfo
-         || value == kAsioSupportsTimeCode
-         || value == kAsioSupportsInputMonitor)
-      ret = 1L;
-    break;
-  case kAsioResetRequest:
-    // Defer the task and perform the reset of the driver during the
-    // next "safe" situation.  You cannot reset the driver right now,
-    // as this code is called from the driver.  Reset the driver is
-    // done by completely destruct is. I.e. ASIOStop(),
-    // ASIODisposeBuffers(), Destruction Afterwards you initialize the
-    // driver again.
-    std::cerr << "\nRtApiAsio: driver reset requested!!!" << std::endl;
-    ret = 1L;
-    break;
-  case kAsioResyncRequest:
-    // This informs the application that the driver encountered some
-    // non-fatal data loss.  It is used for synchronization purposes
-    // of different media.  Added mainly to work around the Win16Mutex
-    // problems in Windows 95/98 with the Windows Multimedia system,
-    // which could lose data because the Mutex was held too long by
-    // another thread.  However a driver can issue it in other
-    // situations, too.
-    // std::cerr << "\nRtApiAsio: driver resync requested!!!" << std::endl;
-    asioXRun = true;
-    ret = 1L;
-    break;
-  case kAsioLatenciesChanged:
-    // This will inform the host application that the drivers were
-    // latencies changed.  Beware, it this does not mean that the
-    // buffer sizes have changed!  You might need to update internal
-    // delay data.
-    std::cerr << "\nRtApiAsio: driver latency may have changed!!!" << std::endl;
-    ret = 1L;
-    break;
-  case kAsioEngineVersion:
-    // Return the supported ASIO version of the host application.  If
-    // a host application does not implement this selector, ASIO 1.0
-    // is assumed by the driver.
-    ret = 2L;
-    break;
-  case kAsioSupportsTimeInfo:
-    // Informs the driver whether the
-    // asioCallbacks.bufferSwitchTimeInfo() callback is supported.
-    // For compatibility with ASIO 1.0 drivers the host application
-    // should always support the "old" bufferSwitch method, too.
-    ret = 0;
-    break;
-  case kAsioSupportsTimeCode:
-    // Informs the driver whether application is interested in time
-    // code info.  If an application does not need to know about time
-    // code, the driver has less work to do.
-    ret = 0;
-    break;
-  }
-  return ret;
-}
-
-static const char* getAsioErrorString( ASIOError result )
-{
-  struct Messages 
-  {
-    ASIOError value;
-    const char*message;
-  };
-
-  static const Messages m[] = 
-    {
-      {   ASE_NotPresent,    "Hardware input or output is not present or available." },
-      {   ASE_HWMalfunction,  "Hardware is malfunctioning." },
-      {   ASE_InvalidParameter, "Invalid input parameter." },
-      {   ASE_InvalidMode,      "Invalid mode." },
-      {   ASE_SPNotAdvancing,     "Sample position not advancing." },
-      {   ASE_NoClock,            "Sample clock or rate cannot be determined or is not present." },
-      {   ASE_NoMemory,           "Not enough memory to complete the request." }
-    };
-
-  for ( unsigned int i = 0; i < sizeof(m)/sizeof(m[0]); ++i )
-    if ( m[i].value == result ) return m[i].message;
-
-  return "Unknown error.";
-}
-
-//******************** End of __WINDOWS_ASIO__ *********************//
-#endif
-
-
-#if defined(__WINDOWS_WASAPI__) // Windows WASAPI API
-
-// Authored by Marcus Tomlinson <themarcustomlinson@gmail.com>, April 2014
-// - Introduces support for the Windows WASAPI API
-// - Aims to deliver bit streams to and from hardware at the lowest possible latency, via the absolute minimum buffer sizes required
-// - Provides flexible stream configuration to an otherwise strict and inflexible WASAPI interface
-// - Includes automatic internal conversion of sample rate and buffer size between hardware and the user
-
-#ifndef INITGUID
-  #define INITGUID
-#endif
-
-#include <mfapi.h>
-#include <mferror.h>
-#include <mfplay.h>
-#include <mftransform.h>
-#include <wmcodecdsp.h>
-
-#include <audioclient.h>
-#include <avrt.h>
-#include <mmdeviceapi.h>
-#include <functiondiscoverykeys_devpkey.h>
-
-#ifndef MF_E_TRANSFORM_NEED_MORE_INPUT
-  #define MF_E_TRANSFORM_NEED_MORE_INPUT _HRESULT_TYPEDEF_(0xc00d6d72)
-#endif
-
-#ifndef MFSTARTUP_NOSOCKET
-  #define MFSTARTUP_NOSOCKET 0x1
-#endif
-
-#ifdef _MSC_VER
-  #pragma comment( lib, "ksuser" )
-  #pragma comment( lib, "mfplat.lib" )
-  #pragma comment( lib, "mfuuid.lib" )
-  #pragma comment( lib, "wmcodecdspuuid" )
-#endif
-
-//=============================================================================
-
-#define SAFE_RELEASE( objectPtr )\
-if ( objectPtr )\
-{\
-  objectPtr->Release();\
-  objectPtr = NULL;\
-}
-
-typedef HANDLE ( __stdcall *TAvSetMmThreadCharacteristicsPtr )( LPCWSTR TaskName, LPDWORD TaskIndex );
-
-//-----------------------------------------------------------------------------
-
-// WASAPI dictates stream sample rate, format, channel count, and in some cases, buffer size.
-// Therefore we must perform all necessary conversions to user buffers in order to satisfy these
-// requirements. WasapiBuffer ring buffers are used between HwIn->UserIn and UserOut->HwOut to
-// provide intermediate storage for read / write synchronization.
-class WasapiBuffer
-{
-public:
-  WasapiBuffer()
-    : buffer_( NULL ),
-      bufferSize_( 0 ),
-      inIndex_( 0 ),
-      outIndex_( 0 ) {}
-
-  ~WasapiBuffer() {
-    free( buffer_ );
-  }
-
-  // sets the length of the internal ring buffer
-  void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) {
-    free( buffer_ );
-
-    buffer_ = ( char* ) calloc( bufferSize, formatBytes );
-
-    bufferSize_ = bufferSize;
-    inIndex_ = 0;
-    outIndex_ = 0;
-  }
-
-  // attempt to push a buffer into the ring buffer at the current "in" index
-  bool pushBuffer( char* buffer, unsigned int bufferSize, RtAudioFormat format )
-  {
-    if ( !buffer ||                 // incoming buffer is NULL
-         bufferSize == 0 ||         // incoming buffer has no data
-         bufferSize > bufferSize_ ) // incoming buffer too large
-    {
-      return false;
-    }
-
-    unsigned int relOutIndex = outIndex_;
-    unsigned int inIndexEnd = inIndex_ + bufferSize;
-    if ( relOutIndex < inIndex_ && inIndexEnd >= bufferSize_ ) {
-      relOutIndex += bufferSize_;
-    }
-
-    // the "IN" index CAN BEGIN at the "OUT" index
-    // the "IN" index CANNOT END at the "OUT" index
-    if ( inIndex_ < relOutIndex && inIndexEnd >= relOutIndex ) {
-      return false; // not enough space between "in" index and "out" index
-    }
-
-    // copy buffer from external to internal
-    int fromZeroSize = inIndex_ + bufferSize - bufferSize_;
-    fromZeroSize = fromZeroSize < 0 ? 0 : fromZeroSize;
-    int fromInSize = bufferSize - fromZeroSize;
-
-    switch( format )
-      {
-      case RTAUDIO_SINT8:
-        memcpy( &( ( char* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( char ) );
-        memcpy( buffer_, &( ( char* ) buffer )[fromInSize], fromZeroSize * sizeof( char ) );
-        break;
-      case RTAUDIO_SINT16:
-        memcpy( &( ( short* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( short ) );
-        memcpy( buffer_, &( ( short* ) buffer )[fromInSize], fromZeroSize * sizeof( short ) );
-        break;
-      case RTAUDIO_SINT24:
-        memcpy( &( ( S24* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( S24 ) );
-        memcpy( buffer_, &( ( S24* ) buffer )[fromInSize], fromZeroSize * sizeof( S24 ) );
-        break;
-      case RTAUDIO_SINT32:
-        memcpy( &( ( int* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( int ) );
-        memcpy( buffer_, &( ( int* ) buffer )[fromInSize], fromZeroSize * sizeof( int ) );
-        break;
-      case RTAUDIO_FLOAT32:
-        memcpy( &( ( float* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( float ) );
-        memcpy( buffer_, &( ( float* ) buffer )[fromInSize], fromZeroSize * sizeof( float ) );
-        break;
-      case RTAUDIO_FLOAT64:
-        memcpy( &( ( double* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( double ) );
-        memcpy( buffer_, &( ( double* ) buffer )[fromInSize], fromZeroSize * sizeof( double ) );
-        break;
-    }
-
-    // update "in" index
-    inIndex_ += bufferSize;
-    inIndex_ %= bufferSize_;
-
-    return true;
-  }
-
-  // attempt to pull a buffer from the ring buffer from the current "out" index
-  bool pullBuffer( char* buffer, unsigned int bufferSize, RtAudioFormat format )
-  {
-    if ( !buffer ||                 // incoming buffer is NULL
-         bufferSize == 0 ||         // incoming buffer has no data
-         bufferSize > bufferSize_ ) // incoming buffer too large
-    {
-      return false;
-    }
-
-    unsigned int relInIndex = inIndex_;
-    unsigned int outIndexEnd = outIndex_ + bufferSize;
-    if ( relInIndex < outIndex_ && outIndexEnd >= bufferSize_ ) {
-      relInIndex += bufferSize_;
-    }
-
-    // the "OUT" index CANNOT BEGIN at the "IN" index
-    // the "OUT" index CAN END at the "IN" index
-    if ( outIndex_ <= relInIndex && outIndexEnd > relInIndex ) {
-      return false; // not enough space between "out" index and "in" index
-    }
-
-    // copy buffer from internal to external
-    int fromZeroSize = outIndex_ + bufferSize - bufferSize_;
-    fromZeroSize = fromZeroSize < 0 ? 0 : fromZeroSize;
-    int fromOutSize = bufferSize - fromZeroSize;
-
-    switch( format )
-    {
-      case RTAUDIO_SINT8:
-        memcpy( buffer, &( ( char* ) buffer_ )[outIndex_], fromOutSize * sizeof( char ) );
-        memcpy( &( ( char* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( char ) );
-        break;
-      case RTAUDIO_SINT16:
-        memcpy( buffer, &( ( short* ) buffer_ )[outIndex_], fromOutSize * sizeof( short ) );
-        memcpy( &( ( short* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( short ) );
-        break;
-      case RTAUDIO_SINT24:
-        memcpy( buffer, &( ( S24* ) buffer_ )[outIndex_], fromOutSize * sizeof( S24 ) );
-        memcpy( &( ( S24* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( S24 ) );
-        break;
-      case RTAUDIO_SINT32:
-        memcpy( buffer, &( ( int* ) buffer_ )[outIndex_], fromOutSize * sizeof( int ) );
-        memcpy( &( ( int* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( int ) );
-        break;
-      case RTAUDIO_FLOAT32:
-        memcpy( buffer, &( ( float* ) buffer_ )[outIndex_], fromOutSize * sizeof( float ) );
-        memcpy( &( ( float* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( float ) );
-        break;
-      case RTAUDIO_FLOAT64:
-        memcpy( buffer, &( ( double* ) buffer_ )[outIndex_], fromOutSize * sizeof( double ) );
-        memcpy( &( ( double* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( double ) );
-        break;
-    }
-
-    // update "out" index
-    outIndex_ += bufferSize;
-    outIndex_ %= bufferSize_;
-
-    return true;
-  }
-
-private:
-  char* buffer_;
-  unsigned int bufferSize_;
-  unsigned int inIndex_;
-  unsigned int outIndex_;
-};
-
-//-----------------------------------------------------------------------------
-
-// In order to satisfy WASAPI's buffer requirements, we need a means of converting sample rate
-// between HW and the user. The WasapiResampler class is used to perform this conversion between
-// HwIn->UserIn and UserOut->HwOut during the stream callback loop.
-class WasapiResampler
-{
-public:
-  WasapiResampler( bool isFloat, unsigned int bitsPerSample, unsigned int channelCount,
-                   unsigned int inSampleRate, unsigned int outSampleRate )
-    : _bytesPerSample( bitsPerSample / 8 )
-    , _channelCount( channelCount )
-    , _sampleRatio( ( float ) outSampleRate / inSampleRate )
-    , _transformUnk( NULL )
-    , _transform( NULL )
-    , _mediaType( NULL )
-    , _inputMediaType( NULL )
-    , _outputMediaType( NULL )
-
-    #ifdef __IWMResamplerProps_FWD_DEFINED__
-      , _resamplerProps( NULL )
-    #endif
-  {
-    // 1. Initialization
-
-    MFStartup( MF_VERSION, MFSTARTUP_NOSOCKET );
-
-    // 2. Create Resampler Transform Object
-
-    CoCreateInstance( CLSID_CResamplerMediaObject, NULL, CLSCTX_INPROC_SERVER,
-                      IID_IUnknown, ( void** ) &_transformUnk );
-
-    _transformUnk->QueryInterface( IID_PPV_ARGS( &_transform ) );
-
-    #ifdef __IWMResamplerProps_FWD_DEFINED__
-      _transformUnk->QueryInterface( IID_PPV_ARGS( &_resamplerProps ) );
-      _resamplerProps->SetHalfFilterLength( 60 ); // best conversion quality
-    #endif
-
-    // 3. Specify input / output format
-
-    MFCreateMediaType( &_mediaType );
-    _mediaType->SetGUID( MF_MT_MAJOR_TYPE, MFMediaType_Audio );
-    _mediaType->SetGUID( MF_MT_SUBTYPE, isFloat ? MFAudioFormat_Float : MFAudioFormat_PCM );
-    _mediaType->SetUINT32( MF_MT_AUDIO_NUM_CHANNELS, channelCount );
-    _mediaType->SetUINT32( MF_MT_AUDIO_SAMPLES_PER_SECOND, inSampleRate );
-    _mediaType->SetUINT32( MF_MT_AUDIO_BLOCK_ALIGNMENT, _bytesPerSample * channelCount );
-    _mediaType->SetUINT32( MF_MT_AUDIO_AVG_BYTES_PER_SECOND, _bytesPerSample * channelCount * inSampleRate );
-    _mediaType->SetUINT32( MF_MT_AUDIO_BITS_PER_SAMPLE, bitsPerSample );
-    _mediaType->SetUINT32( MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE );
-
-    MFCreateMediaType( &_inputMediaType );
-    _mediaType->CopyAllItems( _inputMediaType );
-
-    _transform->SetInputType( 0, _inputMediaType, 0 );
-
-    MFCreateMediaType( &_outputMediaType );
-    _mediaType->CopyAllItems( _outputMediaType );
-
-    _outputMediaType->SetUINT32( MF_MT_AUDIO_SAMPLES_PER_SECOND, outSampleRate );
-    _outputMediaType->SetUINT32( MF_MT_AUDIO_AVG_BYTES_PER_SECOND, _bytesPerSample * channelCount * outSampleRate );
-
-    _transform->SetOutputType( 0, _outputMediaType, 0 );
-
-    // 4. Send stream start messages to Resampler
-
-    _transform->ProcessMessage( MFT_MESSAGE_COMMAND_FLUSH, 0 );
-    _transform->ProcessMessage( MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0 );
-    _transform->ProcessMessage( MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0 );
-  }
-
-  ~WasapiResampler()
-  {
-    // 8. Send stream stop messages to Resampler
-
-    _transform->ProcessMessage( MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0 );
-    _transform->ProcessMessage( MFT_MESSAGE_NOTIFY_END_STREAMING, 0 );
-
-    // 9. Cleanup
-
-    MFShutdown();
-
-    SAFE_RELEASE( _transformUnk );
-    SAFE_RELEASE( _transform );
-    SAFE_RELEASE( _mediaType );
-    SAFE_RELEASE( _inputMediaType );
-    SAFE_RELEASE( _outputMediaType );
-
-    #ifdef __IWMResamplerProps_FWD_DEFINED__
-      SAFE_RELEASE( _resamplerProps );
-    #endif
-  }
-
-  void Convert( char* outBuffer, const char* inBuffer, unsigned int inSampleCount, unsigned int& outSampleCount )
-  {
-    unsigned int inputBufferSize = _bytesPerSample * _channelCount * inSampleCount;
-    if ( _sampleRatio == 1 )
-    {
-      // no sample rate conversion required
-      memcpy( outBuffer, inBuffer, inputBufferSize );
-      outSampleCount = inSampleCount;
-      return;
-    }
-
-    unsigned int outputBufferSize = ( unsigned int ) ceilf( inputBufferSize * _sampleRatio ) + ( _bytesPerSample * _channelCount );
-
-    IMFMediaBuffer* rInBuffer;
-    IMFSample* rInSample;
-    BYTE* rInByteBuffer = NULL;
-
-    // 5. Create Sample object from input data
-
-    MFCreateMemoryBuffer( inputBufferSize, &rInBuffer );
-
-    rInBuffer->Lock( &rInByteBuffer, NULL, NULL );
-    memcpy( rInByteBuffer, inBuffer, inputBufferSize );
-    rInBuffer->Unlock();
-    rInByteBuffer = NULL;
-
-    rInBuffer->SetCurrentLength( inputBufferSize );
-
-    MFCreateSample( &rInSample );
-    rInSample->AddBuffer( rInBuffer );
-
-    // 6. Pass input data to Resampler
-
-    _transform->ProcessInput( 0, rInSample, 0 );
-
-    SAFE_RELEASE( rInBuffer );
-    SAFE_RELEASE( rInSample );
-
-    // 7. Perform sample rate conversion
-
-    IMFMediaBuffer* rOutBuffer = NULL;
-    BYTE* rOutByteBuffer = NULL;
-
-    MFT_OUTPUT_DATA_BUFFER rOutDataBuffer;
-    DWORD rStatus;
-    DWORD rBytes = outputBufferSize; // maximum bytes accepted per ProcessOutput
-
-    // 7.1 Create Sample object for output data
-
-    memset( &rOutDataBuffer, 0, sizeof rOutDataBuffer );
-    MFCreateSample( &( rOutDataBuffer.pSample ) );
-    MFCreateMemoryBuffer( rBytes, &rOutBuffer );
-    rOutDataBuffer.pSample->AddBuffer( rOutBuffer );
-    rOutDataBuffer.dwStreamID = 0;
-    rOutDataBuffer.dwStatus = 0;
-    rOutDataBuffer.pEvents = NULL;
-
-    // 7.2 Get output data from Resampler
-
-    if ( _transform->ProcessOutput( 0, 1, &rOutDataBuffer, &rStatus ) == MF_E_TRANSFORM_NEED_MORE_INPUT )
-    {
-      outSampleCount = 0;
-      SAFE_RELEASE( rOutBuffer );
-      SAFE_RELEASE( rOutDataBuffer.pSample );
-      return;
-    }
-
-    // 7.3 Write output data to outBuffer
-
-    SAFE_RELEASE( rOutBuffer );
-    rOutDataBuffer.pSample->ConvertToContiguousBuffer( &rOutBuffer );
-    rOutBuffer->GetCurrentLength( &rBytes );
-
-    rOutBuffer->Lock( &rOutByteBuffer, NULL, NULL );
-    memcpy( outBuffer, rOutByteBuffer, rBytes );
-    rOutBuffer->Unlock();
-    rOutByteBuffer = NULL;
-
-    outSampleCount = rBytes / _bytesPerSample / _channelCount;
-    SAFE_RELEASE( rOutBuffer );
-    SAFE_RELEASE( rOutDataBuffer.pSample );
-  }
-
-private:
-  unsigned int _bytesPerSample;
-  unsigned int _channelCount;
-  float _sampleRatio;
-
-  IUnknown* _transformUnk;
-  IMFTransform* _transform;
-  IMFMediaType* _mediaType;
-  IMFMediaType* _inputMediaType;
-  IMFMediaType* _outputMediaType;
-
-  #ifdef __IWMResamplerProps_FWD_DEFINED__
-    IWMResamplerProps* _resamplerProps;
-  #endif
-};
-
-//-----------------------------------------------------------------------------
-
-// A structure to hold various information related to the WASAPI implementation.
-struct WasapiHandle
-{
-  IAudioClient* captureAudioClient;
-  IAudioClient* renderAudioClient;
-  IAudioCaptureClient* captureClient;
-  IAudioRenderClient* renderClient;
-  HANDLE captureEvent;
-  HANDLE renderEvent;
-
-  WasapiHandle()
-  : captureAudioClient( NULL ),
-    renderAudioClient( NULL ),
-    captureClient( NULL ),
-    renderClient( NULL ),
-    captureEvent( NULL ),
-    renderEvent( NULL ) {}
-};
-
-//=============================================================================
-
-RtApiWasapi::RtApiWasapi()
-  : coInitialized_( false ), deviceEnumerator_( NULL )
-{
-  // WASAPI can run either apartment or multi-threaded
-  HRESULT hr = CoInitialize( NULL );
-  if ( !FAILED( hr ) )
-    coInitialized_ = true;
-
-  // Instantiate device enumerator
-  hr = CoCreateInstance( __uuidof( MMDeviceEnumerator ), NULL,
-                         CLSCTX_ALL, __uuidof( IMMDeviceEnumerator ),
-                         ( void** ) &deviceEnumerator_ );
-
-  // If this runs on an old Windows, it will fail. Ignore and proceed.
-  if ( FAILED( hr ) )
-    deviceEnumerator_ = NULL;
-}
-
-//-----------------------------------------------------------------------------
-
-RtApiWasapi::~RtApiWasapi()
-{
-  if ( stream_.state != STREAM_CLOSED )
-    closeStream();
-
-  SAFE_RELEASE( deviceEnumerator_ );
-
-  // If this object previously called CoInitialize()
-  if ( coInitialized_ )
-    CoUninitialize();
-}
-
-//=============================================================================
-
-unsigned int RtApiWasapi::getDeviceCount( void )
-{
-  unsigned int captureDeviceCount = 0;
-  unsigned int renderDeviceCount = 0;
-
-  IMMDeviceCollection* captureDevices = NULL;
-  IMMDeviceCollection* renderDevices = NULL;
-
-  if ( !deviceEnumerator_ )
-    return 0;
-
-  // Count capture devices
-  errorText_.clear();
-  HRESULT hr = deviceEnumerator_->EnumAudioEndpoints( eCapture, DEVICE_STATE_ACTIVE, &captureDevices );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve capture device collection.";
-    goto Exit;
-  }
-
-  hr = captureDevices->GetCount( &captureDeviceCount );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve capture device count.";
-    goto Exit;
-  }
-
-  // Count render devices
-  hr = deviceEnumerator_->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &renderDevices );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve render device collection.";
-    goto Exit;
-  }
-
-  hr = renderDevices->GetCount( &renderDeviceCount );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve render device count.";
-    goto Exit;
-  }
-
-Exit:
-  // release all references
-  SAFE_RELEASE( captureDevices );
-  SAFE_RELEASE( renderDevices );
-
-  if ( errorText_.empty() )
-    return captureDeviceCount + renderDeviceCount;
-
-  error( RtAudioError::DRIVER_ERROR );
-  return 0;
-}
-
-//-----------------------------------------------------------------------------
-
-RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
-{
-  RtAudio::DeviceInfo info;
-  unsigned int captureDeviceCount = 0;
-  unsigned int renderDeviceCount = 0;
-  std::string defaultDeviceName;
-  bool isCaptureDevice = false;
-
-  PROPVARIANT deviceNameProp;
-  PROPVARIANT defaultDeviceNameProp;
-
-  IMMDeviceCollection* captureDevices = NULL;
-  IMMDeviceCollection* renderDevices = NULL;
-  IMMDevice* devicePtr = NULL;
-  IMMDevice* defaultDevicePtr = NULL;
-  IAudioClient* audioClient = NULL;
-  IPropertyStore* devicePropStore = NULL;
-  IPropertyStore* defaultDevicePropStore = NULL;
-
-  WAVEFORMATEX* deviceFormat = NULL;
-  WAVEFORMATEX* closestMatchFormat = NULL;
-
-  // probed
-  info.probed = false;
-
-  // Count capture devices
-  errorText_.clear();
-  RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR;
-  HRESULT hr = deviceEnumerator_->EnumAudioEndpoints( eCapture, DEVICE_STATE_ACTIVE, &captureDevices );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device collection.";
-    goto Exit;
-  }
-
-  hr = captureDevices->GetCount( &captureDeviceCount );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device count.";
-    goto Exit;
-  }
-
-  // Count render devices
-  hr = deviceEnumerator_->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &renderDevices );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device collection.";
-    goto Exit;
-  }
-
-  hr = renderDevices->GetCount( &renderDeviceCount );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device count.";
-    goto Exit;
-  }
-
-  // validate device index
-  if ( device >= captureDeviceCount + renderDeviceCount ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Invalid device index.";
-    errorType = RtAudioError::INVALID_USE;
-    goto Exit;
-  }
-
-  // determine whether index falls within capture or render devices
-  if ( device >= renderDeviceCount ) {
-    hr = captureDevices->Item( device - renderDeviceCount, &devicePtr );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device handle.";
-      goto Exit;
-    }
-    isCaptureDevice = true;
-  }
-  else {
-    hr = renderDevices->Item( device, &devicePtr );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device handle.";
-      goto Exit;
-    }
-    isCaptureDevice = false;
-  }
-
-  // get default device name
-  if ( isCaptureDevice ) {
-    hr = deviceEnumerator_->GetDefaultAudioEndpoint( eCapture, eConsole, &defaultDevicePtr );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default capture device handle.";
-      goto Exit;
-    }
-  }
-  else {
-    hr = deviceEnumerator_->GetDefaultAudioEndpoint( eRender, eConsole, &defaultDevicePtr );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default render device handle.";
-      goto Exit;
-    }
-  }
-
-  hr = defaultDevicePtr->OpenPropertyStore( STGM_READ, &defaultDevicePropStore );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to open default device property store.";
-    goto Exit;
-  }
-  PropVariantInit( &defaultDeviceNameProp );
-
-  hr = defaultDevicePropStore->GetValue( PKEY_Device_FriendlyName, &defaultDeviceNameProp );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default device property: PKEY_Device_FriendlyName.";
-    goto Exit;
-  }
-
-  defaultDeviceName = convertCharPointerToStdString(defaultDeviceNameProp.pwszVal);
-
-  // name
-  hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to open device property store.";
-    goto Exit;
-  }
-
-  PropVariantInit( &deviceNameProp );
-
-  hr = devicePropStore->GetValue( PKEY_Device_FriendlyName, &deviceNameProp );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device property: PKEY_Device_FriendlyName.";
-    goto Exit;
-  }
-
-  info.name =convertCharPointerToStdString(deviceNameProp.pwszVal);
-
-  // is default
-  if ( isCaptureDevice ) {
-    info.isDefaultInput = info.name == defaultDeviceName;
-    info.isDefaultOutput = false;
-  }
-  else {
-    info.isDefaultInput = false;
-    info.isDefaultOutput = info.name == defaultDeviceName;
-  }
-
-  // channel count
-  hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL, NULL, ( void** ) &audioClient );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device audio client.";
-    goto Exit;
-  }
-
-  hr = audioClient->GetMixFormat( &deviceFormat );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device mix format.";
-    goto Exit;
-  }
-
-  if ( isCaptureDevice ) {
-    info.inputChannels = deviceFormat->nChannels;
-    info.outputChannels = 0;
-    info.duplexChannels = 0;
-  }
-  else {
-    info.inputChannels = 0;
-    info.outputChannels = deviceFormat->nChannels;
-    info.duplexChannels = 0;
-  }
-
-  // sample rates
-  info.sampleRates.clear();
-
-  // allow support for all sample rates as we have a built-in sample rate converter
-  for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) {
-    info.sampleRates.push_back( SAMPLE_RATES[i] );
-  }
-  info.preferredSampleRate = deviceFormat->nSamplesPerSec;
-
-  // native format
-  info.nativeFormats = 0;
-
-  if ( deviceFormat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
-       ( deviceFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
-         ( ( WAVEFORMATEXTENSIBLE* ) deviceFormat )->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT ) )
-  {
-    if ( deviceFormat->wBitsPerSample == 32 ) {
-      info.nativeFormats |= RTAUDIO_FLOAT32;
-    }
-    else if ( deviceFormat->wBitsPerSample == 64 ) {
-      info.nativeFormats |= RTAUDIO_FLOAT64;
-    }
-  }
-  else if ( deviceFormat->wFormatTag == WAVE_FORMAT_PCM ||
-           ( deviceFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
-             ( ( WAVEFORMATEXTENSIBLE* ) deviceFormat )->SubFormat == KSDATAFORMAT_SUBTYPE_PCM ) )
-  {
-    if ( deviceFormat->wBitsPerSample == 8 ) {
-      info.nativeFormats |= RTAUDIO_SINT8;
-    }
-    else if ( deviceFormat->wBitsPerSample == 16 ) {
-      info.nativeFormats |= RTAUDIO_SINT16;
-    }
-    else if ( deviceFormat->wBitsPerSample == 24 ) {
-      info.nativeFormats |= RTAUDIO_SINT24;
-    }
-    else if ( deviceFormat->wBitsPerSample == 32 ) {
-      info.nativeFormats |= RTAUDIO_SINT32;
-    }
-  }
-
-  // probed
-  info.probed = true;
-
-Exit:
-  // release all references
-  PropVariantClear( &deviceNameProp );
-  PropVariantClear( &defaultDeviceNameProp );
-
-  SAFE_RELEASE( captureDevices );
-  SAFE_RELEASE( renderDevices );
-  SAFE_RELEASE( devicePtr );
-  SAFE_RELEASE( defaultDevicePtr );
-  SAFE_RELEASE( audioClient );
-  SAFE_RELEASE( devicePropStore );
-  SAFE_RELEASE( defaultDevicePropStore );
-
-  CoTaskMemFree( deviceFormat );
-  CoTaskMemFree( closestMatchFormat );
-
-  if ( !errorText_.empty() )
-    error( errorType );
-  return info;
-}
-
-//-----------------------------------------------------------------------------
-
-unsigned int RtApiWasapi::getDefaultOutputDevice( void )
-{
-  for ( unsigned int i = 0; i < getDeviceCount(); i++ ) {
-    if ( getDeviceInfo( i ).isDefaultOutput ) {
-      return i;
-    }
-  }
-
-  return 0;
-}
-
-//-----------------------------------------------------------------------------
-
-unsigned int RtApiWasapi::getDefaultInputDevice( void )
-{
-  for ( unsigned int i = 0; i < getDeviceCount(); i++ ) {
-    if ( getDeviceInfo( i ).isDefaultInput ) {
-      return i;
-    }
-  }
-
-  return 0;
-}
-
-//-----------------------------------------------------------------------------
-
-void RtApiWasapi::closeStream( void )
-{
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiWasapi::closeStream: No open stream to close.";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  if ( stream_.state != STREAM_STOPPED )
-    stopStream();
-
-  // clean up stream memory
-  SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient )
-  SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient )
-
-  SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->captureClient )
-  SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->renderClient )
-
-  if ( ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent )
-    CloseHandle( ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent );
-
-  if ( ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent )
-    CloseHandle( ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent );
-
-  delete ( WasapiHandle* ) stream_.apiHandle;
-  stream_.apiHandle = NULL;
-
-  for ( int i = 0; i < 2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  // update stream state
-  stream_.state = STREAM_CLOSED;
-}
-
-//-----------------------------------------------------------------------------
-
-void RtApiWasapi::startStream( void )
-{
-  verifyStream();
-
-  if ( stream_.state == STREAM_RUNNING ) {
-    errorText_ = "RtApiWasapi::startStream: The stream is already running.";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  #if defined( HAVE_GETTIMEOFDAY )
-  gettimeofday( &stream_.lastTickTimestamp, NULL );
-  #endif
-
-  // update stream state
-  stream_.state = STREAM_RUNNING;
-
-  // create WASAPI stream thread
-  stream_.callbackInfo.thread = ( ThreadHandle ) CreateThread( NULL, 0, runWasapiThread, this, CREATE_SUSPENDED, NULL );
-
-  if ( !stream_.callbackInfo.thread ) {
-    errorText_ = "RtApiWasapi::startStream: Unable to instantiate callback thread.";
-    error( RtAudioError::THREAD_ERROR );
-  }
-  else {
-    SetThreadPriority( ( void* ) stream_.callbackInfo.thread, stream_.callbackInfo.priority );
-    ResumeThread( ( void* ) stream_.callbackInfo.thread );
-  }
-}
-
-//-----------------------------------------------------------------------------
-
-void RtApiWasapi::stopStream( void )
-{
-  verifyStream();
-
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiWasapi::stopStream: The stream is already stopped.";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  // inform stream thread by setting stream state to STREAM_STOPPING
-  stream_.state = STREAM_STOPPING;
-
-  // wait until stream thread is stopped
-  while( stream_.state != STREAM_STOPPED ) {
-    Sleep( 1 );
-  }
-
-  // Wait for the last buffer to play before stopping.
-  Sleep( 1000 * stream_.bufferSize / stream_.sampleRate );
-
-  // close thread handle
-  if ( stream_.callbackInfo.thread && !CloseHandle( ( void* ) stream_.callbackInfo.thread ) ) {
-    errorText_ = "RtApiWasapi::stopStream: Unable to close callback thread.";
-    error( RtAudioError::THREAD_ERROR );
-    return;
-  }
-
-  stream_.callbackInfo.thread = (ThreadHandle) NULL;
-}
-
-//-----------------------------------------------------------------------------
-
-void RtApiWasapi::abortStream( void )
-{
-  verifyStream();
-
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiWasapi::abortStream: The stream is already stopped.";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  // inform stream thread by setting stream state to STREAM_STOPPING
-  stream_.state = STREAM_STOPPING;
-
-  // wait until stream thread is stopped
-  while ( stream_.state != STREAM_STOPPED ) {
-    Sleep( 1 );
-  }
-
-  // close thread handle
-  if ( stream_.callbackInfo.thread && !CloseHandle( ( void* ) stream_.callbackInfo.thread ) ) {
-    errorText_ = "RtApiWasapi::abortStream: Unable to close callback thread.";
-    error( RtAudioError::THREAD_ERROR );
-    return;
-  }
-
-  stream_.callbackInfo.thread = (ThreadHandle) NULL;
-}
-
-//-----------------------------------------------------------------------------
-
-bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
-                                   unsigned int firstChannel, unsigned int sampleRate,
-                                   RtAudioFormat format, unsigned int* bufferSize,
-                                   RtAudio::StreamOptions* options )
-{
-  bool methodResult = FAILURE;
-  unsigned int captureDeviceCount = 0;
-  unsigned int renderDeviceCount = 0;
-
-  IMMDeviceCollection* captureDevices = NULL;
-  IMMDeviceCollection* renderDevices = NULL;
-  IMMDevice* devicePtr = NULL;
-  WAVEFORMATEX* deviceFormat = NULL;
-  unsigned int bufferBytes;
-  stream_.state = STREAM_STOPPED;
-
-  // create API Handle if not already created
-  if ( !stream_.apiHandle )
-    stream_.apiHandle = ( void* ) new WasapiHandle();
-
-  // Count capture devices
-  errorText_.clear();
-  RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR;
-  HRESULT hr = deviceEnumerator_->EnumAudioEndpoints( eCapture, DEVICE_STATE_ACTIVE, &captureDevices );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device collection.";
-    goto Exit;
-  }
-
-  hr = captureDevices->GetCount( &captureDeviceCount );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device count.";
-    goto Exit;
-  }
-
-  // Count render devices
-  hr = deviceEnumerator_->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &renderDevices );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device collection.";
-    goto Exit;
-  }
-
-  hr = renderDevices->GetCount( &renderDeviceCount );
-  if ( FAILED( hr ) ) {
-    errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device count.";
-    goto Exit;
-  }
-
-  // validate device index
-  if ( device >= captureDeviceCount + renderDeviceCount ) {
-    errorType = RtAudioError::INVALID_USE;
-    errorText_ = "RtApiWasapi::probeDeviceOpen: Invalid device index.";
-    goto Exit;
-  }
-
-  // if device index falls within capture devices
-  if ( device >= renderDeviceCount ) {
-    if ( mode != INPUT ) {
-      errorType = RtAudioError::INVALID_USE;
-      errorText_ = "RtApiWasapi::probeDeviceOpen: Capture device selected as output device.";
-      goto Exit;
-    }
-
-    // retrieve captureAudioClient from devicePtr
-    IAudioClient*& captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
-
-    hr = captureDevices->Item( device - renderDeviceCount, &devicePtr );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device handle.";
-      goto Exit;
-    }
-
-    hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL,
-                              NULL, ( void** ) &captureAudioClient );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device audio client.";
-      goto Exit;
-    }
-
-    hr = captureAudioClient->GetMixFormat( &deviceFormat );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device mix format.";
-      goto Exit;
-    }
-
-    stream_.nDeviceChannels[mode] = deviceFormat->nChannels;
-    captureAudioClient->GetStreamLatency( ( long long* ) &stream_.latency[mode] );
-  }
-
-  // if device index falls within render devices and is configured for loopback
-  if ( device < renderDeviceCount && mode == INPUT )
-  {
-    // if renderAudioClient is not initialised, initialise it now
-    IAudioClient*& renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
-    if ( !renderAudioClient )
-    {
-      probeDeviceOpen( device, OUTPUT, channels, firstChannel, sampleRate, format, bufferSize, options );
-    }
-
-    // retrieve captureAudioClient from devicePtr
-    IAudioClient*& captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
-
-    hr = renderDevices->Item( device, &devicePtr );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device handle.";
-      goto Exit;
-    }
-
-    hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL,
-                              NULL, ( void** ) &captureAudioClient );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device audio client.";
-      goto Exit;
-    }
-
-    hr = captureAudioClient->GetMixFormat( &deviceFormat );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device mix format.";
-      goto Exit;
-    }
-
-    stream_.nDeviceChannels[mode] = deviceFormat->nChannels;
-    captureAudioClient->GetStreamLatency( ( long long* ) &stream_.latency[mode] );
-  }
-
-  // if device index falls within render devices and is configured for output
-  if ( device < renderDeviceCount && mode == OUTPUT )
-  {
-    // if renderAudioClient is already initialised, don't initialise it again
-    IAudioClient*& renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
-    if ( renderAudioClient )
-    {
-      methodResult = SUCCESS;
-      goto Exit;
-    }
-
-    hr = renderDevices->Item( device, &devicePtr );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device handle.";
-      goto Exit;
-    }
-
-    hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL,
-                              NULL, ( void** ) &renderAudioClient );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device audio client.";
-      goto Exit;
-    }
-
-    hr = renderAudioClient->GetMixFormat( &deviceFormat );
-    if ( FAILED( hr ) ) {
-      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device mix format.";
-      goto Exit;
-    }
-
-    stream_.nDeviceChannels[mode] = deviceFormat->nChannels;
-    renderAudioClient->GetStreamLatency( ( long long* ) &stream_.latency[mode] );
-  }
-
-  // fill stream data
-  if ( ( stream_.mode == OUTPUT && mode == INPUT ) ||
-       ( stream_.mode == INPUT && mode == OUTPUT ) ) {
-    stream_.mode = DUPLEX;
-  }
-  else {
-    stream_.mode = mode;
-  }
-
-  stream_.device[mode] = device;
-  stream_.doByteSwap[mode] = false;
-  stream_.sampleRate = sampleRate;
-  stream_.bufferSize = *bufferSize;
-  stream_.nBuffers = 1;
-  stream_.nUserChannels[mode] = channels;
-  stream_.channelOffset[mode] = firstChannel;
-  stream_.userFormat = format;
-  stream_.deviceFormat[mode] = getDeviceInfo( device ).nativeFormats;
-
-  if ( options && options->flags & RTAUDIO_NONINTERLEAVED )
-    stream_.userInterleaved = false;
-  else
-    stream_.userInterleaved = true;
-  stream_.deviceInterleaved[mode] = true;
-
-  // Set flags for buffer conversion.
-  stream_.doConvertBuffer[mode] = false;
-  if ( stream_.userFormat != stream_.deviceFormat[mode] ||
-       stream_.nUserChannels[0] != stream_.nDeviceChannels[0] ||
-       stream_.nUserChannels[1] != stream_.nDeviceChannels[1] )
-    stream_.doConvertBuffer[mode] = true;
-  else if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
-            stream_.nUserChannels[mode] > 1 )
-    stream_.doConvertBuffer[mode] = true;
-
-  if ( stream_.doConvertBuffer[mode] )
-    setConvertInfo( mode, 0 );
-
-  // Allocate necessary internal buffers
-  bufferBytes = stream_.nUserChannels[mode] * stream_.bufferSize * formatBytes( stream_.userFormat );
-
-  stream_.userBuffer[mode] = ( char* ) calloc( bufferBytes, 1 );
-  if ( !stream_.userBuffer[mode] ) {
-    errorType = RtAudioError::MEMORY_ERROR;
-    errorText_ = "RtApiWasapi::probeDeviceOpen: Error allocating user buffer memory.";
-    goto Exit;
-  }
-
-  if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME )
-    stream_.callbackInfo.priority = 15;
-  else
-    stream_.callbackInfo.priority = 0;
-
-  ///! TODO: RTAUDIO_MINIMIZE_LATENCY // Provide stream buffers directly to callback
-  ///! TODO: RTAUDIO_HOG_DEVICE       // Exclusive mode
-
-  methodResult = SUCCESS;
-
-Exit:
-  //clean up
-  SAFE_RELEASE( captureDevices );
-  SAFE_RELEASE( renderDevices );
-  SAFE_RELEASE( devicePtr );
-  CoTaskMemFree( deviceFormat );
-
-  // if method failed, close the stream
-  if ( methodResult == FAILURE )
-    closeStream();
-
-  if ( !errorText_.empty() )
-    error( errorType );
-  return methodResult;
-}
-
-//=============================================================================
-
-DWORD WINAPI RtApiWasapi::runWasapiThread( void* wasapiPtr )
-{
-  if ( wasapiPtr )
-    ( ( RtApiWasapi* ) wasapiPtr )->wasapiThread();
-
-  return 0;
-}
-
-DWORD WINAPI RtApiWasapi::stopWasapiThread( void* wasapiPtr )
-{
-  if ( wasapiPtr )
-    ( ( RtApiWasapi* ) wasapiPtr )->stopStream();
-
-  return 0;
-}
-
-DWORD WINAPI RtApiWasapi::abortWasapiThread( void* wasapiPtr )
-{
-  if ( wasapiPtr )
-    ( ( RtApiWasapi* ) wasapiPtr )->abortStream();
-
-  return 0;
-}
-
-//-----------------------------------------------------------------------------
-
-void RtApiWasapi::wasapiThread()
-{
-  // as this is a new thread, we must CoInitialize it
-  CoInitialize( NULL );
-
-  HRESULT hr;
-
-  IAudioClient* captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
-  IAudioClient* renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
-  IAudioCaptureClient* captureClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureClient;
-  IAudioRenderClient* renderClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderClient;
-  HANDLE captureEvent = ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent;
-  HANDLE renderEvent = ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent;
-
-  WAVEFORMATEX* captureFormat = NULL;
-  WAVEFORMATEX* renderFormat = NULL;
-  float captureSrRatio = 0.0f;
-  float renderSrRatio = 0.0f;
-  WasapiBuffer captureBuffer;
-  WasapiBuffer renderBuffer;
-  WasapiResampler* captureResampler = NULL;
-  WasapiResampler* renderResampler = NULL;
-
-  // declare local stream variables
-  RtAudioCallback callback = ( RtAudioCallback ) stream_.callbackInfo.callback;
-  BYTE* streamBuffer = NULL;
-  unsigned long captureFlags = 0;
-  unsigned int bufferFrameCount = 0;
-  unsigned int numFramesPadding = 0;
-  unsigned int convBufferSize = 0;
-  bool loopbackEnabled = stream_.device[INPUT] == stream_.device[OUTPUT];
-  bool callbackPushed = true;
-  bool callbackPulled = false;
-  bool callbackStopped = false;
-  int callbackResult = 0;
-
-  // convBuffer is used to store converted buffers between WASAPI and the user
-  char* convBuffer = NULL;
-  unsigned int convBuffSize = 0;
-  unsigned int deviceBuffSize = 0;
-
-  std::string errorText;
-  RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR;
-
-  // Attempt to assign "Pro Audio" characteristic to thread
-  HMODULE AvrtDll = LoadLibrary( (LPCTSTR) "AVRT.dll" );
-  if ( AvrtDll ) {
-    DWORD taskIndex = 0;
-    TAvSetMmThreadCharacteristicsPtr AvSetMmThreadCharacteristicsPtr =
-      ( TAvSetMmThreadCharacteristicsPtr ) (void(*)()) GetProcAddress( AvrtDll, "AvSetMmThreadCharacteristicsW" );
-    AvSetMmThreadCharacteristicsPtr( L"Pro Audio", &taskIndex );
-    FreeLibrary( AvrtDll );
-  }
-
-  // start capture stream if applicable
-  if ( captureAudioClient ) {
-    hr = captureAudioClient->GetMixFormat( &captureFormat );
-    if ( FAILED( hr ) ) {
-      errorText = "RtApiWasapi::wasapiThread: Unable to retrieve device mix format.";
-      goto Exit;
-    }
-
-    // init captureResampler
-    captureResampler = new WasapiResampler( stream_.deviceFormat[INPUT] == RTAUDIO_FLOAT32 || stream_.deviceFormat[INPUT] == RTAUDIO_FLOAT64,
-                                            formatBytes( stream_.deviceFormat[INPUT] ) * 8, stream_.nDeviceChannels[INPUT],
-                                            captureFormat->nSamplesPerSec, stream_.sampleRate );
-
-    captureSrRatio = ( ( float ) captureFormat->nSamplesPerSec / stream_.sampleRate );
-
-    if ( !captureClient ) {
-      hr = captureAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED,
-                                           loopbackEnabled ? AUDCLNT_STREAMFLAGS_LOOPBACK : AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
-                                           0,
-                                           0,
-                                           captureFormat,
-                                           NULL );
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to initialize capture audio client.";
-        goto Exit;
-      }
-
-      hr = captureAudioClient->GetService( __uuidof( IAudioCaptureClient ),
-                                           ( void** ) &captureClient );
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to retrieve capture client handle.";
-        goto Exit;
-      }
-
-      // don't configure captureEvent if in loopback mode
-      if ( !loopbackEnabled )
-      {
-        // configure captureEvent to trigger on every available capture buffer
-        captureEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
-        if ( !captureEvent ) {
-          errorType = RtAudioError::SYSTEM_ERROR;
-          errorText = "RtApiWasapi::wasapiThread: Unable to create capture event.";
-          goto Exit;
-        }
-
-        hr = captureAudioClient->SetEventHandle( captureEvent );
-        if ( FAILED( hr ) ) {
-          errorText = "RtApiWasapi::wasapiThread: Unable to set capture event handle.";
-          goto Exit;
-        }
-
-        ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent = captureEvent;
-      }
-
-      ( ( WasapiHandle* ) stream_.apiHandle )->captureClient = captureClient;
-
-      // reset the capture stream
-      hr = captureAudioClient->Reset();
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to reset capture stream.";
-        goto Exit;
-      }
-
-      // start the capture stream
-      hr = captureAudioClient->Start();
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to start capture stream.";
-        goto Exit;
-      }
-    }
-
-    unsigned int inBufferSize = 0;
-    hr = captureAudioClient->GetBufferSize( &inBufferSize );
-    if ( FAILED( hr ) ) {
-      errorText = "RtApiWasapi::wasapiThread: Unable to get capture buffer size.";
-      goto Exit;
-    }
-
-    // scale outBufferSize according to stream->user sample rate ratio
-    unsigned int outBufferSize = ( unsigned int ) ceilf( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT];
-    inBufferSize *= stream_.nDeviceChannels[INPUT];
-
-    // set captureBuffer size
-    captureBuffer.setBufferSize( inBufferSize + outBufferSize, formatBytes( stream_.deviceFormat[INPUT] ) );
-  }
-
-  // start render stream if applicable
-  if ( renderAudioClient ) {
-    hr = renderAudioClient->GetMixFormat( &renderFormat );
-    if ( FAILED( hr ) ) {
-      errorText = "RtApiWasapi::wasapiThread: Unable to retrieve device mix format.";
-      goto Exit;
-    }
-
-    // init renderResampler
-    renderResampler = new WasapiResampler( stream_.deviceFormat[OUTPUT] == RTAUDIO_FLOAT32 || stream_.deviceFormat[OUTPUT] == RTAUDIO_FLOAT64,
-                                           formatBytes( stream_.deviceFormat[OUTPUT] ) * 8, stream_.nDeviceChannels[OUTPUT],
-                                           stream_.sampleRate, renderFormat->nSamplesPerSec );
-
-    renderSrRatio = ( ( float ) renderFormat->nSamplesPerSec / stream_.sampleRate );
-
-    if ( !renderClient ) {
-      hr = renderAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED,
-                                          AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
-                                          0,
-                                          0,
-                                          renderFormat,
-                                          NULL );
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to initialize render audio client.";
-        goto Exit;
-      }
-
-      hr = renderAudioClient->GetService( __uuidof( IAudioRenderClient ),
-                                          ( void** ) &renderClient );
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to retrieve render client handle.";
-        goto Exit;
-      }
-
-      // configure renderEvent to trigger on every available render buffer
-      renderEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
-      if ( !renderEvent ) {
-        errorType = RtAudioError::SYSTEM_ERROR;
-        errorText = "RtApiWasapi::wasapiThread: Unable to create render event.";
-        goto Exit;
-      }
-
-      hr = renderAudioClient->SetEventHandle( renderEvent );
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to set render event handle.";
-        goto Exit;
-      }
-
-      ( ( WasapiHandle* ) stream_.apiHandle )->renderClient = renderClient;
-      ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent = renderEvent;
-
-      // reset the render stream
-      hr = renderAudioClient->Reset();
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to reset render stream.";
-        goto Exit;
-      }
-
-      // start the render stream
-      hr = renderAudioClient->Start();
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to start render stream.";
-        goto Exit;
-      }
-    }
-
-    unsigned int outBufferSize = 0;
-    hr = renderAudioClient->GetBufferSize( &outBufferSize );
-    if ( FAILED( hr ) ) {
-      errorText = "RtApiWasapi::wasapiThread: Unable to get render buffer size.";
-      goto Exit;
-    }
-
-    // scale inBufferSize according to user->stream sample rate ratio
-    unsigned int inBufferSize = ( unsigned int ) ceilf( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT];
-    outBufferSize *= stream_.nDeviceChannels[OUTPUT];
-
-    // set renderBuffer size
-    renderBuffer.setBufferSize( inBufferSize + outBufferSize, formatBytes( stream_.deviceFormat[OUTPUT] ) );
-  }
-
-  // malloc buffer memory
-  if ( stream_.mode == INPUT )
-  {
-    using namespace std; // for ceilf
-    convBuffSize = ( size_t ) ( ceilf( stream_.bufferSize * captureSrRatio ) ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] );
-    deviceBuffSize = stream_.bufferSize * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] );
-  }
-  else if ( stream_.mode == OUTPUT )
-  {
-    convBuffSize = ( size_t ) ( ceilf( stream_.bufferSize * renderSrRatio ) ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] );
-    deviceBuffSize = stream_.bufferSize * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] );
-  }
-  else if ( stream_.mode == DUPLEX )
-  {
-    convBuffSize = std::max( ( size_t ) ( ceilf( stream_.bufferSize * captureSrRatio ) ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ),
-                             ( size_t ) ( ceilf( stream_.bufferSize * renderSrRatio ) ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) );
-    deviceBuffSize = std::max( stream_.bufferSize * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ),
-                               stream_.bufferSize * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) );
-  }
-
-  convBuffSize *= 2; // allow overflow for *SrRatio remainders
-  convBuffer = ( char* ) calloc( convBuffSize, 1 );
-  stream_.deviceBuffer = ( char* ) calloc( deviceBuffSize, 1 );
-  if ( !convBuffer || !stream_.deviceBuffer ) {
-    errorType = RtAudioError::MEMORY_ERROR;
-    errorText = "RtApiWasapi::wasapiThread: Error allocating device buffer memory.";
-    goto Exit;
-  }
-
-  // stream process loop
-  while ( stream_.state != STREAM_STOPPING ) {
-    if ( !callbackPulled ) {
-      // Callback Input
-      // ==============
-      // 1. Pull callback buffer from inputBuffer
-      // 2. If 1. was successful: Convert callback buffer to user sample rate and channel count
-      //                          Convert callback buffer to user format
-
-      if ( captureAudioClient )
-      {
-        int samplesToPull = ( unsigned int ) floorf( stream_.bufferSize * captureSrRatio );
-        if ( captureSrRatio != 1 )
-        {
-          // account for remainders
-          samplesToPull--;
-        }
-
-        convBufferSize = 0;
-        while ( convBufferSize < stream_.bufferSize )
-        {
-          // Pull callback buffer from inputBuffer
-          callbackPulled = captureBuffer.pullBuffer( convBuffer,
-                                                     samplesToPull * stream_.nDeviceChannels[INPUT],
-                                                     stream_.deviceFormat[INPUT] );
-
-          if ( !callbackPulled )
-          {
-            break;
-          }
-
-          // Convert callback buffer to user sample rate
-          unsigned int deviceBufferOffset = convBufferSize * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] );
-          unsigned int convSamples = 0;
-
-          captureResampler->Convert( stream_.deviceBuffer + deviceBufferOffset,
-                                     convBuffer,
-                                     samplesToPull,
-                                     convSamples );
-
-          convBufferSize += convSamples;
-          samplesToPull = 1; // now pull one sample at a time until we have stream_.bufferSize samples
-        }
-
-        if ( callbackPulled )
-        {
-          if ( stream_.doConvertBuffer[INPUT] ) {
-            // Convert callback buffer to user format
-            convertBuffer( stream_.userBuffer[INPUT],
-                           stream_.deviceBuffer,
-                           stream_.convertInfo[INPUT] );
-          }
-          else {
-            // no further conversion, simple copy deviceBuffer to userBuffer
-            memcpy( stream_.userBuffer[INPUT],
-                    stream_.deviceBuffer,
-                    stream_.bufferSize * stream_.nUserChannels[INPUT] * formatBytes( stream_.userFormat ) );
-          }
-        }
-      }
-      else {
-        // if there is no capture stream, set callbackPulled flag
-        callbackPulled = true;
-      }
-
-      // Execute Callback
-      // ================
-      // 1. Execute user callback method
-      // 2. Handle return value from callback
-
-      // if callback has not requested the stream to stop
-      if ( callbackPulled && !callbackStopped ) {
-        // Execute user callback method
-        callbackResult = callback( stream_.userBuffer[OUTPUT],
-                                   stream_.userBuffer[INPUT],
-                                   stream_.bufferSize,
-                                   getStreamTime(),
-                                   captureFlags & AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY ? RTAUDIO_INPUT_OVERFLOW : 0,
-                                   stream_.callbackInfo.userData );
-
-        // tick stream time
-        RtApi::tickStreamTime();
-
-        // Handle return value from callback
-        if ( callbackResult == 1 ) {
-          // instantiate a thread to stop this thread
-          HANDLE threadHandle = CreateThread( NULL, 0, stopWasapiThread, this, 0, NULL );
-          if ( !threadHandle ) {
-            errorType = RtAudioError::THREAD_ERROR;
-            errorText = "RtApiWasapi::wasapiThread: Unable to instantiate stream stop thread.";
-            goto Exit;
-          }
-          else if ( !CloseHandle( threadHandle ) ) {
-            errorType = RtAudioError::THREAD_ERROR;
-            errorText = "RtApiWasapi::wasapiThread: Unable to close stream stop thread handle.";
-            goto Exit;
-          }
-
-          callbackStopped = true;
-        }
-        else if ( callbackResult == 2 ) {
-          // instantiate a thread to stop this thread
-          HANDLE threadHandle = CreateThread( NULL, 0, abortWasapiThread, this, 0, NULL );
-          if ( !threadHandle ) {
-            errorType = RtAudioError::THREAD_ERROR;
-            errorText = "RtApiWasapi::wasapiThread: Unable to instantiate stream abort thread.";
-            goto Exit;
-          }
-          else if ( !CloseHandle( threadHandle ) ) {
-            errorType = RtAudioError::THREAD_ERROR;
-            errorText = "RtApiWasapi::wasapiThread: Unable to close stream abort thread handle.";
-            goto Exit;
-          }
-
-          callbackStopped = true;
-        }
-      }
-    }
-
-    // Callback Output
-    // ===============
-    // 1. Convert callback buffer to stream format
-    // 2. Convert callback buffer to stream sample rate and channel count
-    // 3. Push callback buffer into outputBuffer
-
-    if ( renderAudioClient && callbackPulled )
-    {
-      // if the last call to renderBuffer.PushBuffer() was successful
-      if ( callbackPushed || convBufferSize == 0 )
-      {
-        if ( stream_.doConvertBuffer[OUTPUT] )
-        {
-          // Convert callback buffer to stream format
-          convertBuffer( stream_.deviceBuffer,
-                         stream_.userBuffer[OUTPUT],
-                         stream_.convertInfo[OUTPUT] );
-
-        }
-        else {
-          // no further conversion, simple copy userBuffer to deviceBuffer
-          memcpy( stream_.deviceBuffer,
-                  stream_.userBuffer[OUTPUT],
-                  stream_.bufferSize * stream_.nUserChannels[OUTPUT] * formatBytes( stream_.userFormat ) );
-        }
-
-        // Convert callback buffer to stream sample rate
-        renderResampler->Convert( convBuffer,
-                                  stream_.deviceBuffer,
-                                  stream_.bufferSize,
-                                  convBufferSize );
-      }
-
-      // Push callback buffer into outputBuffer
-      callbackPushed = renderBuffer.pushBuffer( convBuffer,
-                                                convBufferSize * stream_.nDeviceChannels[OUTPUT],
-                                                stream_.deviceFormat[OUTPUT] );
-    }
-    else {
-      // if there is no render stream, set callbackPushed flag
-      callbackPushed = true;
-    }
-
-    // Stream Capture
-    // ==============
-    // 1. Get capture buffer from stream
-    // 2. Push capture buffer into inputBuffer
-    // 3. If 2. was successful: Release capture buffer
-
-    if ( captureAudioClient ) {
-      // if the callback input buffer was not pulled from captureBuffer, wait for next capture event
-      if ( !callbackPulled ) {
-        WaitForSingleObject( loopbackEnabled ? renderEvent : captureEvent, INFINITE );
-      }
-
-      // Get capture buffer from stream
-      hr = captureClient->GetBuffer( &streamBuffer,
-                                     &bufferFrameCount,
-                                     &captureFlags, NULL, NULL );
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to retrieve capture buffer.";
-        goto Exit;
-      }
-
-      if ( bufferFrameCount != 0 ) {
-        // Push capture buffer into inputBuffer
-        if ( captureBuffer.pushBuffer( ( char* ) streamBuffer,
-                                       bufferFrameCount * stream_.nDeviceChannels[INPUT],
-                                       stream_.deviceFormat[INPUT] ) )
-        {
-          // Release capture buffer
-          hr = captureClient->ReleaseBuffer( bufferFrameCount );
-          if ( FAILED( hr ) ) {
-            errorText = "RtApiWasapi::wasapiThread: Unable to release capture buffer.";
-            goto Exit;
-          }
-        }
-        else
-        {
-          // Inform WASAPI that capture was unsuccessful
-          hr = captureClient->ReleaseBuffer( 0 );
-          if ( FAILED( hr ) ) {
-            errorText = "RtApiWasapi::wasapiThread: Unable to release capture buffer.";
-            goto Exit;
-          }
-        }
-      }
-      else
-      {
-        // Inform WASAPI that capture was unsuccessful
-        hr = captureClient->ReleaseBuffer( 0 );
-        if ( FAILED( hr ) ) {
-          errorText = "RtApiWasapi::wasapiThread: Unable to release capture buffer.";
-          goto Exit;
-        }
-      }
-    }
-
-    // Stream Render
-    // =============
-    // 1. Get render buffer from stream
-    // 2. Pull next buffer from outputBuffer
-    // 3. If 2. was successful: Fill render buffer with next buffer
-    //                          Release render buffer
-
-    if ( renderAudioClient ) {
-      // if the callback output buffer was not pushed to renderBuffer, wait for next render event
-      if ( callbackPulled && !callbackPushed ) {
-        WaitForSingleObject( renderEvent, INFINITE );
-      }
-
-      // Get render buffer from stream
-      hr = renderAudioClient->GetBufferSize( &bufferFrameCount );
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer size.";
-        goto Exit;
-      }
-
-      hr = renderAudioClient->GetCurrentPadding( &numFramesPadding );
-      if ( FAILED( hr ) ) {
-        errorText = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer padding.";
-        goto Exit;
-      }
-
-      bufferFrameCount -= numFramesPadding;
-
-      if ( bufferFrameCount != 0 ) {
-        hr = renderClient->GetBuffer( bufferFrameCount, &streamBuffer );
-        if ( FAILED( hr ) ) {
-          errorText = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer.";
-          goto Exit;
-        }
-
-        // Pull next buffer from outputBuffer
-        // Fill render buffer with next buffer
-        if ( renderBuffer.pullBuffer( ( char* ) streamBuffer,
-                                      bufferFrameCount * stream_.nDeviceChannels[OUTPUT],
-                                      stream_.deviceFormat[OUTPUT] ) )
-        {
-          // Release render buffer
-          hr = renderClient->ReleaseBuffer( bufferFrameCount, 0 );
-          if ( FAILED( hr ) ) {
-            errorText = "RtApiWasapi::wasapiThread: Unable to release render buffer.";
-            goto Exit;
-          }
-        }
-        else
-        {
-          // Inform WASAPI that render was unsuccessful
-          hr = renderClient->ReleaseBuffer( 0, 0 );
-          if ( FAILED( hr ) ) {
-            errorText = "RtApiWasapi::wasapiThread: Unable to release render buffer.";
-            goto Exit;
-          }
-        }
-      }
-      else
-      {
-        // Inform WASAPI that render was unsuccessful
-        hr = renderClient->ReleaseBuffer( 0, 0 );
-        if ( FAILED( hr ) ) {
-          errorText = "RtApiWasapi::wasapiThread: Unable to release render buffer.";
-          goto Exit;
-        }
-      }
-    }
-
-    // if the callback buffer was pushed renderBuffer reset callbackPulled flag
-    if ( callbackPushed ) {
-      // unsetting the callbackPulled flag lets the stream know that
-      // the audio device is ready for another callback output buffer.
-      callbackPulled = false;
-    }
-
-  }
-
-Exit:
-  // clean up
-  CoTaskMemFree( captureFormat );
-  CoTaskMemFree( renderFormat );
-
-  free ( convBuffer );
-  delete renderResampler;
-  delete captureResampler;
-
-  CoUninitialize();
-
-  // update stream state
-  stream_.state = STREAM_STOPPED;
-
-  if ( !errorText.empty() )
-  {
-    errorText_ = errorText;
-    error( errorType );
-  }
-}
-
-//******************** End of __WINDOWS_WASAPI__ *********************//
-#endif
-
-
-#if defined(__WINDOWS_DS__) // Windows DirectSound API
-
-// Modified by Robin Davies, October 2005
-// - Improvements to DirectX pointer chasing. 
-// - Bug fix for non-power-of-two Asio granularity used by Edirol PCR-A30.
-// - Auto-call CoInitialize for DSOUND and ASIO platforms.
-// Various revisions for RtAudio 4.0 by Gary Scavone, April 2007
-// Changed device query structure for RtAudio 4.0.7, January 2010
-
-#include <WinSock2.h>
-#include <Windows.h>
-#include <process.h>
-#include <mmsystem.h>
-#include <mmreg.h>
-#include <dsound.h>
-#include <assert.h>
-#include <algorithm>
-
-#if defined(__MINGW32__)
-  // missing from latest mingw winapi
-#define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */
-#define WAVE_FORMAT_96S08 0x00020000 /* 96 kHz, Stereo, 8-bit */
-#define WAVE_FORMAT_96M16 0x00040000 /* 96 kHz, Mono, 16-bit */
-#define WAVE_FORMAT_96S16 0x00080000 /* 96 kHz, Stereo, 16-bit */
-#endif
-
-#define MINIMUM_DEVICE_BUFFER_SIZE 32768
-
-#ifdef _MSC_VER // if Microsoft Visual C++
-#pragma comment( lib, "winmm.lib" ) // then, auto-link winmm.lib. Otherwise, it has to be added manually.
-#endif
-
-static inline DWORD dsPointerBetween( DWORD pointer, DWORD laterPointer, DWORD earlierPointer, DWORD bufferSize )
-{
-  if ( pointer > bufferSize ) pointer -= bufferSize;
-  if ( laterPointer < earlierPointer ) laterPointer += bufferSize;
-  if ( pointer < earlierPointer ) pointer += bufferSize;
-  return pointer >= earlierPointer && pointer < laterPointer;
-}
-
-// A structure to hold various information related to the DirectSound
-// API implementation.
-struct DsHandle {
-  unsigned int drainCounter; // Tracks callback counts when draining
-  bool internalDrain;        // Indicates if stop is initiated from callback or not.
-  void *id[2];
-  void *buffer[2];
-  bool xrun[2];
-  UINT bufferPointer[2];  
-  DWORD dsBufferSize[2];
-  DWORD dsPointerLeadTime[2]; // the number of bytes ahead of the safe pointer to lead by.
-  HANDLE condition;
-
-  DsHandle()
-    :drainCounter(0), internalDrain(false) { id[0] = 0; id[1] = 0; buffer[0] = 0; buffer[1] = 0; xrun[0] = false; xrun[1] = false; bufferPointer[0] = 0; bufferPointer[1] = 0; }
-};
-
-// Declarations for utility functions, callbacks, and structures
-// specific to the DirectSound implementation.
-static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
-                                          LPCTSTR description,
-                                          LPCTSTR module,
-                                          LPVOID lpContext );
-
-static const char* getErrorString( int code );
-
-static unsigned __stdcall callbackHandler( void *ptr );
-
-struct DsDevice {
-  LPGUID id[2];
-  bool validId[2];
-  bool found;
-  std::string name;
-
-  DsDevice()
-  : found(false) { validId[0] = false; validId[1] = false; }
-};
-
-struct DsProbeData {
-  bool isInput;
-  std::vector<struct DsDevice>* dsDevices;
-};
-
-RtApiDs :: RtApiDs()
-{
-  // Dsound will run both-threaded. If CoInitialize fails, then just
-  // accept whatever the mainline chose for a threading model.
-  coInitialized_ = false;
-  HRESULT hr = CoInitialize( NULL );
-  if ( !FAILED( hr ) ) coInitialized_ = true;
-}
-
-RtApiDs :: ~RtApiDs()
-{
-  if ( stream_.state != STREAM_CLOSED ) closeStream();
-  if ( coInitialized_ ) CoUninitialize(); // balanced call.
-}
-
-// The DirectSound default output is always the first device.
-unsigned int RtApiDs :: getDefaultOutputDevice( void )
-{
-  return 0;
-}
-
-// The DirectSound default input is always the first input device,
-// which is the first capture device enumerated.
-unsigned int RtApiDs :: getDefaultInputDevice( void )
-{
-  return 0;
-}
-
-unsigned int RtApiDs :: getDeviceCount( void )
-{
-  // Set query flag for previously found devices to false, so that we
-  // can check for any devices that have disappeared.
-  for ( unsigned int i=0; i<dsDevices.size(); i++ )
-    dsDevices[i].found = false;
-
-  // Query DirectSound devices.
-  struct DsProbeData probeInfo;
-  probeInfo.isInput = false;
-  probeInfo.dsDevices = &dsDevices;
-  HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &probeInfo );
-  if ( FAILED( result ) ) {
-    errorStream_ << "RtApiDs::getDeviceCount: error (" << getErrorString( result ) << ") enumerating output devices!";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-  }
-
-  // Query DirectSoundCapture devices.
-  probeInfo.isInput = true;
-  result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &probeInfo );
-  if ( FAILED( result ) ) {
-    errorStream_ << "RtApiDs::getDeviceCount: error (" << getErrorString( result ) << ") enumerating input devices!";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-  }
-
-  // Clean out any devices that may have disappeared (code update submitted by Eli Zehngut).
-  for ( unsigned int i=0; i<dsDevices.size(); ) {
-    if ( dsDevices[i].found == false ) dsDevices.erase( dsDevices.begin() + i );
-    else i++;
-  }
-
-  return static_cast<unsigned int>(dsDevices.size());
-}
-
-RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device )
-{
-  RtAudio::DeviceInfo info;
-  info.probed = false;
-
-  if ( dsDevices.size() == 0 ) {
-    // Force a query of all devices
-    getDeviceCount();
-    if ( dsDevices.size() == 0 ) {
-      errorText_ = "RtApiDs::getDeviceInfo: no devices found!";
-      error( RtAudioError::INVALID_USE );
-      return info;
-    }
-  }
-
-  if ( device >= dsDevices.size() ) {
-    errorText_ = "RtApiDs::getDeviceInfo: device ID is invalid!";
-    error( RtAudioError::INVALID_USE );
-    return info;
-  }
-
-  HRESULT result;
-  if ( dsDevices[ device ].validId[0] == false ) goto probeInput;
-
-  LPDIRECTSOUND output;
-  DSCAPS outCaps;
-  result = DirectSoundCreate( dsDevices[ device ].id[0], &output, NULL );
-  if ( FAILED( result ) ) {
-    errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") opening output device (" << dsDevices[ device ].name << ")!";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    goto probeInput;
-  }
-
-  outCaps.dwSize = sizeof( outCaps );
-  result = output->GetCaps( &outCaps );
-  if ( FAILED( result ) ) {
-    output->Release();
-    errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") getting capabilities!";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    goto probeInput;
-  }
-
-  // Get output channel information.
-  info.outputChannels = ( outCaps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1;
-
-  // Get sample rate information.
-  info.sampleRates.clear();
-  for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
-    if ( SAMPLE_RATES[k] >= (unsigned int) outCaps.dwMinSecondarySampleRate &&
-         SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate ) {
-      info.sampleRates.push_back( SAMPLE_RATES[k] );
-
-      if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
-        info.preferredSampleRate = SAMPLE_RATES[k];
-    }
-  }
-
-  // Get format information.
-  if ( outCaps.dwFlags & DSCAPS_PRIMARY16BIT ) info.nativeFormats |= RTAUDIO_SINT16;
-  if ( outCaps.dwFlags & DSCAPS_PRIMARY8BIT ) info.nativeFormats |= RTAUDIO_SINT8;
-
-  output->Release();
-
-  if ( getDefaultOutputDevice() == device )
-    info.isDefaultOutput = true;
-
-  if ( dsDevices[ device ].validId[1] == false ) {
-    info.name = dsDevices[ device ].name;
-    info.probed = true;
-    return info;
-  }
-
- probeInput:
-
-  LPDIRECTSOUNDCAPTURE input;
-  result = DirectSoundCaptureCreate( dsDevices[ device ].id[1], &input, NULL );
-  if ( FAILED( result ) ) {
-    errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") opening input device (" << dsDevices[ device ].name << ")!";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  DSCCAPS inCaps;
-  inCaps.dwSize = sizeof( inCaps );
-  result = input->GetCaps( &inCaps );
-  if ( FAILED( result ) ) {
-    input->Release();
-    errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") getting object capabilities (" << dsDevices[ device ].name << ")!";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Get input channel information.
-  info.inputChannels = inCaps.dwChannels;
-
-  // Get sample rate and format information.
-  std::vector<unsigned int> rates;
-  if ( inCaps.dwChannels >= 2 ) {
-    if ( inCaps.dwFormats & WAVE_FORMAT_1S16 ) info.nativeFormats |= RTAUDIO_SINT16;
-    if ( inCaps.dwFormats & WAVE_FORMAT_2S16 ) info.nativeFormats |= RTAUDIO_SINT16;
-    if ( inCaps.dwFormats & WAVE_FORMAT_4S16 ) info.nativeFormats |= RTAUDIO_SINT16;
-    if ( inCaps.dwFormats & WAVE_FORMAT_96S16 ) info.nativeFormats |= RTAUDIO_SINT16;
-    if ( inCaps.dwFormats & WAVE_FORMAT_1S08 ) info.nativeFormats |= RTAUDIO_SINT8;
-    if ( inCaps.dwFormats & WAVE_FORMAT_2S08 ) info.nativeFormats |= RTAUDIO_SINT8;
-    if ( inCaps.dwFormats & WAVE_FORMAT_4S08 ) info.nativeFormats |= RTAUDIO_SINT8;
-    if ( inCaps.dwFormats & WAVE_FORMAT_96S08 ) info.nativeFormats |= RTAUDIO_SINT8;
-
-    if ( info.nativeFormats & RTAUDIO_SINT16 ) {
-      if ( inCaps.dwFormats & WAVE_FORMAT_1S16 ) rates.push_back( 11025 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_2S16 ) rates.push_back( 22050 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_4S16 ) rates.push_back( 44100 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_96S16 ) rates.push_back( 96000 );
-    }
-    else if ( info.nativeFormats & RTAUDIO_SINT8 ) {
-      if ( inCaps.dwFormats & WAVE_FORMAT_1S08 ) rates.push_back( 11025 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_2S08 ) rates.push_back( 22050 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_4S08 ) rates.push_back( 44100 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_96S08 ) rates.push_back( 96000 );
-    }
-  }
-  else if ( inCaps.dwChannels == 1 ) {
-    if ( inCaps.dwFormats & WAVE_FORMAT_1M16 ) info.nativeFormats |= RTAUDIO_SINT16;
-    if ( inCaps.dwFormats & WAVE_FORMAT_2M16 ) info.nativeFormats |= RTAUDIO_SINT16;
-    if ( inCaps.dwFormats & WAVE_FORMAT_4M16 ) info.nativeFormats |= RTAUDIO_SINT16;
-    if ( inCaps.dwFormats & WAVE_FORMAT_96M16 ) info.nativeFormats |= RTAUDIO_SINT16;
-    if ( inCaps.dwFormats & WAVE_FORMAT_1M08 ) info.nativeFormats |= RTAUDIO_SINT8;
-    if ( inCaps.dwFormats & WAVE_FORMAT_2M08 ) info.nativeFormats |= RTAUDIO_SINT8;
-    if ( inCaps.dwFormats & WAVE_FORMAT_4M08 ) info.nativeFormats |= RTAUDIO_SINT8;
-    if ( inCaps.dwFormats & WAVE_FORMAT_96M08 ) info.nativeFormats |= RTAUDIO_SINT8;
-
-    if ( info.nativeFormats & RTAUDIO_SINT16 ) {
-      if ( inCaps.dwFormats & WAVE_FORMAT_1M16 ) rates.push_back( 11025 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_2M16 ) rates.push_back( 22050 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_4M16 ) rates.push_back( 44100 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_96M16 ) rates.push_back( 96000 );
-    }
-    else if ( info.nativeFormats & RTAUDIO_SINT8 ) {
-      if ( inCaps.dwFormats & WAVE_FORMAT_1M08 ) rates.push_back( 11025 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_2M08 ) rates.push_back( 22050 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_4M08 ) rates.push_back( 44100 );
-      if ( inCaps.dwFormats & WAVE_FORMAT_96M08 ) rates.push_back( 96000 );
-    }
-  }
-  else info.inputChannels = 0; // technically, this would be an error
-
-  input->Release();
-
-  if ( info.inputChannels == 0 ) return info;
-
-  // Copy the supported rates to the info structure but avoid duplication.
-  bool found;
-  for ( unsigned int i=0; i<rates.size(); i++ ) {
-    found = false;
-    for ( unsigned int j=0; j<info.sampleRates.size(); j++ ) {
-      if ( rates[i] == info.sampleRates[j] ) {
-        found = true;
-        break;
-      }
-    }
-    if ( found == false ) info.sampleRates.push_back( rates[i] );
-  }
-  std::sort( info.sampleRates.begin(), info.sampleRates.end() );
-
-  // If device opens for both playback and capture, we determine the channels.
-  if ( info.outputChannels > 0 && info.inputChannels > 0 )
-    info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-
-  if ( device == 0 ) info.isDefaultInput = true;
-
-  // Copy name and return.
-  info.name = dsDevices[ device ].name;
-  info.probed = true;
-  return info;
-}
-
-bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
-                                 unsigned int firstChannel, unsigned int sampleRate,
-                                 RtAudioFormat format, unsigned int *bufferSize,
-                                 RtAudio::StreamOptions *options )
-{
-  if ( channels + firstChannel > 2 ) {
-    errorText_ = "RtApiDs::probeDeviceOpen: DirectSound does not support more than 2 channels per device.";
-    return FAILURE;
-  }
-
-  size_t nDevices = dsDevices.size();
-  if ( nDevices == 0 ) {
-    // This should not happen because a check is made before this function is called.
-    errorText_ = "RtApiDs::probeDeviceOpen: no devices found!";
-    return FAILURE;
-  }
-
-  if ( device >= nDevices ) {
-    // This should not happen because a check is made before this function is called.
-    errorText_ = "RtApiDs::probeDeviceOpen: device ID is invalid!";
-    return FAILURE;
-  }
-
-  if ( mode == OUTPUT ) {
-    if ( dsDevices[ device ].validId[0] == false ) {
-      errorStream_ << "RtApiDs::probeDeviceOpen: device (" << device << ") does not support output!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-  }
-  else { // mode == INPUT
-    if ( dsDevices[ device ].validId[1] == false ) {
-      errorStream_ << "RtApiDs::probeDeviceOpen: device (" << device << ") does not support input!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-  }
-
-  // According to a note in PortAudio, using GetDesktopWindow()
-  // instead of GetForegroundWindow() is supposed to avoid problems
-  // that occur when the application's window is not the foreground
-  // window.  Also, if the application window closes before the
-  // DirectSound buffer, DirectSound can crash.  In the past, I had
-  // problems when using GetDesktopWindow() but it seems fine now
-  // (January 2010).  I'll leave it commented here.
-  // HWND hWnd = GetForegroundWindow();
-  HWND hWnd = GetDesktopWindow();
-
-  // Check the numberOfBuffers parameter and limit the lowest value to
-  // two.  This is a judgement call and a value of two is probably too
-  // low for capture, but it should work for playback.
-  int nBuffers = 0;
-  if ( options ) nBuffers = options->numberOfBuffers;
-  if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) nBuffers = 2;
-  if ( nBuffers < 2 ) nBuffers = 3;
-
-  // Check the lower range of the user-specified buffer size and set
-  // (arbitrarily) to a lower bound of 32.
-  if ( *bufferSize < 32 ) *bufferSize = 32;
-
-  // Create the wave format structure.  The data format setting will
-  // be determined later.
-  WAVEFORMATEX waveFormat;
-  ZeroMemory( &waveFormat, sizeof(WAVEFORMATEX) );
-  waveFormat.wFormatTag = WAVE_FORMAT_PCM;
-  waveFormat.nChannels = channels + firstChannel;
-  waveFormat.nSamplesPerSec = (unsigned long) sampleRate;
-
-  // Determine the device buffer size. By default, we'll use the value
-  // defined above (32K), but we will grow it to make allowances for
-  // very large software buffer sizes.
-  DWORD dsBufferSize = MINIMUM_DEVICE_BUFFER_SIZE;
-  DWORD dsPointerLeadTime = 0;
-
-  void *ohandle = 0, *bhandle = 0;
-  HRESULT result;
-  if ( mode == OUTPUT ) {
-
-    LPDIRECTSOUND output;
-    result = DirectSoundCreate( dsDevices[ device ].id[0], &output, NULL );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") opening output device (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    DSCAPS outCaps;
-    outCaps.dwSize = sizeof( outCaps );
-    result = output->GetCaps( &outCaps );
-    if ( FAILED( result ) ) {
-      output->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting capabilities (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    // Check channel information.
-    if ( channels + firstChannel == 2 && !( outCaps.dwFlags & DSCAPS_PRIMARYSTEREO ) ) {
-      errorStream_ << "RtApiDs::getDeviceInfo: the output device (" << dsDevices[ device ].name << ") does not support stereo playback.";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    // Check format information.  Use 16-bit format unless not
-    // supported or user requests 8-bit.
-    if ( outCaps.dwFlags & DSCAPS_PRIMARY16BIT &&
-         !( format == RTAUDIO_SINT8 && outCaps.dwFlags & DSCAPS_PRIMARY8BIT ) ) {
-      waveFormat.wBitsPerSample = 16;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT16;
-    }
-    else {
-      waveFormat.wBitsPerSample = 8;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT8;
-    }
-    stream_.userFormat = format;
-
-    // Update wave format structure and buffer information.
-    waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
-    waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
-    dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels;
-
-    // If the user wants an even bigger buffer, increase the device buffer size accordingly.
-    while ( dsPointerLeadTime * 2U > dsBufferSize )
-      dsBufferSize *= 2;
-
-    // Set cooperative level to DSSCL_EXCLUSIVE ... sound stops when window focus changes.
-    // result = output->SetCooperativeLevel( hWnd, DSSCL_EXCLUSIVE );
-    // Set cooperative level to DSSCL_PRIORITY ... sound remains when window focus changes.
-    result = output->SetCooperativeLevel( hWnd, DSSCL_PRIORITY );
-    if ( FAILED( result ) ) {
-      output->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") setting cooperative level (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    // Even though we will write to the secondary buffer, we need to
-    // access the primary buffer to set the correct output format
-    // (since the default is 8-bit, 22 kHz!).  Setup the DS primary
-    // buffer description.
-    DSBUFFERDESC bufferDescription;
-    ZeroMemory( &bufferDescription, sizeof( DSBUFFERDESC ) );
-    bufferDescription.dwSize = sizeof( DSBUFFERDESC );
-    bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER;
-
-    // Obtain the primary buffer
-    LPDIRECTSOUNDBUFFER buffer;
-    result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL );
-    if ( FAILED( result ) ) {
-      output->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") accessing primary buffer (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    // Set the primary DS buffer sound format.
-    result = buffer->SetFormat( &waveFormat );
-    if ( FAILED( result ) ) {
-      output->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") setting primary buffer format (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    // Setup the secondary DS buffer description.
-    ZeroMemory( &bufferDescription, sizeof( DSBUFFERDESC ) );
-    bufferDescription.dwSize = sizeof( DSBUFFERDESC );
-    bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS |
-                                  DSBCAPS_GLOBALFOCUS |
-                                  DSBCAPS_GETCURRENTPOSITION2 |
-                                  DSBCAPS_LOCHARDWARE );  // Force hardware mixing
-    bufferDescription.dwBufferBytes = dsBufferSize;
-    bufferDescription.lpwfxFormat = &waveFormat;
-
-    // Try to create the secondary DS buffer.  If that doesn't work,
-    // try to use software mixing.  Otherwise, there's a problem.
-    result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL );
-    if ( FAILED( result ) ) {
-      bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS |
-                                    DSBCAPS_GLOBALFOCUS |
-                                    DSBCAPS_GETCURRENTPOSITION2 |
-                                    DSBCAPS_LOCSOFTWARE );  // Force software mixing
-      result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL );
-      if ( FAILED( result ) ) {
-        output->Release();
-        errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") creating secondary buffer (" << dsDevices[ device ].name << ")!";
-        errorText_ = errorStream_.str();
-        return FAILURE;
-      }
-    }
-
-    // Get the buffer size ... might be different from what we specified.
-    DSBCAPS dsbcaps;
-    dsbcaps.dwSize = sizeof( DSBCAPS );
-    result = buffer->GetCaps( &dsbcaps );
-    if ( FAILED( result ) ) {
-      output->Release();
-      buffer->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting buffer settings (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    dsBufferSize = dsbcaps.dwBufferBytes;
-
-    // Lock the DS buffer
-    LPVOID audioPtr;
-    DWORD dataLen;
-    result = buffer->Lock( 0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0 );
-    if ( FAILED( result ) ) {
-      output->Release();
-      buffer->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") locking buffer (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    // Zero the DS buffer
-    ZeroMemory( audioPtr, dataLen );
-
-    // Unlock the DS buffer
-    result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
-    if ( FAILED( result ) ) {
-      output->Release();
-      buffer->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") unlocking buffer (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    ohandle = (void *) output;
-    bhandle = (void *) buffer;
-  }
-
-  if ( mode == INPUT ) {
-
-    LPDIRECTSOUNDCAPTURE input;
-    result = DirectSoundCaptureCreate( dsDevices[ device ].id[1], &input, NULL );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") opening input device (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    DSCCAPS inCaps;
-    inCaps.dwSize = sizeof( inCaps );
-    result = input->GetCaps( &inCaps );
-    if ( FAILED( result ) ) {
-      input->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting input capabilities (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    // Check channel information.
-    if ( inCaps.dwChannels < channels + firstChannel ) {
-      errorText_ = "RtApiDs::getDeviceInfo: the input device does not support requested input channels.";
-      return FAILURE;
-    }
-
-    // Check format information.  Use 16-bit format unless user
-    // requests 8-bit.
-    DWORD deviceFormats;
-    if ( channels + firstChannel == 2 ) {
-      deviceFormats = WAVE_FORMAT_1S08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_4S08 | WAVE_FORMAT_96S08;
-      if ( format == RTAUDIO_SINT8 && inCaps.dwFormats & deviceFormats ) {
-        waveFormat.wBitsPerSample = 8;
-        stream_.deviceFormat[mode] = RTAUDIO_SINT8;
-      }
-      else { // assume 16-bit is supported
-        waveFormat.wBitsPerSample = 16;
-        stream_.deviceFormat[mode] = RTAUDIO_SINT16;
-      }
-    }
-    else { // channel == 1
-      deviceFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_2M08 | WAVE_FORMAT_4M08 | WAVE_FORMAT_96M08;
-      if ( format == RTAUDIO_SINT8 && inCaps.dwFormats & deviceFormats ) {
-        waveFormat.wBitsPerSample = 8;
-        stream_.deviceFormat[mode] = RTAUDIO_SINT8;
-      }
-      else { // assume 16-bit is supported
-        waveFormat.wBitsPerSample = 16;
-        stream_.deviceFormat[mode] = RTAUDIO_SINT16;
-      }
-    }
-    stream_.userFormat = format;
-
-    // Update wave format structure and buffer information.
-    waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
-    waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
-    dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels;
-
-    // If the user wants an even bigger buffer, increase the device buffer size accordingly.
-    while ( dsPointerLeadTime * 2U > dsBufferSize )
-      dsBufferSize *= 2;
-
-    // Setup the secondary DS buffer description.
-    DSCBUFFERDESC bufferDescription;
-    ZeroMemory( &bufferDescription, sizeof( DSCBUFFERDESC ) );
-    bufferDescription.dwSize = sizeof( DSCBUFFERDESC );
-    bufferDescription.dwFlags = 0;
-    bufferDescription.dwReserved = 0;
-    bufferDescription.dwBufferBytes = dsBufferSize;
-    bufferDescription.lpwfxFormat = &waveFormat;
-
-    // Create the capture buffer.
-    LPDIRECTSOUNDCAPTUREBUFFER buffer;
-    result = input->CreateCaptureBuffer( &bufferDescription, &buffer, NULL );
-    if ( FAILED( result ) ) {
-      input->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") creating input buffer (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    // Get the buffer size ... might be different from what we specified.
-    DSCBCAPS dscbcaps;
-    dscbcaps.dwSize = sizeof( DSCBCAPS );
-    result = buffer->GetCaps( &dscbcaps );
-    if ( FAILED( result ) ) {
-      input->Release();
-      buffer->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting buffer settings (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    dsBufferSize = dscbcaps.dwBufferBytes;
-
-    // NOTE: We could have a problem here if this is a duplex stream
-    // and the play and capture hardware buffer sizes are different
-    // (I'm actually not sure if that is a problem or not).
-    // Currently, we are not verifying that.
-
-    // Lock the capture buffer
-    LPVOID audioPtr;
-    DWORD dataLen;
-    result = buffer->Lock( 0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0 );
-    if ( FAILED( result ) ) {
-      input->Release();
-      buffer->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") locking input buffer (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    // Zero the buffer
-    ZeroMemory( audioPtr, dataLen );
-
-    // Unlock the buffer
-    result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
-    if ( FAILED( result ) ) {
-      input->Release();
-      buffer->Release();
-      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") unlocking input buffer (" << dsDevices[ device ].name << ")!";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-
-    ohandle = (void *) input;
-    bhandle = (void *) buffer;
-  }
-
-  // Set various stream parameters
-  DsHandle *handle = 0;
-  stream_.nDeviceChannels[mode] = channels + firstChannel;
-  stream_.nUserChannels[mode] = channels;
-  stream_.bufferSize = *bufferSize;
-  stream_.channelOffset[mode] = firstChannel;
-  stream_.deviceInterleaved[mode] = true;
-  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
-  else stream_.userInterleaved = true;
-
-  // Set flag for buffer conversion
-  stream_.doConvertBuffer[mode] = false;
-  if (stream_.nUserChannels[mode] != stream_.nDeviceChannels[mode])
-    stream_.doConvertBuffer[mode] = true;
-  if (stream_.userFormat != stream_.deviceFormat[mode])
-    stream_.doConvertBuffer[mode] = true;
-  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
-       stream_.nUserChannels[mode] > 1 )
-    stream_.doConvertBuffer[mode] = true;
-
-  // Allocate necessary internal buffers
-  long bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
-  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
-  if ( stream_.userBuffer[mode] == NULL ) {
-    errorText_ = "RtApiDs::probeDeviceOpen: error allocating user buffer memory.";
-    goto error;
-  }
-
-  if ( stream_.doConvertBuffer[mode] ) {
-
-    bool makeBuffer = true;
-    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
-    if ( mode == INPUT ) {
-      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
-        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
-        if ( bufferBytes <= (long) bytesOut ) makeBuffer = false;
-      }
-    }
-
-    if ( makeBuffer ) {
-      bufferBytes *= *bufferSize;
-      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
-      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
-      if ( stream_.deviceBuffer == NULL ) {
-        errorText_ = "RtApiDs::probeDeviceOpen: error allocating device buffer memory.";
-        goto error;
-      }
-    }
-  }
-
-  // Allocate our DsHandle structures for the stream.
-  if ( stream_.apiHandle == 0 ) {
-    try {
-      handle = new DsHandle;
-    }
-    catch ( std::bad_alloc& ) {
-      errorText_ = "RtApiDs::probeDeviceOpen: error allocating AsioHandle memory.";
-      goto error;
-    }
-
-    // Create a manual-reset event.
-    handle->condition = CreateEvent( NULL,   // no security
-                                     TRUE,   // manual-reset
-                                     FALSE,  // non-signaled initially
-                                     NULL ); // unnamed
-    stream_.apiHandle = (void *) handle;
-  }
-  else
-    handle = (DsHandle *) stream_.apiHandle;
-  handle->id[mode] = ohandle;
-  handle->buffer[mode] = bhandle;
-  handle->dsBufferSize[mode] = dsBufferSize;
-  handle->dsPointerLeadTime[mode] = dsPointerLeadTime;
-
-  stream_.device[mode] = device;
-  stream_.state = STREAM_STOPPED;
-  if ( stream_.mode == OUTPUT && mode == INPUT )
-    // We had already set up an output stream.
-    stream_.mode = DUPLEX;
-  else
-    stream_.mode = mode;
-  stream_.nBuffers = nBuffers;
-  stream_.sampleRate = sampleRate;
-
-  // Setup the buffer conversion information structure.
-  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
-
-  // Setup the callback thread.
-  if ( stream_.callbackInfo.isRunning == false ) {
-    unsigned threadId;
-    stream_.callbackInfo.isRunning = true;
-    stream_.callbackInfo.object = (void *) this;
-    stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &callbackHandler,
-                                                  &stream_.callbackInfo, 0, &threadId );
-    if ( stream_.callbackInfo.thread == 0 ) {
-      errorText_ = "RtApiDs::probeDeviceOpen: error creating callback thread!";
-      goto error;
-    }
-
-    // Boost DS thread priority
-    SetThreadPriority( (HANDLE) stream_.callbackInfo.thread, THREAD_PRIORITY_HIGHEST );
-  }
-  return SUCCESS;
-
- error:
-  if ( handle ) {
-    if ( handle->buffer[0] ) { // the object pointer can be NULL and valid
-      LPDIRECTSOUND object = (LPDIRECTSOUND) handle->id[0];
-      LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
-      if ( buffer ) buffer->Release();
-      object->Release();
-    }
-    if ( handle->buffer[1] ) {
-      LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) handle->id[1];
-      LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
-      if ( buffer ) buffer->Release();
-      object->Release();
-    }
-    CloseHandle( handle->condition );
-    delete handle;
-    stream_.apiHandle = 0;
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  stream_.state = STREAM_CLOSED;
-  return FAILURE;
-}
-
-void RtApiDs :: closeStream()
-{
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiDs::closeStream(): no open stream to close!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  // Stop the callback thread.
-  stream_.callbackInfo.isRunning = false;
-  WaitForSingleObject( (HANDLE) stream_.callbackInfo.thread, INFINITE );
-  CloseHandle( (HANDLE) stream_.callbackInfo.thread );
-
-  DsHandle *handle = (DsHandle *) stream_.apiHandle;
-  if ( handle ) {
-    if ( handle->buffer[0] ) { // the object pointer can be NULL and valid
-      LPDIRECTSOUND object = (LPDIRECTSOUND) handle->id[0];
-      LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
-      if ( buffer ) {
-        buffer->Stop();
-        buffer->Release();
-      }
-      object->Release();
-    }
-    if ( handle->buffer[1] ) {
-      LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) handle->id[1];
-      LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
-      if ( buffer ) {
-        buffer->Stop();
-        buffer->Release();
-      }
-      object->Release();
-    }
-    CloseHandle( handle->condition );
-    delete handle;
-    stream_.apiHandle = 0;
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  stream_.mode = UNINITIALIZED;
-  stream_.state = STREAM_CLOSED;
-}
-
-void RtApiDs :: startStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_RUNNING ) {
-    errorText_ = "RtApiDs::startStream(): the stream is already running!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  #if defined( HAVE_GETTIMEOFDAY )
-  gettimeofday( &stream_.lastTickTimestamp, NULL );
-  #endif
-
-  DsHandle *handle = (DsHandle *) stream_.apiHandle;
-
-  // Increase scheduler frequency on lesser windows (a side-effect of
-  // increasing timer accuracy).  On greater windows (Win2K or later),
-  // this is already in effect.
-  timeBeginPeriod( 1 ); 
-
-  buffersRolling = false;
-  duplexPrerollBytes = 0;
-
-  if ( stream_.mode == DUPLEX ) {
-    // 0.5 seconds of silence in DUPLEX mode while the devices spin up and synchronize.
-    duplexPrerollBytes = (int) ( 0.5 * stream_.sampleRate * formatBytes( stream_.deviceFormat[1] ) * stream_.nDeviceChannels[1] );
-  }
-
-  HRESULT result = 0;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
-    LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
-    result = buffer->Play( 0, 0, DSBPLAY_LOOPING );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::startStream: error (" << getErrorString( result ) << ") starting output buffer!";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
-  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
-    LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
-    result = buffer->Start( DSCBSTART_LOOPING );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::startStream: error (" << getErrorString( result ) << ") starting input buffer!";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
-  handle->drainCounter = 0;
-  handle->internalDrain = false;
-  ResetEvent( handle->condition );
-  stream_.state = STREAM_RUNNING;
-
- unlock:
-  if ( FAILED( result ) ) error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiDs :: stopStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiDs::stopStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  HRESULT result = 0;
-  LPVOID audioPtr;
-  DWORD dataLen;
-  DsHandle *handle = (DsHandle *) stream_.apiHandle;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-    if ( handle->drainCounter == 0 ) {
-      handle->drainCounter = 2;
-      WaitForSingleObject( handle->condition, INFINITE );  // block until signaled
-    }
-
-    stream_.state = STREAM_STOPPED;
-
-    MUTEX_LOCK( &stream_.mutex );
-
-    // Stop the buffer and clear memory
-    LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
-    result = buffer->Stop();
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") stopping output buffer!";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-
-    // Lock the buffer and clear it so that if we start to play again,
-    // we won't have old data playing.
-    result = buffer->Lock( 0, handle->dsBufferSize[0], &audioPtr, &dataLen, NULL, NULL, 0 );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") locking output buffer!";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-
-    // Zero the DS buffer
-    ZeroMemory( audioPtr, dataLen );
-
-    // Unlock the DS buffer
-    result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") unlocking output buffer!";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-
-    // If we start playing again, we must begin at beginning of buffer.
-    handle->bufferPointer[0] = 0;
-  }
-
-  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-    LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
-    audioPtr = NULL;
-    dataLen = 0;
-
-    stream_.state = STREAM_STOPPED;
-
-    if ( stream_.mode != DUPLEX )
-      MUTEX_LOCK( &stream_.mutex );
-
-    result = buffer->Stop();
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") stopping input buffer!";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-
-    // Lock the buffer and clear it so that if we start to play again,
-    // we won't have old data playing.
-    result = buffer->Lock( 0, handle->dsBufferSize[1], &audioPtr, &dataLen, NULL, NULL, 0 );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") locking input buffer!";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-
-    // Zero the DS buffer
-    ZeroMemory( audioPtr, dataLen );
-
-    // Unlock the DS buffer
-    result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") unlocking input buffer!";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-
-    // If we start recording again, we must begin at beginning of buffer.
-    handle->bufferPointer[1] = 0;
-  }
-
- unlock:
-  timeEndPeriod( 1 ); // revert to normal scheduler frequency on lesser windows.
-  MUTEX_UNLOCK( &stream_.mutex );
-
-  if ( FAILED( result ) ) error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiDs :: abortStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiDs::abortStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  DsHandle *handle = (DsHandle *) stream_.apiHandle;
-  handle->drainCounter = 2;
-
-  stopStream();
-}
-
-void RtApiDs :: callbackEvent()
-{
-  if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) {
-    Sleep( 50 ); // sleep 50 milliseconds
-    return;
-  }
-
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiDs::callbackEvent(): the stream is closed ... this shouldn't happen!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
-  DsHandle *handle = (DsHandle *) stream_.apiHandle;
-
-  // Check if we were draining the stream and signal is finished.
-  if ( handle->drainCounter > stream_.nBuffers + 2 ) {
-
-    stream_.state = STREAM_STOPPING;
-    if ( handle->internalDrain == false )
-      SetEvent( handle->condition );
-    else
-      stopStream();
-    return;
-  }
-
-  // Invoke user callback to get fresh output data UNLESS we are
-  // draining stream.
-  if ( handle->drainCounter == 0 ) {
-    RtAudioCallback callback = (RtAudioCallback) info->callback;
-    double streamTime = getStreamTime();
-    RtAudioStreamStatus status = 0;
-    if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
-      status |= RTAUDIO_OUTPUT_UNDERFLOW;
-      handle->xrun[0] = false;
-    }
-    if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
-      status |= RTAUDIO_INPUT_OVERFLOW;
-      handle->xrun[1] = false;
-    }
-    int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
-                                  stream_.bufferSize, streamTime, status, info->userData );
-    if ( cbReturnValue == 2 ) {
-      stream_.state = STREAM_STOPPING;
-      handle->drainCounter = 2;
-      abortStream();
-      return;
-    }
-    else if ( cbReturnValue == 1 ) {
-      handle->drainCounter = 1;
-      handle->internalDrain = true;
-    }
-  }
-
-  HRESULT result;
-  DWORD currentWritePointer, safeWritePointer;
-  DWORD currentReadPointer, safeReadPointer;
-  UINT nextWritePointer;
-
-  LPVOID buffer1 = NULL;
-  LPVOID buffer2 = NULL;
-  DWORD bufferSize1 = 0;
-  DWORD bufferSize2 = 0;
-
-  char *buffer;
-  long bufferBytes;
-
-  MUTEX_LOCK( &stream_.mutex );
-  if ( stream_.state == STREAM_STOPPED ) {
-    MUTEX_UNLOCK( &stream_.mutex );
-    return;
-  }
-
-  if ( buffersRolling == false ) {
-    if ( stream_.mode == DUPLEX ) {
-      //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
-
-      // It takes a while for the devices to get rolling. As a result,
-      // there's no guarantee that the capture and write device pointers
-      // will move in lockstep.  Wait here for both devices to start
-      // rolling, and then set our buffer pointers accordingly.
-      // e.g. Crystal Drivers: the capture buffer starts up 5700 to 9600
-      // bytes later than the write buffer.
-
-      // Stub: a serious risk of having a pre-emptive scheduling round
-      // take place between the two GetCurrentPosition calls... but I'm
-      // really not sure how to solve the problem.  Temporarily boost to
-      // Realtime priority, maybe; but I'm not sure what priority the
-      // DirectSound service threads run at. We *should* be roughly
-      // within a ms or so of correct.
-
-      LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
-      LPDIRECTSOUNDCAPTUREBUFFER dsCaptureBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
-
-      DWORD startSafeWritePointer, startSafeReadPointer;
-
-      result = dsWriteBuffer->GetCurrentPosition( NULL, &startSafeWritePointer );
-      if ( FAILED( result ) ) {
-        errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
-        errorText_ = errorStream_.str();
-        MUTEX_UNLOCK( &stream_.mutex );
-        error( RtAudioError::SYSTEM_ERROR );
-        return;
-      }
-      result = dsCaptureBuffer->GetCurrentPosition( NULL, &startSafeReadPointer );
-      if ( FAILED( result ) ) {
-        errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
-        errorText_ = errorStream_.str();
-        MUTEX_UNLOCK( &stream_.mutex );
-        error( RtAudioError::SYSTEM_ERROR );
-        return;
-      }
-      while ( true ) {
-        result = dsWriteBuffer->GetCurrentPosition( NULL, &safeWritePointer );
-        if ( FAILED( result ) ) {
-          errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
-          errorText_ = errorStream_.str();
-          MUTEX_UNLOCK( &stream_.mutex );
-          error( RtAudioError::SYSTEM_ERROR );
-          return;
-        }
-        result = dsCaptureBuffer->GetCurrentPosition( NULL, &safeReadPointer );
-        if ( FAILED( result ) ) {
-          errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
-          errorText_ = errorStream_.str();
-          MUTEX_UNLOCK( &stream_.mutex );
-          error( RtAudioError::SYSTEM_ERROR );
-          return;
-        }
-        if ( safeWritePointer != startSafeWritePointer && safeReadPointer != startSafeReadPointer ) break;
-        Sleep( 1 );
-      }
-
-      //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
-
-      handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0];
-      if ( handle->bufferPointer[0] >= handle->dsBufferSize[0] ) handle->bufferPointer[0] -= handle->dsBufferSize[0];
-      handle->bufferPointer[1] = safeReadPointer;
-    }
-    else if ( stream_.mode == OUTPUT ) {
-
-      // Set the proper nextWritePosition after initial startup.
-      LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
-      result = dsWriteBuffer->GetCurrentPosition( &currentWritePointer, &safeWritePointer );
-      if ( FAILED( result ) ) {
-        errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
-        errorText_ = errorStream_.str();
-        MUTEX_UNLOCK( &stream_.mutex );
-        error( RtAudioError::SYSTEM_ERROR );
-        return;
-      }
-      handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0];
-      if ( handle->bufferPointer[0] >= handle->dsBufferSize[0] ) handle->bufferPointer[0] -= handle->dsBufferSize[0];
-    }
-
-    buffersRolling = true;
-  }
-
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-    
-    LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
-
-    if ( handle->drainCounter > 1 ) { // write zeros to the output stream
-      bufferBytes = stream_.bufferSize * stream_.nUserChannels[0];
-      bufferBytes *= formatBytes( stream_.userFormat );
-      memset( stream_.userBuffer[0], 0, bufferBytes );
-    }
-
-    // Setup parameters and do buffer conversion if necessary.
-    if ( stream_.doConvertBuffer[0] ) {
-      buffer = stream_.deviceBuffer;
-      convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] );
-      bufferBytes = stream_.bufferSize * stream_.nDeviceChannels[0];
-      bufferBytes *= formatBytes( stream_.deviceFormat[0] );
-    }
-    else {
-      buffer = stream_.userBuffer[0];
-      bufferBytes = stream_.bufferSize * stream_.nUserChannels[0];
-      bufferBytes *= formatBytes( stream_.userFormat );
-    }
-
-    // No byte swapping necessary in DirectSound implementation.
-
-    // Ahhh ... windoze.  16-bit data is signed but 8-bit data is
-    // unsigned.  So, we need to convert our signed 8-bit data here to
-    // unsigned.
-    if ( stream_.deviceFormat[0] == RTAUDIO_SINT8 )
-      for ( int i=0; i<bufferBytes; i++ ) buffer[i] = (unsigned char) ( buffer[i] + 128 );
-
-    DWORD dsBufferSize = handle->dsBufferSize[0];
-    nextWritePointer = handle->bufferPointer[0];
-
-    DWORD endWrite, leadPointer;
-    while ( true ) {
-      // Find out where the read and "safe write" pointers are.
-      result = dsBuffer->GetCurrentPosition( &currentWritePointer, &safeWritePointer );
-      if ( FAILED( result ) ) {
-        errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
-        errorText_ = errorStream_.str();
-        MUTEX_UNLOCK( &stream_.mutex );
-        error( RtAudioError::SYSTEM_ERROR );
-        return;
-      }
-
-      // We will copy our output buffer into the region between
-      // safeWritePointer and leadPointer.  If leadPointer is not
-      // beyond the next endWrite position, wait until it is.
-      leadPointer = safeWritePointer + handle->dsPointerLeadTime[0];
-      //std::cout << "safeWritePointer = " << safeWritePointer << ", leadPointer = " << leadPointer << ", nextWritePointer = " << nextWritePointer << std::endl;
-      if ( leadPointer > dsBufferSize ) leadPointer -= dsBufferSize;
-      if ( leadPointer < nextWritePointer ) leadPointer += dsBufferSize; // unwrap offset
-      endWrite = nextWritePointer + bufferBytes;
-
-      // Check whether the entire write region is behind the play pointer.
-      if ( leadPointer >= endWrite ) break;
-
-      // If we are here, then we must wait until the leadPointer advances
-      // beyond the end of our next write region. We use the
-      // Sleep() function to suspend operation until that happens.
-      double millis = ( endWrite - leadPointer ) * 1000.0;
-      millis /= ( formatBytes( stream_.deviceFormat[0]) * stream_.nDeviceChannels[0] * stream_.sampleRate);
-      if ( millis < 1.0 ) millis = 1.0;
-      Sleep( (DWORD) millis );
-    }
-
-    if ( dsPointerBetween( nextWritePointer, safeWritePointer, currentWritePointer, dsBufferSize )
-         || dsPointerBetween( endWrite, safeWritePointer, currentWritePointer, dsBufferSize ) ) { 
-      // We've strayed into the forbidden zone ... resync the read pointer.
-      handle->xrun[0] = true;
-      nextWritePointer = safeWritePointer + handle->dsPointerLeadTime[0] - bufferBytes;
-      if ( nextWritePointer >= dsBufferSize ) nextWritePointer -= dsBufferSize;
-      handle->bufferPointer[0] = nextWritePointer;
-      endWrite = nextWritePointer + bufferBytes;
-    }
-
-    // Lock free space in the buffer
-    result = dsBuffer->Lock( nextWritePointer, bufferBytes, &buffer1,
-                             &bufferSize1, &buffer2, &bufferSize2, 0 );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!";
-      errorText_ = errorStream_.str();
-      MUTEX_UNLOCK( &stream_.mutex );
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
-    }
-
-    // Copy our buffer into the DS buffer
-    CopyMemory( buffer1, buffer, bufferSize1 );
-    if ( buffer2 != NULL ) CopyMemory( buffer2, buffer+bufferSize1, bufferSize2 );
-
-    // Update our buffer offset and unlock sound buffer
-    dsBuffer->Unlock( buffer1, bufferSize1, buffer2, bufferSize2 );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!";
-      errorText_ = errorStream_.str();
-      MUTEX_UNLOCK( &stream_.mutex );
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
-    }
-    nextWritePointer = ( nextWritePointer + bufferSize1 + bufferSize2 ) % dsBufferSize;
-    handle->bufferPointer[0] = nextWritePointer;
-  }
-
-  // Don't bother draining input
-  if ( handle->drainCounter ) {
-    handle->drainCounter++;
-    goto unlock;
-  }
-
-  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
-    // Setup parameters.
-    if ( stream_.doConvertBuffer[1] ) {
-      buffer = stream_.deviceBuffer;
-      bufferBytes = stream_.bufferSize * stream_.nDeviceChannels[1];
-      bufferBytes *= formatBytes( stream_.deviceFormat[1] );
-    }
-    else {
-      buffer = stream_.userBuffer[1];
-      bufferBytes = stream_.bufferSize * stream_.nUserChannels[1];
-      bufferBytes *= formatBytes( stream_.userFormat );
-    }
-
-    LPDIRECTSOUNDCAPTUREBUFFER dsBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
-    long nextReadPointer = handle->bufferPointer[1];
-    DWORD dsBufferSize = handle->dsBufferSize[1];
-
-    // Find out where the write and "safe read" pointers are.
-    result = dsBuffer->GetCurrentPosition( &currentReadPointer, &safeReadPointer );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
-      errorText_ = errorStream_.str();
-      MUTEX_UNLOCK( &stream_.mutex );
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
-    }
-
-    if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset
-    DWORD endRead = nextReadPointer + bufferBytes;
-
-    // Handling depends on whether we are INPUT or DUPLEX. 
-    // If we're in INPUT mode then waiting is a good thing. If we're in DUPLEX mode,
-    // then a wait here will drag the write pointers into the forbidden zone.
-    // 
-    // In DUPLEX mode, rather than wait, we will back off the read pointer until 
-    // it's in a safe position. This causes dropouts, but it seems to be the only 
-    // practical way to sync up the read and write pointers reliably, given the 
-    // the very complex relationship between phase and increment of the read and write 
-    // pointers.
-    //
-    // In order to minimize audible dropouts in DUPLEX mode, we will
-    // provide a pre-roll period of 0.5 seconds in which we return
-    // zeros from the read buffer while the pointers sync up.
-
-    if ( stream_.mode == DUPLEX ) {
-      if ( safeReadPointer < endRead ) {
-        if ( duplexPrerollBytes <= 0 ) {
-          // Pre-roll time over. Be more agressive.
-          int adjustment = endRead-safeReadPointer;
-
-          handle->xrun[1] = true;
-          // Two cases:
-          //   - large adjustments: we've probably run out of CPU cycles, so just resync exactly,
-          //     and perform fine adjustments later.
-          //   - small adjustments: back off by twice as much.
-          if ( adjustment >= 2*bufferBytes )
-            nextReadPointer = safeReadPointer-2*bufferBytes;
-          else
-            nextReadPointer = safeReadPointer-bufferBytes-adjustment;
-
-          if ( nextReadPointer < 0 ) nextReadPointer += dsBufferSize;
-
-        }
-        else {
-          // In pre=roll time. Just do it.
-          nextReadPointer = safeReadPointer - bufferBytes;
-          while ( nextReadPointer < 0 ) nextReadPointer += dsBufferSize;
-        }
-        endRead = nextReadPointer + bufferBytes;
-      }
-    }
-    else { // mode == INPUT
-      while ( safeReadPointer < endRead && stream_.callbackInfo.isRunning ) {
-        // See comments for playback.
-        double millis = (endRead - safeReadPointer) * 1000.0;
-        millis /= ( formatBytes(stream_.deviceFormat[1]) * stream_.nDeviceChannels[1] * stream_.sampleRate);
-        if ( millis < 1.0 ) millis = 1.0;
-        Sleep( (DWORD) millis );
-
-        // Wake up and find out where we are now.
-        result = dsBuffer->GetCurrentPosition( &currentReadPointer, &safeReadPointer );
-        if ( FAILED( result ) ) {
-          errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
-          errorText_ = errorStream_.str();
-          MUTEX_UNLOCK( &stream_.mutex );
-          error( RtAudioError::SYSTEM_ERROR );
-          return;
-        }
-      
-        if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset
-      }
-    }
-
-    // Lock free space in the buffer
-    result = dsBuffer->Lock( nextReadPointer, bufferBytes, &buffer1,
-                             &bufferSize1, &buffer2, &bufferSize2, 0 );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!";
-      errorText_ = errorStream_.str();
-      MUTEX_UNLOCK( &stream_.mutex );
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
-    }
-
-    if ( duplexPrerollBytes <= 0 ) {
-      // Copy our buffer into the DS buffer
-      CopyMemory( buffer, buffer1, bufferSize1 );
-      if ( buffer2 != NULL ) CopyMemory( buffer+bufferSize1, buffer2, bufferSize2 );
-    }
-    else {
-      memset( buffer, 0, bufferSize1 );
-      if ( buffer2 != NULL ) memset( buffer + bufferSize1, 0, bufferSize2 );
-      duplexPrerollBytes -= bufferSize1 + bufferSize2;
-    }
-
-    // Update our buffer offset and unlock sound buffer
-    nextReadPointer = ( nextReadPointer + bufferSize1 + bufferSize2 ) % dsBufferSize;
-    dsBuffer->Unlock( buffer1, bufferSize1, buffer2, bufferSize2 );
-    if ( FAILED( result ) ) {
-      errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!";
-      errorText_ = errorStream_.str();
-      MUTEX_UNLOCK( &stream_.mutex );
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
-    }
-    handle->bufferPointer[1] = nextReadPointer;
-
-    // No byte swapping necessary in DirectSound implementation.
-
-    // If necessary, convert 8-bit data from unsigned to signed.
-    if ( stream_.deviceFormat[1] == RTAUDIO_SINT8 )
-      for ( int j=0; j<bufferBytes; j++ ) buffer[j] = (signed char) ( buffer[j] - 128 );
-
-    // Do buffer conversion if necessary.
-    if ( stream_.doConvertBuffer[1] )
-      convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
-  }
-
- unlock:
-  MUTEX_UNLOCK( &stream_.mutex );
-  RtApi::tickStreamTime();
-}
-
-// Definitions for utility functions and callbacks
-// specific to the DirectSound implementation.
-
-static unsigned __stdcall callbackHandler( void *ptr )
-{
-  CallbackInfo *info = (CallbackInfo *) ptr;
-  RtApiDs *object = (RtApiDs *) info->object;
-  bool* isRunning = &info->isRunning;
-
-  while ( *isRunning == true ) {
-    object->callbackEvent();
-  }
-
-  _endthreadex( 0 );
-  return 0;
-}
-
-static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
-                                          LPCTSTR description,
-                                          LPCTSTR /*module*/,
-                                          LPVOID lpContext )
-{
-  struct DsProbeData& probeInfo = *(struct DsProbeData*) lpContext;
-  std::vector<struct DsDevice>& dsDevices = *probeInfo.dsDevices;
-
-  HRESULT hr;
-  bool validDevice = false;
-  if ( probeInfo.isInput == true ) {
-    DSCCAPS caps;
-    LPDIRECTSOUNDCAPTURE object;
-
-    hr = DirectSoundCaptureCreate(  lpguid, &object,   NULL );
-    if ( hr != DS_OK ) return TRUE;
-
-    caps.dwSize = sizeof(caps);
-    hr = object->GetCaps( &caps );
-    if ( hr == DS_OK ) {
-      if ( caps.dwChannels > 0 && caps.dwFormats > 0 )
-        validDevice = true;
-    }
-    object->Release();
-  }
-  else {
-    DSCAPS caps;
-    LPDIRECTSOUND object;
-    hr = DirectSoundCreate(  lpguid, &object,   NULL );
-    if ( hr != DS_OK ) return TRUE;
-
-    caps.dwSize = sizeof(caps);
-    hr = object->GetCaps( &caps );
-    if ( hr == DS_OK ) {
-      if ( caps.dwFlags & DSCAPS_PRIMARYMONO || caps.dwFlags & DSCAPS_PRIMARYSTEREO )
-        validDevice = true;
-    }
-    object->Release();
-  }
-
-  // If good device, then save its name and guid.
-  std::string name = convertCharPointerToStdString( description );
-  //if ( name == "Primary Sound Driver" || name == "Primary Sound Capture Driver" )
-  if ( lpguid == NULL )
-    name = "Default Device";
-  if ( validDevice ) {
-    for ( unsigned int i=0; i<dsDevices.size(); i++ ) {
-      if ( dsDevices[i].name == name ) {
-        dsDevices[i].found = true;
-        if ( probeInfo.isInput ) {
-          dsDevices[i].id[1] = lpguid;
-          dsDevices[i].validId[1] = true;
-        }
-        else {
-          dsDevices[i].id[0] = lpguid;
-          dsDevices[i].validId[0] = true;
-        }
-        return TRUE;
-      }
-    }
-
-    DsDevice device;
-    device.name = name;
-    device.found = true;
-    if ( probeInfo.isInput ) {
-      device.id[1] = lpguid;
-      device.validId[1] = true;
-    }
-    else {
-      device.id[0] = lpguid;
-      device.validId[0] = true;
-    }
-    dsDevices.push_back( device );
-  }
-
-  return TRUE;
-}
-
-static const char* getErrorString( int code )
-{
-  switch ( code ) {
-
-  case DSERR_ALLOCATED:
-    return "Already allocated";
-
-  case DSERR_CONTROLUNAVAIL:
-    return "Control unavailable";
-
-  case DSERR_INVALIDPARAM:
-    return "Invalid parameter";
-
-  case DSERR_INVALIDCALL:
-    return "Invalid call";
-
-  case DSERR_GENERIC:
-    return "Generic error";
-
-  case DSERR_PRIOLEVELNEEDED:
-    return "Priority level needed";
-
-  case DSERR_OUTOFMEMORY:
-    return "Out of memory";
-
-  case DSERR_BADFORMAT:
-    return "The sample rate or the channel format is not supported";
-
-  case DSERR_UNSUPPORTED:
-    return "Not supported";
-
-  case DSERR_NODRIVER:
-    return "No driver";
-
-  case DSERR_ALREADYINITIALIZED:
-    return "Already initialized";
-
-  case DSERR_NOAGGREGATION:
-    return "No aggregation";
-
-  case DSERR_BUFFERLOST:
-    return "Buffer lost";
-
-  case DSERR_OTHERAPPHASPRIO:
-    return "Another application already has priority";
-
-  case DSERR_UNINITIALIZED:
-    return "Uninitialized";
-
-  default:
-    return "DirectSound unknown error";
-  }
-}
-//******************** End of __WINDOWS_DS__ *********************//
-#endif
-
-
-#if defined(__LINUX_ALSA__)
-
-#include <alsa/asoundlib.h>
-#include <unistd.h>
-
-  // A structure to hold various information related to the ALSA API
-  // implementation.
-struct AlsaHandle {
-  snd_pcm_t *handles[2];
-  bool synchronized;
-  bool xrun[2];
-  pthread_cond_t runnable_cv;
-  bool runnable;
-
-  AlsaHandle()
-    :synchronized(false), runnable(false) { xrun[0] = false; xrun[1] = false; }
-};
-
-static void *alsaCallbackHandler( void * ptr );
-
-RtApiAlsa :: RtApiAlsa()
-{
-  // Nothing to do here.
-}
-
-RtApiAlsa :: ~RtApiAlsa()
-{
-  if ( stream_.state != STREAM_CLOSED ) closeStream();
-}
-
-unsigned int RtApiAlsa :: getDeviceCount( void )
-{
-  unsigned nDevices = 0;
-  int result, subdevice, card;
-  char name[64];
-  snd_ctl_t *handle = 0;
-
-  // Count cards and devices
-  card = -1;
-  snd_card_next( &card );
-  while ( card >= 0 ) {
-    sprintf( name, "hw:%d", card );
-    result = snd_ctl_open( &handle, name, 0 );
-    if ( result < 0 ) {
-      handle = 0;
-      errorStream_ << "RtApiAlsa::getDeviceCount: control open, card = " << card << ", " << snd_strerror( result ) << ".";
-      errorText_ = errorStream_.str();
-      error( RtAudioError::WARNING );
-      goto nextcard;
-    }
-    subdevice = -1;
-    while( 1 ) {
-      result = snd_ctl_pcm_next_device( handle, &subdevice );
-      if ( result < 0 ) {
-        errorStream_ << "RtApiAlsa::getDeviceCount: control next device, card = " << card << ", " << snd_strerror( result ) << ".";
-        errorText_ = errorStream_.str();
-        error( RtAudioError::WARNING );
-        break;
-      }
-      if ( subdevice < 0 )
-        break;
-      nDevices++;
-    }
-  nextcard:
-    if ( handle )
-        snd_ctl_close( handle );
-    snd_card_next( &card );
-  }
-
-  result = snd_ctl_open( &handle, "default", 0 );
-  if (result == 0) {
-    nDevices++;
-    snd_ctl_close( handle );
-  }
-
-  return nDevices;
-}
-
-RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
-{
-  RtAudio::DeviceInfo info;
-  info.probed = false;
-
-  unsigned nDevices = 0;
-  int result, subdevice, card;
-  char name[64];
-  snd_ctl_t *chandle = 0;
-
-  // Count cards and devices
-  card = -1;
-  subdevice = -1;
-  snd_card_next( &card );
-  while ( card >= 0 ) {
-    sprintf( name, "hw:%d", card );
-    result = snd_ctl_open( &chandle, name, SND_CTL_NONBLOCK );
-    if ( result < 0 ) {
-      chandle = 0;
-      errorStream_ << "RtApiAlsa::getDeviceInfo: control open, card = " << card << ", " << snd_strerror( result ) << ".";
-      errorText_ = errorStream_.str();
-      error( RtAudioError::WARNING );
-      goto nextcard;
-    }
-    subdevice = -1;
-    while( 1 ) {
-      result = snd_ctl_pcm_next_device( chandle, &subdevice );
-      if ( result < 0 ) {
-        errorStream_ << "RtApiAlsa::getDeviceInfo: control next device, card = " << card << ", " << snd_strerror( result ) << ".";
-        errorText_ = errorStream_.str();
-        error( RtAudioError::WARNING );
-        break;
-      }
-      if ( subdevice < 0 ) break;
-      if ( nDevices == device ) {
-        sprintf( name, "hw:%d,%d", card, subdevice );
-        goto foundDevice;
-      }
-      nDevices++;
-    }
-  nextcard:
-    if ( chandle )
-        snd_ctl_close( chandle );
-    snd_card_next( &card );
-  }
-
-  result = snd_ctl_open( &chandle, "default", SND_CTL_NONBLOCK );
-  if ( result == 0 ) {
-    if ( nDevices == device ) {
-      strcpy( name, "default" );
-      goto foundDevice;
-    }
-    nDevices++;
-  }
-
-  if ( nDevices == 0 ) {
-    errorText_ = "RtApiAlsa::getDeviceInfo: no devices found!";
-    error( RtAudioError::INVALID_USE );
-    return info;
-  }
-
-  if ( device >= nDevices ) {
-    errorText_ = "RtApiAlsa::getDeviceInfo: device ID is invalid!";
-    error( RtAudioError::INVALID_USE );
-    return info;
-  }
-
- foundDevice:
-
-  // If a stream is already open, we cannot probe the stream devices.
-  // Thus, use the saved results.
-  if ( stream_.state != STREAM_CLOSED &&
-       ( stream_.device[0] == device || stream_.device[1] == device ) ) {
-    snd_ctl_close( chandle );
-    if ( device >= devices_.size() ) {
-      errorText_ = "RtApiAlsa::getDeviceInfo: device ID was not present before stream was opened.";
-      error( RtAudioError::WARNING );
-      return info;
-    }
-    return devices_[ device ];
-  }
-
-  int openMode = SND_PCM_ASYNC;
-  snd_pcm_stream_t stream;
-  snd_pcm_info_t *pcminfo;
-  snd_pcm_info_alloca( &pcminfo );
-  snd_pcm_t *phandle;
-  snd_pcm_hw_params_t *params;
-  snd_pcm_hw_params_alloca( &params );
-
-  // First try for playback unless default device (which has subdev -1)
-  stream = SND_PCM_STREAM_PLAYBACK;
-  snd_pcm_info_set_stream( pcminfo, stream );
-  if ( subdevice != -1 ) {
-    snd_pcm_info_set_device( pcminfo, subdevice );
-    snd_pcm_info_set_subdevice( pcminfo, 0 );
-
-    result = snd_ctl_pcm_info( chandle, pcminfo );
-    if ( result < 0 ) {
-      // Device probably doesn't support playback.
-      goto captureProbe;
-    }
-  }
-
-  result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK );
-  if ( result < 0 ) {
-    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    goto captureProbe;
-  }
-
-  // The device is open ... fill the parameter structure.
-  result = snd_pcm_hw_params_any( phandle, params );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    goto captureProbe;
-  }
-
-  // Get output channel information.
-  unsigned int value;
-  result = snd_pcm_hw_params_get_channels_max( params, &value );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::getDeviceInfo: error getting device (" << name << ") output channels, " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    goto captureProbe;
-  }
-  info.outputChannels = value;
-  snd_pcm_close( phandle );
-
- captureProbe:
-  stream = SND_PCM_STREAM_CAPTURE;
-  snd_pcm_info_set_stream( pcminfo, stream );
-
-  // Now try for capture unless default device (with subdev = -1)
-  if ( subdevice != -1 ) {
-    result = snd_ctl_pcm_info( chandle, pcminfo );
-    snd_ctl_close( chandle );
-    if ( result < 0 ) {
-      // Device probably doesn't support capture.
-      if ( info.outputChannels == 0 ) return info;
-      goto probeParameters;
-    }
-  }
-  else
-    snd_ctl_close( chandle );
-
-  result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK);
-  if ( result < 0 ) {
-    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    if ( info.outputChannels == 0 ) return info;
-    goto probeParameters;
-  }
-
-  // The device is open ... fill the parameter structure.
-  result = snd_pcm_hw_params_any( phandle, params );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    if ( info.outputChannels == 0 ) return info;
-    goto probeParameters;
-  }
-
-  result = snd_pcm_hw_params_get_channels_max( params, &value );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::getDeviceInfo: error getting device (" << name << ") input channels, " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    if ( info.outputChannels == 0 ) return info;
-    goto probeParameters;
-  }
-  info.inputChannels = value;
-  snd_pcm_close( phandle );
-
-  // If device opens for both playback and capture, we determine the channels.
-  if ( info.outputChannels > 0 && info.inputChannels > 0 )
-    info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-
-  // ALSA doesn't provide default devices so we'll use the first available one.
-  if ( device == 0 && info.outputChannels > 0 )
-    info.isDefaultOutput = true;
-  if ( device == 0 && info.inputChannels > 0 )
-    info.isDefaultInput = true;
-
- probeParameters:
-  // At this point, we just need to figure out the supported data
-  // formats and sample rates.  We'll proceed by opening the device in
-  // the direction with the maximum number of channels, or playback if
-  // they are equal.  This might limit our sample rate options, but so
-  // be it.
-
-  if ( info.outputChannels >= info.inputChannels )
-    stream = SND_PCM_STREAM_PLAYBACK;
-  else
-    stream = SND_PCM_STREAM_CAPTURE;
-  snd_pcm_info_set_stream( pcminfo, stream );
-
-  result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK);
-  if ( result < 0 ) {
-    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // The device is open ... fill the parameter structure.
-  result = snd_pcm_hw_params_any( phandle, params );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Test our discrete set of sample rate values.
-  info.sampleRates.clear();
-  for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
-    if ( snd_pcm_hw_params_test_rate( phandle, params, SAMPLE_RATES[i], 0 ) == 0 ) {
-      info.sampleRates.push_back( SAMPLE_RATES[i] );
-
-      if ( !info.preferredSampleRate || ( SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate ) )
-        info.preferredSampleRate = SAMPLE_RATES[i];
-    }
-  }
-  if ( info.sampleRates.size() == 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::getDeviceInfo: no supported sample rates found for device (" << name << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Probe the supported data formats ... we don't care about endian-ness just yet
-  snd_pcm_format_t format;
-  info.nativeFormats = 0;
-  format = SND_PCM_FORMAT_S8;
-  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
-    info.nativeFormats |= RTAUDIO_SINT8;
-  format = SND_PCM_FORMAT_S16;
-  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
-    info.nativeFormats |= RTAUDIO_SINT16;
-  format = SND_PCM_FORMAT_S24;
-  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
-    info.nativeFormats |= RTAUDIO_SINT24;
-  format = SND_PCM_FORMAT_S32;
-  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
-    info.nativeFormats |= RTAUDIO_SINT32;
-  format = SND_PCM_FORMAT_FLOAT;
-  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
-    info.nativeFormats |= RTAUDIO_FLOAT32;
-  format = SND_PCM_FORMAT_FLOAT64;
-  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
-    info.nativeFormats |= RTAUDIO_FLOAT64;
-
-  // Check that we have at least one supported format
-  if ( info.nativeFormats == 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::getDeviceInfo: pcm device (" << name << ") data format not supported by RtAudio.";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Get the device name
-  char *cardname;
-  result = snd_card_get_name( card, &cardname );
-  if ( result >= 0 ) {
-    sprintf( name, "hw:%s,%d", cardname, subdevice );
-    free( cardname );
-  }
-  info.name = name;
-
-  // That's all ... close the device and return
-  snd_pcm_close( phandle );
-  info.probed = true;
-  return info;
-}
-
-void RtApiAlsa :: saveDeviceInfo( void )
-{
-  devices_.clear();
-
-  unsigned int nDevices = getDeviceCount();
-  devices_.resize( nDevices );
-  for ( unsigned int i=0; i<nDevices; i++ )
-    devices_[i] = getDeviceInfo( i );
-}
-
-bool RtApiAlsa :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
-                                   unsigned int firstChannel, unsigned int sampleRate,
-                                   RtAudioFormat format, unsigned int *bufferSize,
-                                   RtAudio::StreamOptions *options )
-
-{
-#if defined(__RTAUDIO_DEBUG__)
-  snd_output_t *out;
-  snd_output_stdio_attach(&out, stderr, 0);
-#endif
-
-  // I'm not using the "plug" interface ... too much inconsistent behavior.
-
-  unsigned nDevices = 0;
-  int result, subdevice, card;
-  char name[64];
-  snd_ctl_t *chandle;
-
-  if ( options && options->flags & RTAUDIO_ALSA_USE_DEFAULT )
-    snprintf(name, sizeof(name), "%s", "default");
-  else {
-    // Count cards and devices
-    card = -1;
-    snd_card_next( &card );
-    while ( card >= 0 ) {
-      sprintf( name, "hw:%d", card );
-      result = snd_ctl_open( &chandle, name, SND_CTL_NONBLOCK );
-      if ( result < 0 ) {
-        errorStream_ << "RtApiAlsa::probeDeviceOpen: control open, card = " << card << ", " << snd_strerror( result ) << ".";
-        errorText_ = errorStream_.str();
-        return FAILURE;
-      }
-      subdevice = -1;
-      while( 1 ) {
-        result = snd_ctl_pcm_next_device( chandle, &subdevice );
-        if ( result < 0 ) break;
-        if ( subdevice < 0 ) break;
-        if ( nDevices == device ) {
-          sprintf( name, "hw:%d,%d", card, subdevice );
-          snd_ctl_close( chandle );
-          goto foundDevice;
-        }
-        nDevices++;
-      }
-      snd_ctl_close( chandle );
-      snd_card_next( &card );
-    }
-
-    result = snd_ctl_open( &chandle, "default", SND_CTL_NONBLOCK );
-    if ( result == 0 ) {
-      if ( nDevices == device ) {
-        strcpy( name, "default" );
-        snd_ctl_close( chandle );
-        goto foundDevice;
-      }
-      nDevices++;
-    }
-    snd_ctl_close( chandle );
-
-    if ( nDevices == 0 ) {
-      // This should not happen because a check is made before this function is called.
-      errorText_ = "RtApiAlsa::probeDeviceOpen: no devices found!";
-      return FAILURE;
-    }
-
-    if ( device >= nDevices ) {
-      // This should not happen because a check is made before this function is called.
-      errorText_ = "RtApiAlsa::probeDeviceOpen: device ID is invalid!";
-      return FAILURE;
-    }
-  }
-
- foundDevice:
-
-  // The getDeviceInfo() function will not work for a device that is
-  // already open.  Thus, we'll probe the system before opening a
-  // stream and save the results for use by getDeviceInfo().
-  if ( mode == OUTPUT || ( mode == INPUT && stream_.mode != OUTPUT ) ) // only do once
-    this->saveDeviceInfo();
-
-  snd_pcm_stream_t stream;
-  if ( mode == OUTPUT )
-    stream = SND_PCM_STREAM_PLAYBACK;
-  else
-    stream = SND_PCM_STREAM_CAPTURE;
-
-  snd_pcm_t *phandle;
-  int openMode = SND_PCM_ASYNC;
-  result = snd_pcm_open( &phandle, name, stream, openMode );
-  if ( result < 0 ) {
-    if ( mode == OUTPUT )
-      errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") won't open for output.";
-    else
-      errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") won't open for input.";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Fill the parameter structure.
-  snd_pcm_hw_params_t *hw_params;
-  snd_pcm_hw_params_alloca( &hw_params );
-  result = snd_pcm_hw_params_any( phandle, hw_params );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") parameters, " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-#if defined(__RTAUDIO_DEBUG__)
-  fprintf( stderr, "\nRtApiAlsa: dump hardware params just after device open:\n\n" );
-  snd_pcm_hw_params_dump( hw_params, out );
-#endif
-
-  // Set access ... check user preference.
-  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) {
-    stream_.userInterleaved = false;
-    result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED );
-    if ( result < 0 ) {
-      result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED );
-      stream_.deviceInterleaved[mode] =  true;
-    }
-    else
-      stream_.deviceInterleaved[mode] = false;
-  }
-  else {
-    stream_.userInterleaved = true;
-    result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED );
-    if ( result < 0 ) {
-      result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED );
-      stream_.deviceInterleaved[mode] =  false;
-    }
-    else
-      stream_.deviceInterleaved[mode] =  true;
-  }
-
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") access, " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Determine how to set the device format.
-  stream_.userFormat = format;
-  snd_pcm_format_t deviceFormat = SND_PCM_FORMAT_UNKNOWN;
-
-  if ( format == RTAUDIO_SINT8 )
-    deviceFormat = SND_PCM_FORMAT_S8;
-  else if ( format == RTAUDIO_SINT16 )
-    deviceFormat = SND_PCM_FORMAT_S16;
-  else if ( format == RTAUDIO_SINT24 )
-    deviceFormat = SND_PCM_FORMAT_S24;
-  else if ( format == RTAUDIO_SINT32 )
-    deviceFormat = SND_PCM_FORMAT_S32;
-  else if ( format == RTAUDIO_FLOAT32 )
-    deviceFormat = SND_PCM_FORMAT_FLOAT;
-  else if ( format == RTAUDIO_FLOAT64 )
-    deviceFormat = SND_PCM_FORMAT_FLOAT64;
-
-  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
-    stream_.deviceFormat[mode] = format;
-    goto setFormat;
-  }
-
-  // The user requested format is not natively supported by the device.
-  deviceFormat = SND_PCM_FORMAT_FLOAT64;
-  if ( snd_pcm_hw_params_test_format( phandle, hw_params, deviceFormat ) == 0 ) {
-    stream_.deviceFormat[mode] = RTAUDIO_FLOAT64;
-    goto setFormat;
-  }
-
-  deviceFormat = SND_PCM_FORMAT_FLOAT;
-  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
-    stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
-    goto setFormat;
-  }
-
-  deviceFormat = SND_PCM_FORMAT_S32;
-  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
-    stream_.deviceFormat[mode] = RTAUDIO_SINT32;
-    goto setFormat;
-  }
-
-  deviceFormat = SND_PCM_FORMAT_S24;
-  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
-    stream_.deviceFormat[mode] = RTAUDIO_SINT24;
-    goto setFormat;
-  }
-
-  deviceFormat = SND_PCM_FORMAT_S16;
-  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
-    stream_.deviceFormat[mode] = RTAUDIO_SINT16;
-    goto setFormat;
-  }
-
-  deviceFormat = SND_PCM_FORMAT_S8;
-  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
-    stream_.deviceFormat[mode] = RTAUDIO_SINT8;
-    goto setFormat;
-  }
-
-  // If we get here, no supported format was found.
-  snd_pcm_close( phandle );
-  errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device " << device << " data format not supported by RtAudio.";
-  errorText_ = errorStream_.str();
-  return FAILURE;
-
- setFormat:
-  result = snd_pcm_hw_params_set_format( phandle, hw_params, deviceFormat );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") data format, " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Determine whether byte-swaping is necessary.
-  stream_.doByteSwap[mode] = false;
-  if ( deviceFormat != SND_PCM_FORMAT_S8 ) {
-    result = snd_pcm_format_cpu_endian( deviceFormat );
-    if ( result == 0 )
-      stream_.doByteSwap[mode] = true;
-    else if (result < 0) {
-      snd_pcm_close( phandle );
-      errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") endian-ness, " << snd_strerror( result ) << ".";
-      errorText_ = errorStream_.str();
-      return FAILURE;
-    }
-  }
-
-  // Set the sample rate.
-  result = snd_pcm_hw_params_set_rate_near( phandle, hw_params, (unsigned int*) &sampleRate, 0 );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting sample rate on device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Determine the number of channels for this device.  We support a possible
-  // minimum device channel number > than the value requested by the user.
-  stream_.nUserChannels[mode] = channels;
-  unsigned int value;
-  result = snd_pcm_hw_params_get_channels_max( hw_params, &value );
-  unsigned int deviceChannels = value;
-  if ( result < 0 || deviceChannels < channels + firstChannel ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: requested channel parameters not supported by device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  result = snd_pcm_hw_params_get_channels_min( hw_params, &value );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting minimum channels for device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-  deviceChannels = value;
-  if ( deviceChannels < channels + firstChannel ) deviceChannels = channels + firstChannel;
-  stream_.nDeviceChannels[mode] = deviceChannels;
-
-  // Set the device channels.
-  result = snd_pcm_hw_params_set_channels( phandle, hw_params, deviceChannels );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting channels for device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Set the buffer (or period) size.
-  int dir = 0;
-  snd_pcm_uframes_t periodSize = *bufferSize;
-  result = snd_pcm_hw_params_set_period_size_near( phandle, hw_params, &periodSize, &dir );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting period size for device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-  *bufferSize = periodSize;
-
-  // Set the buffer number, which in ALSA is referred to as the "period".
-  unsigned int periods = 0;
-  if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) periods = 2;
-  if ( options && options->numberOfBuffers > 0 ) periods = options->numberOfBuffers;
-  if ( periods < 2 ) periods = 4; // a fairly safe default value
-  result = snd_pcm_hw_params_set_periods_near( phandle, hw_params, &periods, &dir );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting periods for device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // If attempting to setup a duplex stream, the bufferSize parameter
-  // MUST be the same in both directions!
-  if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << name << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  stream_.bufferSize = *bufferSize;
-
-  // Install the hardware configuration
-  result = snd_pcm_hw_params( phandle, hw_params );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing hardware configuration on device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-#if defined(__RTAUDIO_DEBUG__)
-  fprintf(stderr, "\nRtApiAlsa: dump hardware params after installation:\n\n");
-  snd_pcm_hw_params_dump( hw_params, out );
-#endif
-
-  // Set the software configuration to fill buffers with zeros and prevent device stopping on xruns.
-  snd_pcm_sw_params_t *sw_params = NULL;
-  snd_pcm_sw_params_alloca( &sw_params );
-  snd_pcm_sw_params_current( phandle, sw_params );
-  snd_pcm_sw_params_set_start_threshold( phandle, sw_params, *bufferSize );
-  snd_pcm_sw_params_set_stop_threshold( phandle, sw_params, ULONG_MAX );
-  snd_pcm_sw_params_set_silence_threshold( phandle, sw_params, 0 );
-
-  // The following two settings were suggested by Theo Veenker
-  //snd_pcm_sw_params_set_avail_min( phandle, sw_params, *bufferSize );
-  //snd_pcm_sw_params_set_xfer_align( phandle, sw_params, 1 );
-
-  // here are two options for a fix
-  //snd_pcm_sw_params_set_silence_size( phandle, sw_params, ULONG_MAX );
-  snd_pcm_uframes_t val;
-  snd_pcm_sw_params_get_boundary( sw_params, &val );
-  snd_pcm_sw_params_set_silence_size( phandle, sw_params, val );
-
-  result = snd_pcm_sw_params( phandle, sw_params );
-  if ( result < 0 ) {
-    snd_pcm_close( phandle );
-    errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing software configuration on device (" << name << "), " << snd_strerror( result ) << ".";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-#if defined(__RTAUDIO_DEBUG__)
-  fprintf(stderr, "\nRtApiAlsa: dump software params after installation:\n\n");
-  snd_pcm_sw_params_dump( sw_params, out );
-#endif
-
-  // Set flags for buffer conversion
-  stream_.doConvertBuffer[mode] = false;
-  if ( stream_.userFormat != stream_.deviceFormat[mode] )
-    stream_.doConvertBuffer[mode] = true;
-  if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
-    stream_.doConvertBuffer[mode] = true;
-  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
-       stream_.nUserChannels[mode] > 1 )
-    stream_.doConvertBuffer[mode] = true;
-
-  // Allocate the ApiHandle if necessary and then save.
-  AlsaHandle *apiInfo = 0;
-  if ( stream_.apiHandle == 0 ) {
-    try {
-      apiInfo = (AlsaHandle *) new AlsaHandle;
-    }
-    catch ( std::bad_alloc& ) {
-      errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating AlsaHandle memory.";
-      goto error;
-    }
-
-    if ( pthread_cond_init( &apiInfo->runnable_cv, NULL ) ) {
-      errorText_ = "RtApiAlsa::probeDeviceOpen: error initializing pthread condition variable.";
-      goto error;
-    }
-
-    stream_.apiHandle = (void *) apiInfo;
-    apiInfo->handles[0] = 0;
-    apiInfo->handles[1] = 0;
-  }
-  else {
-    apiInfo = (AlsaHandle *) stream_.apiHandle;
-  }
-  apiInfo->handles[mode] = phandle;
-  phandle = 0;
-
-  // Allocate necessary internal buffers.
-  unsigned long bufferBytes;
-  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
-  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
-  if ( stream_.userBuffer[mode] == NULL ) {
-    errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating user buffer memory.";
-    goto error;
-  }
-
-  if ( stream_.doConvertBuffer[mode] ) {
-
-    bool makeBuffer = true;
-    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
-    if ( mode == INPUT ) {
-      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
-        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
-        if ( bufferBytes <= bytesOut ) makeBuffer = false;
-      }
-    }
-
-    if ( makeBuffer ) {
-      bufferBytes *= *bufferSize;
-      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
-      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
-      if ( stream_.deviceBuffer == NULL ) {
-        errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating device buffer memory.";
-        goto error;
-      }
-    }
-  }
-
-  stream_.sampleRate = sampleRate;
-  stream_.nBuffers = periods;
-  stream_.device[mode] = device;
-  stream_.state = STREAM_STOPPED;
-
-  // Setup the buffer conversion information structure.
-  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
-
-  // Setup thread if necessary.
-  if ( stream_.mode == OUTPUT && mode == INPUT ) {
-    // We had already set up an output stream.
-    stream_.mode = DUPLEX;
-    // Link the streams if possible.
-    apiInfo->synchronized = false;
-    if ( snd_pcm_link( apiInfo->handles[0], apiInfo->handles[1] ) == 0 )
-      apiInfo->synchronized = true;
-    else {
-      errorText_ = "RtApiAlsa::probeDeviceOpen: unable to synchronize input and output devices.";
-      error( RtAudioError::WARNING );
-    }
-  }
-  else {
-    stream_.mode = mode;
-
-    // Setup callback thread.
-    stream_.callbackInfo.object = (void *) this;
-
-    // Set the thread attributes for joinable and realtime scheduling
-    // priority (optional).  The higher priority will only take affect
-    // if the program is run as root or suid. Note, under Linux
-    // processes with CAP_SYS_NICE privilege, a user can change
-    // scheduling policy and priority (thus need not be root). See
-    // POSIX "capabilities".
-    pthread_attr_t attr;
-    pthread_attr_init( &attr );
-    pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
-#ifdef SCHED_RR // Undefined with some OSes (e.g. NetBSD 1.6.x with GNU Pthread)
-    if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME ) {
-      stream_.callbackInfo.doRealtime = true;
-      struct sched_param param;
-      int priority = options->priority;
-      int min = sched_get_priority_min( SCHED_RR );
-      int max = sched_get_priority_max( SCHED_RR );
-      if ( priority < min ) priority = min;
-      else if ( priority > max ) priority = max;
-      param.sched_priority = priority;
-
-      // Set the policy BEFORE the priority. Otherwise it fails.
-      pthread_attr_setschedpolicy(&attr, SCHED_RR);
-      pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
-      // This is definitely required. Otherwise it fails.
-      pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
-      pthread_attr_setschedparam(&attr, &param);
-    }
-    else
-      pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
-#else
-    pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
-#endif
-
-    stream_.callbackInfo.isRunning = true;
-    result = pthread_create( &stream_.callbackInfo.thread, &attr, alsaCallbackHandler, &stream_.callbackInfo );
-    pthread_attr_destroy( &attr );
-    if ( result ) {
-      // Failed. Try instead with default attributes.
-      result = pthread_create( &stream_.callbackInfo.thread, NULL, alsaCallbackHandler, &stream_.callbackInfo );
-      if ( result ) {
-        stream_.callbackInfo.isRunning = false;
-        errorText_ = "RtApiAlsa::error creating callback thread!";
-        goto error;
-      }
-    }
-  }
-
-  return SUCCESS;
-
- error:
-  if ( apiInfo ) {
-    pthread_cond_destroy( &apiInfo->runnable_cv );
-    if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] );
-    if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] );
-    delete apiInfo;
-    stream_.apiHandle = 0;
-  }
-
-  if ( phandle) snd_pcm_close( phandle );
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  stream_.state = STREAM_CLOSED;
-  return FAILURE;
-}
-
-void RtApiAlsa :: closeStream()
-{
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiAlsa::closeStream(): no open stream to close!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
-  stream_.callbackInfo.isRunning = false;
-  MUTEX_LOCK( &stream_.mutex );
-  if ( stream_.state == STREAM_STOPPED ) {
-    apiInfo->runnable = true;
-    pthread_cond_signal( &apiInfo->runnable_cv );
-  }
-  MUTEX_UNLOCK( &stream_.mutex );
-  pthread_join( stream_.callbackInfo.thread, NULL );
-
-  if ( stream_.state == STREAM_RUNNING ) {
-    stream_.state = STREAM_STOPPED;
-    if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX )
-      snd_pcm_drop( apiInfo->handles[0] );
-    if ( stream_.mode == INPUT || stream_.mode == DUPLEX )
-      snd_pcm_drop( apiInfo->handles[1] );
-  }
-
-  if ( apiInfo ) {
-    pthread_cond_destroy( &apiInfo->runnable_cv );
-    if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] );
-    if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] );
-    delete apiInfo;
-    stream_.apiHandle = 0;
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  stream_.mode = UNINITIALIZED;
-  stream_.state = STREAM_CLOSED;
-}
-
-void RtApiAlsa :: startStream()
-{
-  // This method calls snd_pcm_prepare if the device isn't already in that state.
-
-  verifyStream();
-  if ( stream_.state == STREAM_RUNNING ) {
-    errorText_ = "RtApiAlsa::startStream(): the stream is already running!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  MUTEX_LOCK( &stream_.mutex );
-
-  #if defined( HAVE_GETTIMEOFDAY )
-  gettimeofday( &stream_.lastTickTimestamp, NULL );
-  #endif
-
-  int result = 0;
-  snd_pcm_state_t state;
-  AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
-  snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-    state = snd_pcm_state( handle[0] );
-    if ( state != SND_PCM_STATE_PREPARED ) {
-      result = snd_pcm_prepare( handle[0] );
-      if ( result < 0 ) {
-        errorStream_ << "RtApiAlsa::startStream: error preparing output pcm device, " << snd_strerror( result ) << ".";
-        errorText_ = errorStream_.str();
-        goto unlock;
-      }
-    }
-  }
-
-  if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) {
-    result = snd_pcm_drop(handle[1]); // fix to remove stale data received since device has been open
-    state = snd_pcm_state( handle[1] );
-    if ( state != SND_PCM_STATE_PREPARED ) {
-      result = snd_pcm_prepare( handle[1] );
-      if ( result < 0 ) {
-        errorStream_ << "RtApiAlsa::startStream: error preparing input pcm device, " << snd_strerror( result ) << ".";
-        errorText_ = errorStream_.str();
-        goto unlock;
-      }
-    }
-  }
-
-  stream_.state = STREAM_RUNNING;
-
- unlock:
-  apiInfo->runnable = true;
-  pthread_cond_signal( &apiInfo->runnable_cv );
-  MUTEX_UNLOCK( &stream_.mutex );
-
-  if ( result >= 0 ) return;
-  error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiAlsa :: stopStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiAlsa::stopStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  stream_.state = STREAM_STOPPED;
-  MUTEX_LOCK( &stream_.mutex );
-
-  int result = 0;
-  AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
-  snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-    if ( apiInfo->synchronized ) 
-      result = snd_pcm_drop( handle[0] );
-    else
-      result = snd_pcm_drain( handle[0] );
-    if ( result < 0 ) {
-      errorStream_ << "RtApiAlsa::stopStream: error draining output pcm device, " << snd_strerror( result ) << ".";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
-  if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) {
-    result = snd_pcm_drop( handle[1] );
-    if ( result < 0 ) {
-      errorStream_ << "RtApiAlsa::stopStream: error stopping input pcm device, " << snd_strerror( result ) << ".";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
- unlock:
-  apiInfo->runnable = false; // fixes high CPU usage when stopped
-  MUTEX_UNLOCK( &stream_.mutex );
-
-  if ( result >= 0 ) return;
-  error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiAlsa :: abortStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiAlsa::abortStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  stream_.state = STREAM_STOPPED;
-  MUTEX_LOCK( &stream_.mutex );
-
-  int result = 0;
-  AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
-  snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-    result = snd_pcm_drop( handle[0] );
-    if ( result < 0 ) {
-      errorStream_ << "RtApiAlsa::abortStream: error aborting output pcm device, " << snd_strerror( result ) << ".";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
-  if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) {
-    result = snd_pcm_drop( handle[1] );
-    if ( result < 0 ) {
-      errorStream_ << "RtApiAlsa::abortStream: error aborting input pcm device, " << snd_strerror( result ) << ".";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
- unlock:
-  apiInfo->runnable = false; // fixes high CPU usage when stopped
-  MUTEX_UNLOCK( &stream_.mutex );
-
-  if ( result >= 0 ) return;
-  error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiAlsa :: callbackEvent()
-{
-  AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
-  if ( stream_.state == STREAM_STOPPED ) {
-    MUTEX_LOCK( &stream_.mutex );
-    while ( !apiInfo->runnable )
-      pthread_cond_wait( &apiInfo->runnable_cv, &stream_.mutex );
-
-    if ( stream_.state != STREAM_RUNNING ) {
-      MUTEX_UNLOCK( &stream_.mutex );
-      return;
-    }
-    MUTEX_UNLOCK( &stream_.mutex );
-  }
-
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiAlsa::callbackEvent(): the stream is closed ... this shouldn't happen!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  int doStopStream = 0;
-  RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback;
-  double streamTime = getStreamTime();
-  RtAudioStreamStatus status = 0;
-  if ( stream_.mode != INPUT && apiInfo->xrun[0] == true ) {
-    status |= RTAUDIO_OUTPUT_UNDERFLOW;
-    apiInfo->xrun[0] = false;
-  }
-  if ( stream_.mode != OUTPUT && apiInfo->xrun[1] == true ) {
-    status |= RTAUDIO_INPUT_OVERFLOW;
-    apiInfo->xrun[1] = false;
-  }
-  doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1],
-                           stream_.bufferSize, streamTime, status, stream_.callbackInfo.userData );
-
-  if ( doStopStream == 2 ) {
-    abortStream();
-    return;
-  }
-
-  MUTEX_LOCK( &stream_.mutex );
-
-  // The state might change while waiting on a mutex.
-  if ( stream_.state == STREAM_STOPPED ) goto unlock;
-
-  int result;
-  char *buffer;
-  int channels;
-  snd_pcm_t **handle;
-  snd_pcm_sframes_t frames;
-  RtAudioFormat format;
-  handle = (snd_pcm_t **) apiInfo->handles;
-
-  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
-    // Setup parameters.
-    if ( stream_.doConvertBuffer[1] ) {
-      buffer = stream_.deviceBuffer;
-      channels = stream_.nDeviceChannels[1];
-      format = stream_.deviceFormat[1];
-    }
-    else {
-      buffer = stream_.userBuffer[1];
-      channels = stream_.nUserChannels[1];
-      format = stream_.userFormat;
-    }
-
-    // Read samples from device in interleaved/non-interleaved format.
-    if ( stream_.deviceInterleaved[1] )
-      result = snd_pcm_readi( handle[1], buffer, stream_.bufferSize );
-    else {
-      void *bufs[channels];
-      size_t offset = stream_.bufferSize * formatBytes( format );
-      for ( int i=0; i<channels; i++ )
-        bufs[i] = (void *) (buffer + (i * offset));
-      result = snd_pcm_readn( handle[1], bufs, stream_.bufferSize );
-    }
-
-    if ( result < (int) stream_.bufferSize ) {
-      // Either an error or overrun occured.
-      if ( result == -EPIPE ) {
-        snd_pcm_state_t state = snd_pcm_state( handle[1] );
-        if ( state == SND_PCM_STATE_XRUN ) {
-          apiInfo->xrun[1] = true;
-          result = snd_pcm_prepare( handle[1] );
-          if ( result < 0 ) {
-            errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after overrun, " << snd_strerror( result ) << ".";
-            errorText_ = errorStream_.str();
-          }
-        }
-        else {
-          errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << ".";
-          errorText_ = errorStream_.str();
-        }
-      }
-      else {
-        errorStream_ << "RtApiAlsa::callbackEvent: audio read error, " << snd_strerror( result ) << ".";
-        errorText_ = errorStream_.str();
-      }
-      error( RtAudioError::WARNING );
-      goto tryOutput;
-    }
-
-    // Do byte swapping if necessary.
-    if ( stream_.doByteSwap[1] )
-      byteSwapBuffer( buffer, stream_.bufferSize * channels, format );
-
-    // Do buffer conversion if necessary.
-    if ( stream_.doConvertBuffer[1] )
-      convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
-
-    // Check stream latency
-    result = snd_pcm_delay( handle[1], &frames );
-    if ( result == 0 && frames > 0 ) stream_.latency[1] = frames;
-  }
-
- tryOutput:
-
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
-    // Setup parameters and do buffer conversion if necessary.
-    if ( stream_.doConvertBuffer[0] ) {
-      buffer = stream_.deviceBuffer;
-      convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] );
-      channels = stream_.nDeviceChannels[0];
-      format = stream_.deviceFormat[0];
-    }
-    else {
-      buffer = stream_.userBuffer[0];
-      channels = stream_.nUserChannels[0];
-      format = stream_.userFormat;
-    }
-
-    // Do byte swapping if necessary.
-    if ( stream_.doByteSwap[0] )
-      byteSwapBuffer(buffer, stream_.bufferSize * channels, format);
-
-    // Write samples to device in interleaved/non-interleaved format.
-    if ( stream_.deviceInterleaved[0] )
-      result = snd_pcm_writei( handle[0], buffer, stream_.bufferSize );
-    else {
-      void *bufs[channels];
-      size_t offset = stream_.bufferSize * formatBytes( format );
-      for ( int i=0; i<channels; i++ )
-        bufs[i] = (void *) (buffer + (i * offset));
-      result = snd_pcm_writen( handle[0], bufs, stream_.bufferSize );
-    }
-
-    if ( result < (int) stream_.bufferSize ) {
-      // Either an error or underrun occured.
-      if ( result == -EPIPE ) {
-        snd_pcm_state_t state = snd_pcm_state( handle[0] );
-        if ( state == SND_PCM_STATE_XRUN ) {
-          apiInfo->xrun[0] = true;
-          result = snd_pcm_prepare( handle[0] );
-          if ( result < 0 ) {
-            errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << ".";
-            errorText_ = errorStream_.str();
-          }
-          else
-            errorText_ =  "RtApiAlsa::callbackEvent: audio write error, underrun.";
-        }
-        else {
-          errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << ".";
-          errorText_ = errorStream_.str();
-        }
-      }
-      else {
-        errorStream_ << "RtApiAlsa::callbackEvent: audio write error, " << snd_strerror( result ) << ".";
-        errorText_ = errorStream_.str();
-      }
-      error( RtAudioError::WARNING );
-      goto unlock;
-    }
-
-    // Check stream latency
-    result = snd_pcm_delay( handle[0], &frames );
-    if ( result == 0 && frames > 0 ) stream_.latency[0] = frames;
-  }
-
- unlock:
-  MUTEX_UNLOCK( &stream_.mutex );
-
-  RtApi::tickStreamTime();
-  if ( doStopStream == 1 ) this->stopStream();
-}
-
-static void *alsaCallbackHandler( void *ptr )
-{
-  CallbackInfo *info = (CallbackInfo *) ptr;
-  RtApiAlsa *object = (RtApiAlsa *) info->object;
-  bool *isRunning = &info->isRunning;
-
-#ifdef SCHED_RR // Undefined with some OSes (e.g. NetBSD 1.6.x with GNU Pthread)
-  if ( info->doRealtime ) {
-    std::cerr << "RtAudio alsa: " << 
-             (sched_getscheduler(0) == SCHED_RR ? "" : "_NOT_ ") << 
-             "running realtime scheduling" << std::endl;
-  }
-#endif
-
-  while ( *isRunning == true ) {
-    pthread_testcancel();
-    object->callbackEvent();
-  }
-
-  pthread_exit( NULL );
-}
-
-//******************** End of __LINUX_ALSA__ *********************//
-#endif
-
-#if defined(__LINUX_PULSE__)
-
-// Code written by Peter Meerwald, pmeerw@pmeerw.net
-// and Tristan Matthews.
-
-#include <pulse/error.h>
-#include <pulse/simple.h>
-#include <cstdio>
-
-static const unsigned int SUPPORTED_SAMPLERATES[] = { 8000, 16000, 22050, 32000,
-                                                      44100, 48000, 96000, 0};
-
-struct rtaudio_pa_format_mapping_t {
-  RtAudioFormat rtaudio_format;
-  pa_sample_format_t pa_format;
-};
-
-static const rtaudio_pa_format_mapping_t supported_sampleformats[] = {
-  {RTAUDIO_SINT16, PA_SAMPLE_S16LE},
-  {RTAUDIO_SINT32, PA_SAMPLE_S32LE},
-  {RTAUDIO_FLOAT32, PA_SAMPLE_FLOAT32LE},
-  {0, PA_SAMPLE_INVALID}};
-
-struct PulseAudioHandle {
-  pa_simple *s_play;
-  pa_simple *s_rec;
-  pthread_t thread;
-  pthread_cond_t runnable_cv;
-  bool runnable;
-  PulseAudioHandle() : s_play(0), s_rec(0), runnable(false) { }
-};
-
-RtApiPulse::~RtApiPulse()
-{
-  if ( stream_.state != STREAM_CLOSED )
-    closeStream();
-}
-
-unsigned int RtApiPulse::getDeviceCount( void )
-{
-  return 1;
-}
-
-RtAudio::DeviceInfo RtApiPulse::getDeviceInfo( unsigned int /*device*/ )
-{
-  RtAudio::DeviceInfo info;
-  info.probed = true;
-  info.name = "PulseAudio";
-  info.outputChannels = 2;
-  info.inputChannels = 2;
-  info.duplexChannels = 2;
-  info.isDefaultOutput = true;
-  info.isDefaultInput = true;
-
-  for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr )
-    info.sampleRates.push_back( *sr );
-
-  info.preferredSampleRate = 48000;
-  info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32;
-
-  return info;
-}
-
-static void *pulseaudio_callback( void * user )
-{
-  CallbackInfo *cbi = static_cast<CallbackInfo *>( user );
-  RtApiPulse *context = static_cast<RtApiPulse *>( cbi->object );
-  volatile bool *isRunning = &cbi->isRunning;
-  
-#ifdef SCHED_RR // Undefined with some OSes (e.g. NetBSD 1.6.x with GNU Pthread)
-  if (cbi->doRealtime) {
-    std::cerr << "RtAudio pulse: " << 
-             (sched_getscheduler(0) == SCHED_RR ? "" : "_NOT_ ") << 
-             "running realtime scheduling" << std::endl;
-  }
-#endif
-  
-  while ( *isRunning ) {
-    pthread_testcancel();
-    context->callbackEvent();
-  }
-
-  pthread_exit( NULL );
-}
-
-void RtApiPulse::closeStream( void )
-{
-  PulseAudioHandle *pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
-
-  stream_.callbackInfo.isRunning = false;
-  if ( pah ) {
-    MUTEX_LOCK( &stream_.mutex );
-    if ( stream_.state == STREAM_STOPPED ) {
-      pah->runnable = true;
-      pthread_cond_signal( &pah->runnable_cv );
-    }
-    MUTEX_UNLOCK( &stream_.mutex );
-
-    pthread_join( pah->thread, 0 );
-    if ( pah->s_play ) {
-      pa_simple_flush( pah->s_play, NULL );
-      pa_simple_free( pah->s_play );
-    }
-    if ( pah->s_rec )
-      pa_simple_free( pah->s_rec );
-
-    pthread_cond_destroy( &pah->runnable_cv );
-    delete pah;
-    stream_.apiHandle = 0;
-  }
-
-  if ( stream_.userBuffer[0] ) {
-    free( stream_.userBuffer[0] );
-    stream_.userBuffer[0] = 0;
-  }
-  if ( stream_.userBuffer[1] ) {
-    free( stream_.userBuffer[1] );
-    stream_.userBuffer[1] = 0;
-  }
-
-  stream_.state = STREAM_CLOSED;
-  stream_.mode = UNINITIALIZED;
-}
-
-void RtApiPulse::callbackEvent( void )
-{
-  PulseAudioHandle *pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
-
-  if ( stream_.state == STREAM_STOPPED ) {
-    MUTEX_LOCK( &stream_.mutex );
-    while ( !pah->runnable )
-      pthread_cond_wait( &pah->runnable_cv, &stream_.mutex );
-
-    if ( stream_.state != STREAM_RUNNING ) {
-      MUTEX_UNLOCK( &stream_.mutex );
-      return;
-    }
-    MUTEX_UNLOCK( &stream_.mutex );
-  }
-
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiPulse::callbackEvent(): the stream is closed ... "
-      "this shouldn't happen!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback;
-  double streamTime = getStreamTime();
-  RtAudioStreamStatus status = 0;
-  int doStopStream = callback( stream_.userBuffer[OUTPUT], stream_.userBuffer[INPUT],
-                               stream_.bufferSize, streamTime, status,
-                               stream_.callbackInfo.userData );
-
-  if ( doStopStream == 2 ) {
-    abortStream();
-    return;
-  }
-
-  MUTEX_LOCK( &stream_.mutex );
-  void *pulse_in = stream_.doConvertBuffer[INPUT] ? stream_.deviceBuffer : stream_.userBuffer[INPUT];
-  void *pulse_out = stream_.doConvertBuffer[OUTPUT] ? stream_.deviceBuffer : stream_.userBuffer[OUTPUT];
-
-  if ( stream_.state != STREAM_RUNNING )
-    goto unlock;
-
-  int pa_error;
-  size_t bytes;
-  if (stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-    if ( stream_.doConvertBuffer[OUTPUT] ) {
-        convertBuffer( stream_.deviceBuffer,
-                       stream_.userBuffer[OUTPUT],
-                       stream_.convertInfo[OUTPUT] );
-        bytes = stream_.nDeviceChannels[OUTPUT] * stream_.bufferSize *
-                formatBytes( stream_.deviceFormat[OUTPUT] );
-    } else
-        bytes = stream_.nUserChannels[OUTPUT] * stream_.bufferSize *
-                formatBytes( stream_.userFormat );
-
-    if ( pa_simple_write( pah->s_play, pulse_out, bytes, &pa_error ) < 0 ) {
-      errorStream_ << "RtApiPulse::callbackEvent: audio write error, " <<
-        pa_strerror( pa_error ) << ".";
-      errorText_ = errorStream_.str();
-      error( RtAudioError::WARNING );
-    }
-  }
-
-  if ( stream_.mode == INPUT || stream_.mode == DUPLEX) {
-    if ( stream_.doConvertBuffer[INPUT] )
-      bytes = stream_.nDeviceChannels[INPUT] * stream_.bufferSize *
-        formatBytes( stream_.deviceFormat[INPUT] );
-    else
-      bytes = stream_.nUserChannels[INPUT] * stream_.bufferSize *
-        formatBytes( stream_.userFormat );
-            
-    if ( pa_simple_read( pah->s_rec, pulse_in, bytes, &pa_error ) < 0 ) {
-      errorStream_ << "RtApiPulse::callbackEvent: audio read error, " <<
-        pa_strerror( pa_error ) << ".";
-      errorText_ = errorStream_.str();
-      error( RtAudioError::WARNING );
-    }
-    if ( stream_.doConvertBuffer[INPUT] ) {
-      convertBuffer( stream_.userBuffer[INPUT],
-                     stream_.deviceBuffer,
-                     stream_.convertInfo[INPUT] );
-    }
-  }
-
- unlock:
-  MUTEX_UNLOCK( &stream_.mutex );
-  RtApi::tickStreamTime();
-
-  if ( doStopStream == 1 )
-    stopStream();
-}
-
-void RtApiPulse::startStream( void )
-{
-  PulseAudioHandle *pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
-
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiPulse::startStream(): the stream is not open!";
-    error( RtAudioError::INVALID_USE );
-    return;
-  }
-  if ( stream_.state == STREAM_RUNNING ) {
-    errorText_ = "RtApiPulse::startStream(): the stream is already running!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  MUTEX_LOCK( &stream_.mutex );
-
-  #if defined( HAVE_GETTIMEOFDAY )
-  gettimeofday( &stream_.lastTickTimestamp, NULL );
-  #endif
-
-  stream_.state = STREAM_RUNNING;
-
-  pah->runnable = true;
-  pthread_cond_signal( &pah->runnable_cv );
-  MUTEX_UNLOCK( &stream_.mutex );
-}
-
-void RtApiPulse::stopStream( void )
-{
-  PulseAudioHandle *pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
-
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiPulse::stopStream(): the stream is not open!";
-    error( RtAudioError::INVALID_USE );
-    return;
-  }
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiPulse::stopStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  stream_.state = STREAM_STOPPED;
-  MUTEX_LOCK( &stream_.mutex );
-
-  if ( pah && pah->s_play ) {
-    int pa_error;
-    if ( pa_simple_drain( pah->s_play, &pa_error ) < 0 ) {
-      errorStream_ << "RtApiPulse::stopStream: error draining output device, " <<
-        pa_strerror( pa_error ) << ".";
-      errorText_ = errorStream_.str();
-      MUTEX_UNLOCK( &stream_.mutex );
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
-    }
-  }
-
-  stream_.state = STREAM_STOPPED;
-  MUTEX_UNLOCK( &stream_.mutex );
-}
-
-void RtApiPulse::abortStream( void )
-{
-  PulseAudioHandle *pah = static_cast<PulseAudioHandle*>( stream_.apiHandle );
-
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiPulse::abortStream(): the stream is not open!";
-    error( RtAudioError::INVALID_USE );
-    return;
-  }
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiPulse::abortStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  stream_.state = STREAM_STOPPED;
-  MUTEX_LOCK( &stream_.mutex );
-
-  if ( pah && pah->s_play ) {
-    int pa_error;
-    if ( pa_simple_flush( pah->s_play, &pa_error ) < 0 ) {
-      errorStream_ << "RtApiPulse::abortStream: error flushing output device, " <<
-        pa_strerror( pa_error ) << ".";
-      errorText_ = errorStream_.str();
-      MUTEX_UNLOCK( &stream_.mutex );
-      error( RtAudioError::SYSTEM_ERROR );
-      return;
-    }
-  }
-
-  stream_.state = STREAM_STOPPED;
-  MUTEX_UNLOCK( &stream_.mutex );
-}
-
-bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode,
-                                  unsigned int channels, unsigned int firstChannel,
-                                  unsigned int sampleRate, RtAudioFormat format,
-                                  unsigned int *bufferSize, RtAudio::StreamOptions *options )
-{
-  PulseAudioHandle *pah = 0;
-  unsigned long bufferBytes = 0;
-  pa_sample_spec ss;
-
-  if ( device != 0 ) return false;
-  if ( mode != INPUT && mode != OUTPUT ) return false;
-  if ( channels != 1 && channels != 2 ) {
-    errorText_ = "RtApiPulse::probeDeviceOpen: unsupported number of channels.";
-    return false;
-  }
-  ss.channels = channels;
-
-  if ( firstChannel != 0 ) return false;
-
-  bool sr_found = false;
-  for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr ) {
-    if ( sampleRate == *sr ) {
-      sr_found = true;
-      stream_.sampleRate = sampleRate;
-      ss.rate = sampleRate;
-      break;
-    }
-  }
-  if ( !sr_found ) {
-    errorText_ = "RtApiPulse::probeDeviceOpen: unsupported sample rate.";
-    return false;
-  }
-
-  bool sf_found = 0;
-  for ( const rtaudio_pa_format_mapping_t *sf = supported_sampleformats;
-        sf->rtaudio_format && sf->pa_format != PA_SAMPLE_INVALID; ++sf ) {
-    if ( format == sf->rtaudio_format ) {
-      sf_found = true;
-      stream_.userFormat = sf->rtaudio_format;
-      stream_.deviceFormat[mode] = stream_.userFormat;
-      ss.format = sf->pa_format;
-      break;
-    }
-  }
-  if ( !sf_found ) { // Use internal data format conversion.
-    stream_.userFormat = format;
-    stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
-    ss.format = PA_SAMPLE_FLOAT32LE;
-  }
-
-  // Set other stream parameters.
-  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
-  else stream_.userInterleaved = true;
-  stream_.deviceInterleaved[mode] = true;
-  stream_.nBuffers = 1;
-  stream_.doByteSwap[mode] = false;
-  stream_.nUserChannels[mode] = channels;
-  stream_.nDeviceChannels[mode] = channels + firstChannel;
-  stream_.channelOffset[mode] = 0;
-  std::string streamName = "RtAudio";
-
-  // Set flags for buffer conversion.
-  stream_.doConvertBuffer[mode] = false;
-  if ( stream_.userFormat != stream_.deviceFormat[mode] )
-    stream_.doConvertBuffer[mode] = true;
-  if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
-    stream_.doConvertBuffer[mode] = true;
-
-  // Allocate necessary internal buffers.
-  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
-  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
-  if ( stream_.userBuffer[mode] == NULL ) {
-    errorText_ = "RtApiPulse::probeDeviceOpen: error allocating user buffer memory.";
-    goto error;
-  }
-  stream_.bufferSize = *bufferSize;
-
-  if ( stream_.doConvertBuffer[mode] ) {
-
-    bool makeBuffer = true;
-    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
-    if ( mode == INPUT ) {
-      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
-        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
-        if ( bufferBytes <= bytesOut ) makeBuffer = false;
-      }
-    }
-
-    if ( makeBuffer ) {
-      bufferBytes *= *bufferSize;
-      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
-      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
-      if ( stream_.deviceBuffer == NULL ) {
-        errorText_ = "RtApiPulse::probeDeviceOpen: error allocating device buffer memory.";
-        goto error;
-      }
-    }
-  }
-
-  stream_.device[mode] = device;
-
-  // Setup the buffer conversion information structure.
-  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
-
-  if ( !stream_.apiHandle ) {
-    PulseAudioHandle *pah = new PulseAudioHandle;
-    if ( !pah ) {
-      errorText_ = "RtApiPulse::probeDeviceOpen: error allocating memory for handle.";
-      goto error;
-    }
-
-    stream_.apiHandle = pah;
-    if ( pthread_cond_init( &pah->runnable_cv, NULL ) != 0 ) {
-      errorText_ = "RtApiPulse::probeDeviceOpen: error creating condition variable.";
-      goto error;
-    }
-  }
-  pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
-
-  int error;
-  if ( options && !options->streamName.empty() ) streamName = options->streamName;
-  switch ( mode ) {
-  case INPUT:
-    pa_buffer_attr buffer_attr;
-    buffer_attr.fragsize = bufferBytes;
-    buffer_attr.maxlength = -1;
-
-    pah->s_rec = pa_simple_new( NULL, streamName.c_str(), PA_STREAM_RECORD, NULL, "Record", &ss, NULL, &buffer_attr, &error );
-    if ( !pah->s_rec ) {
-      errorText_ = "RtApiPulse::probeDeviceOpen: error connecting input to PulseAudio server.";
-      goto error;
-    }
-    break;
-  case OUTPUT:
-    pah->s_play = pa_simple_new( NULL, streamName.c_str(), PA_STREAM_PLAYBACK, NULL, "Playback", &ss, NULL, NULL, &error );
-    if ( !pah->s_play ) {
-      errorText_ = "RtApiPulse::probeDeviceOpen: error connecting output to PulseAudio server.";
-      goto error;
-    }
-    break;
-  default:
-    goto error;
-  }
-
-  if ( stream_.mode == UNINITIALIZED )
-    stream_.mode = mode;
-  else if ( stream_.mode == mode )
-    goto error;
-  else
-    stream_.mode = DUPLEX;
-
-  if ( !stream_.callbackInfo.isRunning ) {
-    stream_.callbackInfo.object = this;
-    
-    stream_.state = STREAM_STOPPED;
-    // Set the thread attributes for joinable and realtime scheduling
-    // priority (optional).  The higher priority will only take affect
-    // if the program is run as root or suid. Note, under Linux
-    // processes with CAP_SYS_NICE privilege, a user can change
-    // scheduling policy and priority (thus need not be root). See
-    // POSIX "capabilities".
-    pthread_attr_t attr;
-    pthread_attr_init( &attr );
-    pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
-#ifdef SCHED_RR // Undefined with some OSes (e.g. NetBSD 1.6.x with GNU Pthread)
-    if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME ) {
-      stream_.callbackInfo.doRealtime = true;
-      struct sched_param param;
-      int priority = options->priority;
-      int min = sched_get_priority_min( SCHED_RR );
-      int max = sched_get_priority_max( SCHED_RR );
-      if ( priority < min ) priority = min;
-      else if ( priority > max ) priority = max;
-      param.sched_priority = priority;
-      
-      // Set the policy BEFORE the priority. Otherwise it fails.
-      pthread_attr_setschedpolicy(&attr, SCHED_RR);
-      pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
-      // This is definitely required. Otherwise it fails.
-      pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
-      pthread_attr_setschedparam(&attr, &param);
-    }
-    else
-      pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
-#else
-    pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
-#endif
-
-    stream_.callbackInfo.isRunning = true;
-    int result = pthread_create( &pah->thread, &attr, pulseaudio_callback, (void *)&stream_.callbackInfo);
-    pthread_attr_destroy(&attr);
-    if(result != 0) {
-      // Failed. Try instead with default attributes.
-      result = pthread_create( &pah->thread, NULL, pulseaudio_callback, (void *)&stream_.callbackInfo);
-      if(result != 0) {
-        stream_.callbackInfo.isRunning = false;
-        errorText_ = "RtApiPulse::probeDeviceOpen: error creating thread.";
-        goto error;
-      }
-    }
-  }
-
-  return SUCCESS;
- 
- error:
-  if ( pah && stream_.callbackInfo.isRunning ) {
-    pthread_cond_destroy( &pah->runnable_cv );
-    delete pah;
-    stream_.apiHandle = 0;
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  stream_.state = STREAM_CLOSED;
-  return FAILURE;
-}
-
-//******************** End of __LINUX_PULSE__ *********************//
-#endif
-
-#if defined(__LINUX_OSS__)
-
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/soundcard.h>
-#include <errno.h>
-#include <math.h>
-
-static void *ossCallbackHandler(void * ptr);
-
-// A structure to hold various information related to the OSS API
-// implementation.
-struct OssHandle {
-  int id[2];    // device ids
-  bool xrun[2];
-  bool triggered;
-  pthread_cond_t runnable;
-
-  OssHandle()
-    :triggered(false) { id[0] = 0; id[1] = 0; xrun[0] = false; xrun[1] = false; }
-};
-
-RtApiOss :: RtApiOss()
-{
-  // Nothing to do here.
-}
-
-RtApiOss :: ~RtApiOss()
-{
-  if ( stream_.state != STREAM_CLOSED ) closeStream();
-}
-
-unsigned int RtApiOss :: getDeviceCount( void )
-{
-  int mixerfd = open( "/dev/mixer", O_RDWR, 0 );
-  if ( mixerfd == -1 ) {
-    errorText_ = "RtApiOss::getDeviceCount: error opening '/dev/mixer'.";
-    error( RtAudioError::WARNING );
-    return 0;
-  }
-
-  oss_sysinfo sysinfo;
-  if ( ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo ) == -1 ) {
-    close( mixerfd );
-    errorText_ = "RtApiOss::getDeviceCount: error getting sysinfo, OSS version >= 4.0 is required.";
-    error( RtAudioError::WARNING );
-    return 0;
-  }
-
-  close( mixerfd );
-  return sysinfo.numaudios;
-}
-
-RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device )
-{
-  RtAudio::DeviceInfo info;
-  info.probed = false;
-
-  int mixerfd = open( "/dev/mixer", O_RDWR, 0 );
-  if ( mixerfd == -1 ) {
-    errorText_ = "RtApiOss::getDeviceInfo: error opening '/dev/mixer'.";
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  oss_sysinfo sysinfo;
-  int result = ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo );
-  if ( result == -1 ) {
-    close( mixerfd );
-    errorText_ = "RtApiOss::getDeviceInfo: error getting sysinfo, OSS version >= 4.0 is required.";
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  unsigned nDevices = sysinfo.numaudios;
-  if ( nDevices == 0 ) {
-    close( mixerfd );
-    errorText_ = "RtApiOss::getDeviceInfo: no devices found!";
-    error( RtAudioError::INVALID_USE );
-    return info;
-  }
-
-  if ( device >= nDevices ) {
-    close( mixerfd );
-    errorText_ = "RtApiOss::getDeviceInfo: device ID is invalid!";
-    error( RtAudioError::INVALID_USE );
-    return info;
-  }
-
-  oss_audioinfo ainfo;
-  ainfo.dev = device;
-  result = ioctl( mixerfd, SNDCTL_AUDIOINFO, &ainfo );
-  close( mixerfd );
-  if ( result == -1 ) {
-    errorStream_ << "RtApiOss::getDeviceInfo: error getting device (" << ainfo.name << ") info.";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Probe channels
-  if ( ainfo.caps & PCM_CAP_OUTPUT ) info.outputChannels = ainfo.max_channels;
-  if ( ainfo.caps & PCM_CAP_INPUT ) info.inputChannels = ainfo.max_channels;
-  if ( ainfo.caps & PCM_CAP_DUPLEX ) {
-    if ( info.outputChannels > 0 && info.inputChannels > 0 && ainfo.caps & PCM_CAP_DUPLEX )
-      info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-  }
-
-  // Probe data formats ... do for input
-  unsigned long mask = ainfo.iformats;
-  if ( mask & AFMT_S16_LE || mask & AFMT_S16_BE )
-    info.nativeFormats |= RTAUDIO_SINT16;
-  if ( mask & AFMT_S8 )
-    info.nativeFormats |= RTAUDIO_SINT8;
-  if ( mask & AFMT_S32_LE || mask & AFMT_S32_BE )
-    info.nativeFormats |= RTAUDIO_SINT32;
-#ifdef AFMT_FLOAT
-  if ( mask & AFMT_FLOAT )
-    info.nativeFormats |= RTAUDIO_FLOAT32;
-#endif
-  if ( mask & AFMT_S24_LE || mask & AFMT_S24_BE )
-    info.nativeFormats |= RTAUDIO_SINT24;
-
-  // Check that we have at least one supported format
-  if ( info.nativeFormats == 0 ) {
-    errorStream_ << "RtApiOss::getDeviceInfo: device (" << ainfo.name << ") data format not supported by RtAudio.";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-    return info;
-  }
-
-  // Probe the supported sample rates.
-  info.sampleRates.clear();
-  if ( ainfo.nrates ) {
-    for ( unsigned int i=0; i<ainfo.nrates; i++ ) {
-      for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
-        if ( ainfo.rates[i] == SAMPLE_RATES[k] ) {
-          info.sampleRates.push_back( SAMPLE_RATES[k] );
-
-          if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
-            info.preferredSampleRate = SAMPLE_RATES[k];
-
-          break;
-        }
-      }
-    }
-  }
-  else {
-    // Check min and max rate values;
-    for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
-      if ( ainfo.min_rate <= (int) SAMPLE_RATES[k] && ainfo.max_rate >= (int) SAMPLE_RATES[k] ) {
-        info.sampleRates.push_back( SAMPLE_RATES[k] );
-
-        if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
-          info.preferredSampleRate = SAMPLE_RATES[k];
-      }
-    }
-  }
-
-  if ( info.sampleRates.size() == 0 ) {
-    errorStream_ << "RtApiOss::getDeviceInfo: no supported sample rates found for device (" << ainfo.name << ").";
-    errorText_ = errorStream_.str();
-    error( RtAudioError::WARNING );
-  }
-  else {
-    info.probed = true;
-    info.name = ainfo.name;
-  }
-
-  return info;
-}
-
-
-bool RtApiOss :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
-                                  unsigned int firstChannel, unsigned int sampleRate,
-                                  RtAudioFormat format, unsigned int *bufferSize,
-                                  RtAudio::StreamOptions *options )
-{
-  int mixerfd = open( "/dev/mixer", O_RDWR, 0 );
-  if ( mixerfd == -1 ) {
-    errorText_ = "RtApiOss::probeDeviceOpen: error opening '/dev/mixer'.";
-    return FAILURE;
-  }
-
-  oss_sysinfo sysinfo;
-  int result = ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo );
-  if ( result == -1 ) {
-    close( mixerfd );
-    errorText_ = "RtApiOss::probeDeviceOpen: error getting sysinfo, OSS version >= 4.0 is required.";
-    return FAILURE;
-  }
-
-  unsigned nDevices = sysinfo.numaudios;
-  if ( nDevices == 0 ) {
-    // This should not happen because a check is made before this function is called.
-    close( mixerfd );
-    errorText_ = "RtApiOss::probeDeviceOpen: no devices found!";
-    return FAILURE;
-  }
-
-  if ( device >= nDevices ) {
-    // This should not happen because a check is made before this function is called.
-    close( mixerfd );
-    errorText_ = "RtApiOss::probeDeviceOpen: device ID is invalid!";
-    return FAILURE;
-  }
-
-  oss_audioinfo ainfo;
-  ainfo.dev = device;
-  result = ioctl( mixerfd, SNDCTL_AUDIOINFO, &ainfo );
-  close( mixerfd );
-  if ( result == -1 ) {
-    errorStream_ << "RtApiOss::getDeviceInfo: error getting device (" << ainfo.name << ") info.";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Check if device supports input or output
-  if ( ( mode == OUTPUT && !( ainfo.caps & PCM_CAP_OUTPUT ) ) ||
-       ( mode == INPUT && !( ainfo.caps & PCM_CAP_INPUT ) ) ) {
-    if ( mode == OUTPUT )
-      errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support output.";
-    else
-      errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support input.";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  int flags = 0;
-  OssHandle *handle = (OssHandle *) stream_.apiHandle;
-  if ( mode == OUTPUT )
-    flags |= O_WRONLY;
-  else { // mode == INPUT
-    if (stream_.mode == OUTPUT && stream_.device[0] == device) {
-      // We just set the same device for playback ... close and reopen for duplex (OSS only).
-      close( handle->id[0] );
-      handle->id[0] = 0;
-      if ( !( ainfo.caps & PCM_CAP_DUPLEX ) ) {
-        errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support duplex mode.";
-        errorText_ = errorStream_.str();
-        return FAILURE;
-      }
-      // Check that the number previously set channels is the same.
-      if ( stream_.nUserChannels[0] != channels ) {
-        errorStream_ << "RtApiOss::probeDeviceOpen: input/output channels must be equal for OSS duplex device (" << ainfo.name << ").";
-        errorText_ = errorStream_.str();
-        return FAILURE;
-      }
-      flags |= O_RDWR;
-    }
-    else
-      flags |= O_RDONLY;
-  }
-
-  // Set exclusive access if specified.
-  if ( options && options->flags & RTAUDIO_HOG_DEVICE ) flags |= O_EXCL;
-
-  // Try to open the device.
-  int fd;
-  fd = open( ainfo.devnode, flags, 0 );
-  if ( fd == -1 ) {
-    if ( errno == EBUSY )
-      errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") is busy.";
-    else
-      errorStream_ << "RtApiOss::probeDeviceOpen: error opening device (" << ainfo.name << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // For duplex operation, specifically set this mode (this doesn't seem to work).
-  /*
-    if ( flags | O_RDWR ) {
-    result = ioctl( fd, SNDCTL_DSP_SETDUPLEX, NULL );
-    if ( result == -1) {
-    errorStream_ << "RtApiOss::probeDeviceOpen: error setting duplex mode for device (" << ainfo.name << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-    }
-    }
-  */
-
-  // Check the device channel support.
-  stream_.nUserChannels[mode] = channels;
-  if ( ainfo.max_channels < (int)(channels + firstChannel) ) {
-    close( fd );
-    errorStream_ << "RtApiOss::probeDeviceOpen: the device (" << ainfo.name << ") does not support requested channel parameters.";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Set the number of channels.
-  int deviceChannels = channels + firstChannel;
-  result = ioctl( fd, SNDCTL_DSP_CHANNELS, &deviceChannels );
-  if ( result == -1 || deviceChannels < (int)(channels + firstChannel) ) {
-    close( fd );
-    errorStream_ << "RtApiOss::probeDeviceOpen: error setting channel parameters on device (" << ainfo.name << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-  stream_.nDeviceChannels[mode] = deviceChannels;
-
-  // Get the data format mask
-  int mask;
-  result = ioctl( fd, SNDCTL_DSP_GETFMTS, &mask );
-  if ( result == -1 ) {
-    close( fd );
-    errorStream_ << "RtApiOss::probeDeviceOpen: error getting device (" << ainfo.name << ") data formats.";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Determine how to set the device format.
-  stream_.userFormat = format;
-  int deviceFormat = -1;
-  stream_.doByteSwap[mode] = false;
-  if ( format == RTAUDIO_SINT8 ) {
-    if ( mask & AFMT_S8 ) {
-      deviceFormat = AFMT_S8;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT8;
-    }
-  }
-  else if ( format == RTAUDIO_SINT16 ) {
-    if ( mask & AFMT_S16_NE ) {
-      deviceFormat = AFMT_S16_NE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT16;
-    }
-    else if ( mask & AFMT_S16_OE ) {
-      deviceFormat = AFMT_S16_OE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT16;
-      stream_.doByteSwap[mode] = true;
-    }
-  }
-  else if ( format == RTAUDIO_SINT24 ) {
-    if ( mask & AFMT_S24_NE ) {
-      deviceFormat = AFMT_S24_NE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT24;
-    }
-    else if ( mask & AFMT_S24_OE ) {
-      deviceFormat = AFMT_S24_OE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT24;
-      stream_.doByteSwap[mode] = true;
-    }
-  }
-  else if ( format == RTAUDIO_SINT32 ) {
-    if ( mask & AFMT_S32_NE ) {
-      deviceFormat = AFMT_S32_NE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT32;
-    }
-    else if ( mask & AFMT_S32_OE ) {
-      deviceFormat = AFMT_S32_OE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT32;
-      stream_.doByteSwap[mode] = true;
-    }
-  }
-
-  if ( deviceFormat == -1 ) {
-    // The user requested format is not natively supported by the device.
-    if ( mask & AFMT_S16_NE ) {
-      deviceFormat = AFMT_S16_NE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT16;
-    }
-    else if ( mask & AFMT_S32_NE ) {
-      deviceFormat = AFMT_S32_NE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT32;
-    }
-    else if ( mask & AFMT_S24_NE ) {
-      deviceFormat = AFMT_S24_NE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT24;
-    }
-    else if ( mask & AFMT_S16_OE ) {
-      deviceFormat = AFMT_S16_OE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT16;
-      stream_.doByteSwap[mode] = true;
-    }
-    else if ( mask & AFMT_S32_OE ) {
-      deviceFormat = AFMT_S32_OE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT32;
-      stream_.doByteSwap[mode] = true;
-    }
-    else if ( mask & AFMT_S24_OE ) {
-      deviceFormat = AFMT_S24_OE;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT24;
-      stream_.doByteSwap[mode] = true;
-    }
-    else if ( mask & AFMT_S8) {
-      deviceFormat = AFMT_S8;
-      stream_.deviceFormat[mode] = RTAUDIO_SINT8;
-    }
-  }
-
-  if ( stream_.deviceFormat[mode] == 0 ) {
-    // This really shouldn't happen ...
-    close( fd );
-    errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") data format not supported by RtAudio.";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Set the data format.
-  int temp = deviceFormat;
-  result = ioctl( fd, SNDCTL_DSP_SETFMT, &deviceFormat );
-  if ( result == -1 || deviceFormat != temp ) {
-    close( fd );
-    errorStream_ << "RtApiOss::probeDeviceOpen: error setting data format on device (" << ainfo.name << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Attempt to set the buffer size.  According to OSS, the minimum
-  // number of buffers is two.  The supposed minimum buffer size is 16
-  // bytes, so that will be our lower bound.  The argument to this
-  // call is in the form 0xMMMMSSSS (hex), where the buffer size (in
-  // bytes) is given as 2^SSSS and the number of buffers as 2^MMMM.
-  // We'll check the actual value used near the end of the setup
-  // procedure.
-  int ossBufferBytes = *bufferSize * formatBytes( stream_.deviceFormat[mode] ) * deviceChannels;
-  if ( ossBufferBytes < 16 ) ossBufferBytes = 16;
-  int buffers = 0;
-  if ( options ) buffers = options->numberOfBuffers;
-  if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) buffers = 2;
-  if ( buffers < 2 ) buffers = 3;
-  temp = ((int) buffers << 16) + (int)( log10( (double)ossBufferBytes ) / log10( 2.0 ) );
-  result = ioctl( fd, SNDCTL_DSP_SETFRAGMENT, &temp );
-  if ( result == -1 ) {
-    close( fd );
-    errorStream_ << "RtApiOss::probeDeviceOpen: error setting buffer size on device (" << ainfo.name << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-  stream_.nBuffers = buffers;
-
-  // Save buffer size (in sample frames).
-  *bufferSize = ossBufferBytes / ( formatBytes(stream_.deviceFormat[mode]) * deviceChannels );
-  stream_.bufferSize = *bufferSize;
-
-  // Set the sample rate.
-  int srate = sampleRate;
-  result = ioctl( fd, SNDCTL_DSP_SPEED, &srate );
-  if ( result == -1 ) {
-    close( fd );
-    errorStream_ << "RtApiOss::probeDeviceOpen: error setting sample rate (" << sampleRate << ") on device (" << ainfo.name << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-
-  // Verify the sample rate setup worked.
-  if ( abs( srate - (int)sampleRate ) > 100 ) {
-    close( fd );
-    errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support sample rate (" << sampleRate << ").";
-    errorText_ = errorStream_.str();
-    return FAILURE;
-  }
-  stream_.sampleRate = sampleRate;
-
-  if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] == device) {
-    // We're doing duplex setup here.
-    stream_.deviceFormat[0] = stream_.deviceFormat[1];
-    stream_.nDeviceChannels[0] = deviceChannels;
-  }
-
-  // Set interleaving parameters.
-  stream_.userInterleaved = true;
-  stream_.deviceInterleaved[mode] =  true;
-  if ( options && options->flags & RTAUDIO_NONINTERLEAVED )
-    stream_.userInterleaved = false;
-
-  // Set flags for buffer conversion
-  stream_.doConvertBuffer[mode] = false;
-  if ( stream_.userFormat != stream_.deviceFormat[mode] )
-    stream_.doConvertBuffer[mode] = true;
-  if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
-    stream_.doConvertBuffer[mode] = true;
-  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
-       stream_.nUserChannels[mode] > 1 )
-    stream_.doConvertBuffer[mode] = true;
-
-  // Allocate the stream handles if necessary and then save.
-  if ( stream_.apiHandle == 0 ) {
-    try {
-      handle = new OssHandle;
-    }
-    catch ( std::bad_alloc& ) {
-      errorText_ = "RtApiOss::probeDeviceOpen: error allocating OssHandle memory.";
-      goto error;
-    }
-
-    if ( pthread_cond_init( &handle->runnable, NULL ) ) {
-      errorText_ = "RtApiOss::probeDeviceOpen: error initializing pthread condition variable.";
-      goto error;
-    }
-
-    stream_.apiHandle = (void *) handle;
-  }
-  else {
-    handle = (OssHandle *) stream_.apiHandle;
-  }
-  handle->id[mode] = fd;
-
-  // Allocate necessary internal buffers.
-  unsigned long bufferBytes;
-  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
-  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
-  if ( stream_.userBuffer[mode] == NULL ) {
-    errorText_ = "RtApiOss::probeDeviceOpen: error allocating user buffer memory.";
-    goto error;
-  }
-
-  if ( stream_.doConvertBuffer[mode] ) {
-
-    bool makeBuffer = true;
-    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
-    if ( mode == INPUT ) {
-      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
-        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
-        if ( bufferBytes <= bytesOut ) makeBuffer = false;
-      }
-    }
-
-    if ( makeBuffer ) {
-      bufferBytes *= *bufferSize;
-      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
-      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
-      if ( stream_.deviceBuffer == NULL ) {
-        errorText_ = "RtApiOss::probeDeviceOpen: error allocating device buffer memory.";
-        goto error;
-      }
-    }
-  }
-
-  stream_.device[mode] = device;
-  stream_.state = STREAM_STOPPED;
-
-  // Setup the buffer conversion information structure.
-  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
-
-  // Setup thread if necessary.
-  if ( stream_.mode == OUTPUT && mode == INPUT ) {
-    // We had already set up an output stream.
-    stream_.mode = DUPLEX;
-    if ( stream_.device[0] == device ) handle->id[0] = fd;
-  }
-  else {
-    stream_.mode = mode;
-
-    // Setup callback thread.
-    stream_.callbackInfo.object = (void *) this;
-
-    // Set the thread attributes for joinable and realtime scheduling
-    // priority.  The higher priority will only take affect if the
-    // program is run as root or suid.
-    pthread_attr_t attr;
-    pthread_attr_init( &attr );
-    pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
-#ifdef SCHED_RR // Undefined with some OSes (e.g. NetBSD 1.6.x with GNU Pthread)
-    if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME ) {
-      stream_.callbackInfo.doRealtime = true;
-      struct sched_param param;
-      int priority = options->priority;
-      int min = sched_get_priority_min( SCHED_RR );
-      int max = sched_get_priority_max( SCHED_RR );
-      if ( priority < min ) priority = min;
-      else if ( priority > max ) priority = max;
-      param.sched_priority = priority;
-      
-      // Set the policy BEFORE the priority. Otherwise it fails.
-      pthread_attr_setschedpolicy(&attr, SCHED_RR);
-      pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
-      // This is definitely required. Otherwise it fails.
-      pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
-      pthread_attr_setschedparam(&attr, &param);
-    }
-    else
-      pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
-#else
-    pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
-#endif
-
-    stream_.callbackInfo.isRunning = true;
-    result = pthread_create( &stream_.callbackInfo.thread, &attr, ossCallbackHandler, &stream_.callbackInfo );
-    pthread_attr_destroy( &attr );
-    if ( result ) {
-      // Failed. Try instead with default attributes.
-      result = pthread_create( &stream_.callbackInfo.thread, NULL, ossCallbackHandler, &stream_.callbackInfo );
-      if ( result ) {
-        stream_.callbackInfo.isRunning = false;
-        errorText_ = "RtApiOss::error creating callback thread!";
-        goto error;
-      }
-    }
-  }
-
-  return SUCCESS;
-
- error:
-  if ( handle ) {
-    pthread_cond_destroy( &handle->runnable );
-    if ( handle->id[0] ) close( handle->id[0] );
-    if ( handle->id[1] ) close( handle->id[1] );
-    delete handle;
-    stream_.apiHandle = 0;
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  stream_.state = STREAM_CLOSED;
-  return FAILURE;
-}
-
-void RtApiOss :: closeStream()
-{
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiOss::closeStream(): no open stream to close!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  OssHandle *handle = (OssHandle *) stream_.apiHandle;
-  stream_.callbackInfo.isRunning = false;
-  MUTEX_LOCK( &stream_.mutex );
-  if ( stream_.state == STREAM_STOPPED )
-    pthread_cond_signal( &handle->runnable );
-  MUTEX_UNLOCK( &stream_.mutex );
-  pthread_join( stream_.callbackInfo.thread, NULL );
-
-  if ( stream_.state == STREAM_RUNNING ) {
-    if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX )
-      ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 );
-    else
-      ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 );
-    stream_.state = STREAM_STOPPED;
-  }
-
-  if ( handle ) {
-    pthread_cond_destroy( &handle->runnable );
-    if ( handle->id[0] ) close( handle->id[0] );
-    if ( handle->id[1] ) close( handle->id[1] );
-    delete handle;
-    stream_.apiHandle = 0;
-  }
-
-  for ( int i=0; i<2; i++ ) {
-    if ( stream_.userBuffer[i] ) {
-      free( stream_.userBuffer[i] );
-      stream_.userBuffer[i] = 0;
-    }
-  }
-
-  if ( stream_.deviceBuffer ) {
-    free( stream_.deviceBuffer );
-    stream_.deviceBuffer = 0;
-  }
-
-  stream_.mode = UNINITIALIZED;
-  stream_.state = STREAM_CLOSED;
-}
-
-void RtApiOss :: startStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_RUNNING ) {
-    errorText_ = "RtApiOss::startStream(): the stream is already running!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  MUTEX_LOCK( &stream_.mutex );
-
-  #if defined( HAVE_GETTIMEOFDAY )
-  gettimeofday( &stream_.lastTickTimestamp, NULL );
-  #endif
-
-  stream_.state = STREAM_RUNNING;
-
-  // No need to do anything else here ... OSS automatically starts
-  // when fed samples.
-
-  MUTEX_UNLOCK( &stream_.mutex );
-
-  OssHandle *handle = (OssHandle *) stream_.apiHandle;
-  pthread_cond_signal( &handle->runnable );
-}
-
-void RtApiOss :: stopStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiOss::stopStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  MUTEX_LOCK( &stream_.mutex );
-
-  // The state might change while waiting on a mutex.
-  if ( stream_.state == STREAM_STOPPED ) {
-    MUTEX_UNLOCK( &stream_.mutex );
-    return;
-  }
-
-  int result = 0;
-  OssHandle *handle = (OssHandle *) stream_.apiHandle;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
-    // Flush the output with zeros a few times.
-    char *buffer;
-    int samples;
-    RtAudioFormat format;
-
-    if ( stream_.doConvertBuffer[0] ) {
-      buffer = stream_.deviceBuffer;
-      samples = stream_.bufferSize * stream_.nDeviceChannels[0];
-      format = stream_.deviceFormat[0];
-    }
-    else {
-      buffer = stream_.userBuffer[0];
-      samples = stream_.bufferSize * stream_.nUserChannels[0];
-      format = stream_.userFormat;
-    }
-
-    memset( buffer, 0, samples * formatBytes(format) );
-    for ( unsigned int i=0; i<stream_.nBuffers+1; i++ ) {
-      result = write( handle->id[0], buffer, samples * formatBytes(format) );
-      if ( result == -1 ) {
-        errorText_ = "RtApiOss::stopStream: audio write error.";
-        error( RtAudioError::WARNING );
-      }
-    }
-
-    result = ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 );
-    if ( result == -1 ) {
-      errorStream_ << "RtApiOss::stopStream: system error stopping callback procedure on device (" << stream_.device[0] << ").";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-    handle->triggered = false;
-  }
-
-  if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && handle->id[0] != handle->id[1] ) ) {
-    result = ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 );
-    if ( result == -1 ) {
-      errorStream_ << "RtApiOss::stopStream: system error stopping input callback procedure on device (" << stream_.device[0] << ").";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
- unlock:
-  stream_.state = STREAM_STOPPED;
-  MUTEX_UNLOCK( &stream_.mutex );
-
-  if ( result != -1 ) return;
-  error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiOss :: abortStream()
-{
-  verifyStream();
-  if ( stream_.state == STREAM_STOPPED ) {
-    errorText_ = "RtApiOss::abortStream(): the stream is already stopped!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  MUTEX_LOCK( &stream_.mutex );
-
-  // The state might change while waiting on a mutex.
-  if ( stream_.state == STREAM_STOPPED ) {
-    MUTEX_UNLOCK( &stream_.mutex );
-    return;
-  }
-
-  int result = 0;
-  OssHandle *handle = (OssHandle *) stream_.apiHandle;
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-    result = ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 );
-    if ( result == -1 ) {
-      errorStream_ << "RtApiOss::abortStream: system error stopping callback procedure on device (" << stream_.device[0] << ").";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-    handle->triggered = false;
-  }
-
-  if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && handle->id[0] != handle->id[1] ) ) {
-    result = ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 );
-    if ( result == -1 ) {
-      errorStream_ << "RtApiOss::abortStream: system error stopping input callback procedure on device (" << stream_.device[0] << ").";
-      errorText_ = errorStream_.str();
-      goto unlock;
-    }
-  }
-
- unlock:
-  stream_.state = STREAM_STOPPED;
-  MUTEX_UNLOCK( &stream_.mutex );
-
-  if ( result != -1 ) return;
-  error( RtAudioError::SYSTEM_ERROR );
-}
-
-void RtApiOss :: callbackEvent()
-{
-  OssHandle *handle = (OssHandle *) stream_.apiHandle;
-  if ( stream_.state == STREAM_STOPPED ) {
-    MUTEX_LOCK( &stream_.mutex );
-    pthread_cond_wait( &handle->runnable, &stream_.mutex );
-    if ( stream_.state != STREAM_RUNNING ) {
-      MUTEX_UNLOCK( &stream_.mutex );
-      return;
-    }
-    MUTEX_UNLOCK( &stream_.mutex );
-  }
-
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApiOss::callbackEvent(): the stream is closed ... this shouldn't happen!";
-    error( RtAudioError::WARNING );
-    return;
-  }
-
-  // Invoke user callback to get fresh output data.
-  int doStopStream = 0;
-  RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback;
-  double streamTime = getStreamTime();
-  RtAudioStreamStatus status = 0;
-  if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
-    status |= RTAUDIO_OUTPUT_UNDERFLOW;
-    handle->xrun[0] = false;
-  }
-  if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
-    status |= RTAUDIO_INPUT_OVERFLOW;
-    handle->xrun[1] = false;
-  }
-  doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1],
-                           stream_.bufferSize, streamTime, status, stream_.callbackInfo.userData );
-  if ( doStopStream == 2 ) {
-    this->abortStream();
-    return;
-  }
-
-  MUTEX_LOCK( &stream_.mutex );
-
-  // The state might change while waiting on a mutex.
-  if ( stream_.state == STREAM_STOPPED ) goto unlock;
-
-  int result;
-  char *buffer;
-  int samples;
-  RtAudioFormat format;
-
-  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
-    // Setup parameters and do buffer conversion if necessary.
-    if ( stream_.doConvertBuffer[0] ) {
-      buffer = stream_.deviceBuffer;
-      convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] );
-      samples = stream_.bufferSize * stream_.nDeviceChannels[0];
-      format = stream_.deviceFormat[0];
-    }
-    else {
-      buffer = stream_.userBuffer[0];
-      samples = stream_.bufferSize * stream_.nUserChannels[0];
-      format = stream_.userFormat;
-    }
-
-    // Do byte swapping if necessary.
-    if ( stream_.doByteSwap[0] )
-      byteSwapBuffer( buffer, samples, format );
-
-    if ( stream_.mode == DUPLEX && handle->triggered == false ) {
-      int trig = 0;
-      ioctl( handle->id[0], SNDCTL_DSP_SETTRIGGER, &trig );
-      result = write( handle->id[0], buffer, samples * formatBytes(format) );
-      trig = PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT;
-      ioctl( handle->id[0], SNDCTL_DSP_SETTRIGGER, &trig );
-      handle->triggered = true;
-    }
-    else
-      // Write samples to device.
-      result = write( handle->id[0], buffer, samples * formatBytes(format) );
-
-    if ( result == -1 ) {
-      // We'll assume this is an underrun, though there isn't a
-      // specific means for determining that.
-      handle->xrun[0] = true;
-      errorText_ = "RtApiOss::callbackEvent: audio write error.";
-      error( RtAudioError::WARNING );
-      // Continue on to input section.
-    }
-  }
-
-  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
-    // Setup parameters.
-    if ( stream_.doConvertBuffer[1] ) {
-      buffer = stream_.deviceBuffer;
-      samples = stream_.bufferSize * stream_.nDeviceChannels[1];
-      format = stream_.deviceFormat[1];
-    }
-    else {
-      buffer = stream_.userBuffer[1];
-      samples = stream_.bufferSize * stream_.nUserChannels[1];
-      format = stream_.userFormat;
-    }
-
-    // Read samples from device.
-    result = read( handle->id[1], buffer, samples * formatBytes(format) );
-
-    if ( result == -1 ) {
-      // We'll assume this is an overrun, though there isn't a
-      // specific means for determining that.
-      handle->xrun[1] = true;
-      errorText_ = "RtApiOss::callbackEvent: audio read error.";
-      error( RtAudioError::WARNING );
-      goto unlock;
-    }
-
-    // Do byte swapping if necessary.
-    if ( stream_.doByteSwap[1] )
-      byteSwapBuffer( buffer, samples, format );
-
-    // Do buffer conversion if necessary.
-    if ( stream_.doConvertBuffer[1] )
-      convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
-  }
-
- unlock:
-  MUTEX_UNLOCK( &stream_.mutex );
-
-  RtApi::tickStreamTime();
-  if ( doStopStream == 1 ) this->stopStream();
-}
-
-static void *ossCallbackHandler( void *ptr )
-{
-  CallbackInfo *info = (CallbackInfo *) ptr;
-  RtApiOss *object = (RtApiOss *) info->object;
-  bool *isRunning = &info->isRunning;
-
-#ifdef SCHED_RR // Undefined with some OSes (e.g. NetBSD 1.6.x with GNU Pthread)
-  if (info->doRealtime) {
-    std::cerr << "RtAudio oss: " << 
-             (sched_getscheduler(0) == SCHED_RR ? "" : "_NOT_ ") << 
-             "running realtime scheduling" << std::endl;
-  }
-#endif
-
-  while ( *isRunning == true ) {
-    pthread_testcancel();
-    object->callbackEvent();
-  }
-
-  pthread_exit( NULL );
-}
-
-//******************** End of __LINUX_OSS__ *********************//
-#endif
-
-
-// *************************************************** //
-//
-// Protected common (OS-independent) RtAudio methods.
-//
-// *************************************************** //
-
-// This method can be modified to control the behavior of error
-// message printing.
-void RtApi :: error( RtAudioError::Type type )
-{
-  errorStream_.str(""); // clear the ostringstream
-
-  RtAudioErrorCallback errorCallback = (RtAudioErrorCallback) stream_.callbackInfo.errorCallback;
-  if ( errorCallback ) {
-    // abortStream() can generate new error messages. Ignore them. Just keep original one.
-
-    if ( firstErrorOccurred_ )
-      return;
-
-    firstErrorOccurred_ = true;
-    const std::string errorMessage = errorText_;
-
-    if ( type != RtAudioError::WARNING && stream_.state != STREAM_STOPPED) {
-      stream_.callbackInfo.isRunning = false; // exit from the thread
-      abortStream();
-    }
-
-    errorCallback( type, errorMessage );
-    firstErrorOccurred_ = false;
-    return;
-  }
-
-  if ( type == RtAudioError::WARNING && showWarnings_ == true )
-    std::cerr << '\n' << errorText_ << "\n\n";
-  else if ( type != RtAudioError::WARNING )
-    throw( RtAudioError( errorText_, type ) );
-}
-
-void RtApi :: verifyStream()
-{
-  if ( stream_.state == STREAM_CLOSED ) {
-    errorText_ = "RtApi:: a stream is not open!";
-    error( RtAudioError::INVALID_USE );
-  }
-}
-
-void RtApi :: clearStreamInfo()
-{
-  stream_.mode = UNINITIALIZED;
-  stream_.state = STREAM_CLOSED;
-  stream_.sampleRate = 0;
-  stream_.bufferSize = 0;
-  stream_.nBuffers = 0;
-  stream_.userFormat = 0;
-  stream_.userInterleaved = true;
-  stream_.streamTime = 0.0;
-  stream_.apiHandle = 0;
-  stream_.deviceBuffer = 0;
-  stream_.callbackInfo.callback = 0;
-  stream_.callbackInfo.userData = 0;
-  stream_.callbackInfo.isRunning = false;
-  stream_.callbackInfo.errorCallback = 0;
-  for ( int i=0; i<2; i++ ) {
-    stream_.device[i] = 11111;
-    stream_.doConvertBuffer[i] = false;
-    stream_.deviceInterleaved[i] = true;
-    stream_.doByteSwap[i] = false;
-    stream_.nUserChannels[i] = 0;
-    stream_.nDeviceChannels[i] = 0;
-    stream_.channelOffset[i] = 0;
-    stream_.deviceFormat[i] = 0;
-    stream_.latency[i] = 0;
-    stream_.userBuffer[i] = 0;
-    stream_.convertInfo[i].channels = 0;
-    stream_.convertInfo[i].inJump = 0;
-    stream_.convertInfo[i].outJump = 0;
-    stream_.convertInfo[i].inFormat = 0;
-    stream_.convertInfo[i].outFormat = 0;
-    stream_.convertInfo[i].inOffset.clear();
-    stream_.convertInfo[i].outOffset.clear();
-  }
-}
-
-unsigned int RtApi :: formatBytes( RtAudioFormat format )
-{
-  if ( format == RTAUDIO_SINT16 )
-    return 2;
-  else if ( format == RTAUDIO_SINT32 || format == RTAUDIO_FLOAT32 )
-    return 4;
-  else if ( format == RTAUDIO_FLOAT64 )
-    return 8;
-  else if ( format == RTAUDIO_SINT24 )
-    return 3;
-  else if ( format == RTAUDIO_SINT8 )
-    return 1;
-
-  errorText_ = "RtApi::formatBytes: undefined format.";
-  error( RtAudioError::WARNING );
-
-  return 0;
-}
-
-void RtApi :: setConvertInfo( StreamMode mode, unsigned int firstChannel )
-{
-  if ( mode == INPUT ) { // convert device to user buffer
-    stream_.convertInfo[mode].inJump = stream_.nDeviceChannels[1];
-    stream_.convertInfo[mode].outJump = stream_.nUserChannels[1];
-    stream_.convertInfo[mode].inFormat = stream_.deviceFormat[1];
-    stream_.convertInfo[mode].outFormat = stream_.userFormat;
-  }
-  else { // convert user to device buffer
-    stream_.convertInfo[mode].inJump = stream_.nUserChannels[0];
-    stream_.convertInfo[mode].outJump = stream_.nDeviceChannels[0];
-    stream_.convertInfo[mode].inFormat = stream_.userFormat;
-    stream_.convertInfo[mode].outFormat = stream_.deviceFormat[0];
-  }
-
-  if ( stream_.convertInfo[mode].inJump < stream_.convertInfo[mode].outJump )
-    stream_.convertInfo[mode].channels = stream_.convertInfo[mode].inJump;
-  else
-    stream_.convertInfo[mode].channels = stream_.convertInfo[mode].outJump;
-
-  // Set up the interleave/deinterleave offsets.
-  if ( stream_.deviceInterleaved[mode] != stream_.userInterleaved ) {
-    if ( ( mode == OUTPUT && stream_.deviceInterleaved[mode] ) ||
-         ( mode == INPUT && stream_.userInterleaved ) ) {
-      for ( int k=0; k<stream_.convertInfo[mode].channels; k++ ) {
-        stream_.convertInfo[mode].inOffset.push_back( k * stream_.bufferSize );
-        stream_.convertInfo[mode].outOffset.push_back( k );
-        stream_.convertInfo[mode].inJump = 1;
-      }
-    }
-    else {
-      for ( int k=0; k<stream_.convertInfo[mode].channels; k++ ) {
-        stream_.convertInfo[mode].inOffset.push_back( k );
-        stream_.convertInfo[mode].outOffset.push_back( k * stream_.bufferSize );
-        stream_.convertInfo[mode].outJump = 1;
-      }
-    }
-  }
-  else { // no (de)interleaving
-    if ( stream_.userInterleaved ) {
-      for ( int k=0; k<stream_.convertInfo[mode].channels; k++ ) {
-        stream_.convertInfo[mode].inOffset.push_back( k );
-        stream_.convertInfo[mode].outOffset.push_back( k );
-      }
-    }
-    else {
-      for ( int k=0; k<stream_.convertInfo[mode].channels; k++ ) {
-        stream_.convertInfo[mode].inOffset.push_back( k * stream_.bufferSize );
-        stream_.convertInfo[mode].outOffset.push_back( k * stream_.bufferSize );
-        stream_.convertInfo[mode].inJump = 1;
-        stream_.convertInfo[mode].outJump = 1;
-      }
-    }
-  }
-
-  // Add channel offset.
-  if ( firstChannel > 0 ) {
-    if ( stream_.deviceInterleaved[mode] ) {
-      if ( mode == OUTPUT ) {
-        for ( int k=0; k<stream_.convertInfo[mode].channels; k++ )
-          stream_.convertInfo[mode].outOffset[k] += firstChannel;
-      }
-      else {
-        for ( int k=0; k<stream_.convertInfo[mode].channels; k++ )
-          stream_.convertInfo[mode].inOffset[k] += firstChannel;
-      }
-    }
-    else {
-      if ( mode == OUTPUT ) {
-        for ( int k=0; k<stream_.convertInfo[mode].channels; k++ )
-          stream_.convertInfo[mode].outOffset[k] += ( firstChannel * stream_.bufferSize );
-      }
-      else {
-        for ( int k=0; k<stream_.convertInfo[mode].channels; k++ )
-          stream_.convertInfo[mode].inOffset[k] += ( firstChannel  * stream_.bufferSize );
-      }
-    }
-  }
-}
-
-void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info )
-{
-  // This function does format conversion, input/output channel compensation, and
-  // data interleaving/deinterleaving.  24-bit integers are assumed to occupy
-  // the lower three bytes of a 32-bit integer.
-
-  // Clear our device buffer when in/out duplex device channels are different
-  if ( outBuffer == stream_.deviceBuffer && stream_.mode == DUPLEX &&
-       ( stream_.nDeviceChannels[0] < stream_.nDeviceChannels[1] ) )
-    memset( outBuffer, 0, stream_.bufferSize * info.outJump * formatBytes( info.outFormat ) );
-
-  int j;
-  if (info.outFormat == RTAUDIO_FLOAT64) {
-    Float64 scale;
-    Float64 *out = (Float64 *)outBuffer;
-
-    if (info.inFormat == RTAUDIO_SINT8) {
-      signed char *in = (signed char *)inBuffer;
-      scale = 1.0 / 127.5;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Float64) in[info.inOffset[j]];
-          out[info.outOffset[j]] += 0.5;
-          out[info.outOffset[j]] *= scale;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT16) {
-      Int16 *in = (Int16 *)inBuffer;
-      scale = 1.0 / 32767.5;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Float64) in[info.inOffset[j]];
-          out[info.outOffset[j]] += 0.5;
-          out[info.outOffset[j]] *= scale;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT24) {
-      Int24 *in = (Int24 *)inBuffer;
-      scale = 1.0 / 8388607.5;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Float64) (in[info.inOffset[j]].asInt());
-          out[info.outOffset[j]] += 0.5;
-          out[info.outOffset[j]] *= scale;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT32) {
-      Int32 *in = (Int32 *)inBuffer;
-      scale = 1.0 / 2147483647.5;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Float64) in[info.inOffset[j]];
-          out[info.outOffset[j]] += 0.5;
-          out[info.outOffset[j]] *= scale;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT32) {
-      Float32 *in = (Float32 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Float64) in[info.inOffset[j]];
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT64) {
-      // Channel compensation and/or (de)interleaving only.
-      Float64 *in = (Float64 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = in[info.inOffset[j]];
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-  }
-  else if (info.outFormat == RTAUDIO_FLOAT32) {
-    Float32 scale;
-    Float32 *out = (Float32 *)outBuffer;
-
-    if (info.inFormat == RTAUDIO_SINT8) {
-      signed char *in = (signed char *)inBuffer;
-      scale = (Float32) ( 1.0 / 127.5 );
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Float32) in[info.inOffset[j]];
-          out[info.outOffset[j]] += 0.5;
-          out[info.outOffset[j]] *= scale;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT16) {
-      Int16 *in = (Int16 *)inBuffer;
-      scale = (Float32) ( 1.0 / 32767.5 );
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Float32) in[info.inOffset[j]];
-          out[info.outOffset[j]] += 0.5;
-          out[info.outOffset[j]] *= scale;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT24) {
-      Int24 *in = (Int24 *)inBuffer;
-      scale = (Float32) ( 1.0 / 8388607.5 );
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Float32) (in[info.inOffset[j]].asInt());
-          out[info.outOffset[j]] += 0.5;
-          out[info.outOffset[j]] *= scale;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT32) {
-      Int32 *in = (Int32 *)inBuffer;
-      scale = (Float32) ( 1.0 / 2147483647.5 );
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Float32) in[info.inOffset[j]];
-          out[info.outOffset[j]] += 0.5;
-          out[info.outOffset[j]] *= scale;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT32) {
-      // Channel compensation and/or (de)interleaving only.
-      Float32 *in = (Float32 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = in[info.inOffset[j]];
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT64) {
-      Float64 *in = (Float64 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Float32) in[info.inOffset[j]];
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-  }
-  else if (info.outFormat == RTAUDIO_SINT32) {
-    Int32 *out = (Int32 *)outBuffer;
-    if (info.inFormat == RTAUDIO_SINT8) {
-      signed char *in = (signed char *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]];
-          out[info.outOffset[j]] <<= 24;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT16) {
-      Int16 *in = (Int16 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]];
-          out[info.outOffset[j]] <<= 16;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT24) {
-      Int24 *in = (Int24 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]].asInt();
-          out[info.outOffset[j]] <<= 8;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT32) {
-      // Channel compensation and/or (de)interleaving only.
-      Int32 *in = (Int32 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = in[info.inOffset[j]];
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT32) {
-      Float32 *in = (Float32 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] * 2147483647.5 - 0.5);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT64) {
-      Float64 *in = (Float64 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] * 2147483647.5 - 0.5);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-  }
-  else if (info.outFormat == RTAUDIO_SINT24) {
-    Int24 *out = (Int24 *)outBuffer;
-    if (info.inFormat == RTAUDIO_SINT8) {
-      signed char *in = (signed char *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] << 16);
-          //out[info.outOffset[j]] <<= 16;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT16) {
-      Int16 *in = (Int16 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] << 8);
-          //out[info.outOffset[j]] <<= 8;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT24) {
-      // Channel compensation and/or (de)interleaving only.
-      Int24 *in = (Int24 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = in[info.inOffset[j]];
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT32) {
-      Int32 *in = (Int32 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] >> 8);
-          //out[info.outOffset[j]] >>= 8;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT32) {
-      Float32 *in = (Float32 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] * 8388607.5 - 0.5);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT64) {
-      Float64 *in = (Float64 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] * 8388607.5 - 0.5);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-  }
-  else if (info.outFormat == RTAUDIO_SINT16) {
-    Int16 *out = (Int16 *)outBuffer;
-    if (info.inFormat == RTAUDIO_SINT8) {
-      signed char *in = (signed char *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int16) in[info.inOffset[j]];
-          out[info.outOffset[j]] <<= 8;
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT16) {
-      // Channel compensation and/or (de)interleaving only.
-      Int16 *in = (Int16 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = in[info.inOffset[j]];
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT24) {
-      Int24 *in = (Int24 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int16) (in[info.inOffset[j]].asInt() >> 8);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT32) {
-      Int32 *in = (Int32 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int16) ((in[info.inOffset[j]] >> 16) & 0x0000ffff);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT32) {
-      Float32 *in = (Float32 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int16) (in[info.inOffset[j]] * 32767.5 - 0.5);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT64) {
-      Float64 *in = (Float64 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (Int16) (in[info.inOffset[j]] * 32767.5 - 0.5);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-  }
-  else if (info.outFormat == RTAUDIO_SINT8) {
-    signed char *out = (signed char *)outBuffer;
-    if (info.inFormat == RTAUDIO_SINT8) {
-      // Channel compensation and/or (de)interleaving only.
-      signed char *in = (signed char *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = in[info.inOffset[j]];
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    if (info.inFormat == RTAUDIO_SINT16) {
-      Int16 *in = (Int16 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (signed char) ((in[info.inOffset[j]] >> 8) & 0x00ff);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT24) {
-      Int24 *in = (Int24 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (signed char) (in[info.inOffset[j]].asInt() >> 16);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_SINT32) {
-      Int32 *in = (Int32 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (signed char) ((in[info.inOffset[j]] >> 24) & 0x000000ff);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT32) {
-      Float32 *in = (Float32 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (signed char) (in[info.inOffset[j]] * 127.5 - 0.5);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-    else if (info.inFormat == RTAUDIO_FLOAT64) {
-      Float64 *in = (Float64 *)inBuffer;
-      for (unsigned int i=0; i<stream_.bufferSize; i++) {
-        for (j=0; j<info.channels; j++) {
-          out[info.outOffset[j]] = (signed char) (in[info.inOffset[j]] * 127.5 - 0.5);
-        }
-        in += info.inJump;
-        out += info.outJump;
-      }
-    }
-  }
-}
-
-//static inline uint16_t bswap_16(uint16_t x) { return (x>>8) | (x<<8); }
-//static inline uint32_t bswap_32(uint32_t x) { return (bswap_16(x&0xffff)<<16) | (bswap_16(x>>16)); }
-//static inline uint64_t bswap_64(uint64_t x) { return (((unsigned long long)bswap_32(x&0xffffffffull))<<32) | (bswap_32(x>>32)); }
-
-void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format )
-{
-  char val;
-  char *ptr;
-
-  ptr = buffer;
-  if ( format == RTAUDIO_SINT16 ) {
-    for ( unsigned int i=0; i<samples; i++ ) {
-      // Swap 1st and 2nd bytes.
-      val = *(ptr);
-      *(ptr) = *(ptr+1);
-      *(ptr+1) = val;
-
-      // Increment 2 bytes.
-      ptr += 2;
-    }
-  }
-  else if ( format == RTAUDIO_SINT32 ||
-            format == RTAUDIO_FLOAT32 ) {
-    for ( unsigned int i=0; i<samples; i++ ) {
-      // Swap 1st and 4th bytes.
-      val = *(ptr);
-      *(ptr) = *(ptr+3);
-      *(ptr+3) = val;
-
-      // Swap 2nd and 3rd bytes.
-      ptr += 1;
-      val = *(ptr);
-      *(ptr) = *(ptr+1);
-      *(ptr+1) = val;
-
-      // Increment 3 more bytes.
-      ptr += 3;
-    }
-  }
-  else if ( format == RTAUDIO_SINT24 ) {
-    for ( unsigned int i=0; i<samples; i++ ) {
-      // Swap 1st and 3rd bytes.
-      val = *(ptr);
-      *(ptr) = *(ptr+2);
-      *(ptr+2) = val;
-
-      // Increment 2 more bytes.
-      ptr += 2;
-    }
-  }
-  else if ( format == RTAUDIO_FLOAT64 ) {
-    for ( unsigned int i=0; i<samples; i++ ) {
-      // Swap 1st and 8th bytes
-      val = *(ptr);
-      *(ptr) = *(ptr+7);
-      *(ptr+7) = val;
-
-      // Swap 2nd and 7th bytes
-      ptr += 1;
-      val = *(ptr);
-      *(ptr) = *(ptr+5);
-      *(ptr+5) = val;
-
-      // Swap 3rd and 6th bytes
-      ptr += 1;
-      val = *(ptr);
-      *(ptr) = *(ptr+3);
-      *(ptr+3) = val;
-
-      // Swap 4th and 5th bytes
-      ptr += 1;
-      val = *(ptr);
-      *(ptr) = *(ptr+1);
-      *(ptr+1) = val;
-
-      // Increment 5 more bytes.
-      ptr += 5;
-    }
-  }
-}
-
-  // Indentation settings for Vim and Emacs
-  //
-  // Local Variables:
-  // c-basic-offset: 2
-  // indent-tabs-mode: nil
-  // End:
-  //
-  // vim: et sts=2 sw=2
-

+ 0 - 1204
source/AudioDecode/AudioDecoder/lib/RtAudio/src/RtAudio.h

@@ -1,1204 +0,0 @@
-/************************************************************************/
-/*! \class RtAudio
-    \brief Realtime audio i/o C++ classes.
-
-    RtAudio provides a common API (Application Programming Interface)
-    for realtime audio input/output across Linux (native ALSA, Jack,
-    and OSS), Macintosh OS X (CoreAudio and Jack), and Windows
-    (DirectSound, ASIO and WASAPI) operating systems.
-
-    RtAudio GitHub site: https://github.com/thestk/rtaudio
-    RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
-
-    RtAudio: realtime audio i/o C++ classes
-    Copyright (c) 2001-2019 Gary P. Scavone
-
-    Permission is hereby granted, free of charge, to any person
-    obtaining a copy of this software and associated documentation files
-    (the "Software"), to deal in the Software without restriction,
-    including without limitation the rights to use, copy, modify, merge,
-    publish, distribute, sublicense, and/or sell copies of the Software,
-    and to permit persons to whom the Software is furnished to do so,
-    subject to the following conditions:
-
-    The above copyright notice and this permission notice shall be
-    included in all copies or substantial portions of the Software.
-
-    Any person wishing to distribute modifications to the Software is
-    asked to send the modifications to the original developer so that
-    they can be incorporated into the canonical version.  This is,
-    however, not a binding provision of this license.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
-    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-/************************************************************************/
-
-/*!
-  \file RtAudio.h
- */
-
-#ifndef __RTAUDIO_H
-#define __RTAUDIO_H
-
-#define RTAUDIO_VERSION "5.1.0"
-
-#if defined _WIN32 || defined __CYGWIN__
-  #if defined(RTAUDIO_EXPORT)
-    #define RTAUDIO_DLL_PUBLIC __declspec(dllexport)
-  #else
-    #define RTAUDIO_DLL_PUBLIC
-  #endif
-#else
-  #if __GNUC__ >= 4
-    #define RTAUDIO_DLL_PUBLIC __attribute__( (visibility( "default" )) )
-  #else
-    #define RTAUDIO_DLL_PUBLIC
-  #endif
-#endif
-
-#include <string>
-#include <vector>
-#include <stdexcept>
-#include <iostream>
-
-/*! \typedef typedef unsigned long RtAudioFormat;
-    \brief RtAudio data format type.
-
-    Support for signed integers and floats.  Audio data fed to/from an
-    RtAudio stream is assumed to ALWAYS be in host byte order.  The
-    internal routines will automatically take care of any necessary
-    byte-swapping between the host format and the soundcard.  Thus,
-    endian-ness is not a concern in the following format definitions.
-
-    - \e RTAUDIO_SINT8:   8-bit signed integer.
-    - \e RTAUDIO_SINT16:  16-bit signed integer.
-    - \e RTAUDIO_SINT24:  24-bit signed integer.
-    - \e RTAUDIO_SINT32:  32-bit signed integer.
-    - \e RTAUDIO_FLOAT32: Normalized between plus/minus 1.0.
-    - \e RTAUDIO_FLOAT64: Normalized between plus/minus 1.0.
-*/
-typedef unsigned long RtAudioFormat;
-static const RtAudioFormat RTAUDIO_SINT8 = 0x1;    // 8-bit signed integer.
-static const RtAudioFormat RTAUDIO_SINT16 = 0x2;   // 16-bit signed integer.
-static const RtAudioFormat RTAUDIO_SINT24 = 0x4;   // 24-bit signed integer.
-static const RtAudioFormat RTAUDIO_SINT32 = 0x8;   // 32-bit signed integer.
-static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; // Normalized between plus/minus 1.0.
-static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/minus 1.0.
-
-/*! \typedef typedef unsigned long RtAudioStreamFlags;
-    \brief RtAudio stream option flags.
-
-    The following flags can be OR'ed together to allow a client to
-    make changes to the default stream behavior:
-
-    - \e RTAUDIO_NONINTERLEAVED:   Use non-interleaved buffers (default = interleaved).
-    - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
-    - \e RTAUDIO_HOG_DEVICE:       Attempt grab device for exclusive use.
-    - \e RTAUDIO_ALSA_USE_DEFAULT: Use the "default" PCM device (ALSA only).
-    - \e RTAUDIO_JACK_DONT_CONNECT: Do not automatically connect ports (JACK only).
-
-    By default, RtAudio streams pass and receive audio data from the
-    client in an interleaved format.  By passing the
-    RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
-    data will instead be presented in non-interleaved buffers.  In
-    this case, each buffer argument in the RtAudioCallback function
-    will point to a single array of data, with \c nFrames samples for
-    each channel concatenated back-to-back.  For example, the first
-    sample of data for the second channel would be located at index \c
-    nFrames (assuming the \c buffer pointer was recast to the correct
-    data type for the stream).
-
-    Certain audio APIs offer a number of parameters that influence the
-    I/O latency of a stream.  By default, RtAudio will attempt to set
-    these parameters internally for robust (glitch-free) performance
-    (though some APIs, like Windows DirectSound, make this difficult).
-    By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream()
-    function, internal stream settings will be influenced in an attempt
-    to minimize stream latency, though possibly at the expense of stream
-    performance.
-
-    If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
-    open the input and/or output stream device(s) for exclusive use.
-    Note that this is not possible with all supported audio APIs.
-
-    If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt 
-    to select realtime scheduling (round-robin) for the callback thread.
-
-    If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
-    open the "default" PCM device when using the ALSA API. Note that this
-    will override any specified input or output device id.
-
-    If the RTAUDIO_JACK_DONT_CONNECT flag is set, RtAudio will not attempt
-    to automatically connect the ports of the client to the audio device.
-*/
-typedef unsigned int RtAudioStreamFlags;
-static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1;    // Use non-interleaved buffers (default = interleaved).
-static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2;  // Attempt to set stream parameters for lowest possible latency.
-static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4;        // Attempt grab device and prevent use by others.
-static const RtAudioStreamFlags RTAUDIO_SCHEDULE_REALTIME = 0x8; // Try to select realtime scheduling for callback thread.
-static const RtAudioStreamFlags RTAUDIO_ALSA_USE_DEFAULT = 0x10; // Use the "default" PCM device (ALSA only).
-static const RtAudioStreamFlags RTAUDIO_JACK_DONT_CONNECT = 0x20; // Do not automatically connect ports (JACK only).
-
-/*! \typedef typedef unsigned long RtAudioStreamStatus;
-    \brief RtAudio stream status (over- or underflow) flags.
-
-    Notification of a stream over- or underflow is indicated by a
-    non-zero stream \c status argument in the RtAudioCallback function.
-    The stream status can be one of the following two options,
-    depending on whether the stream is open for output and/or input:
-
-    - \e RTAUDIO_INPUT_OVERFLOW:   Input data was discarded because of an overflow condition at the driver.
-    - \e RTAUDIO_OUTPUT_UNDERFLOW: The output buffer ran low, likely producing a break in the output sound.
-*/
-typedef unsigned int RtAudioStreamStatus;
-static const RtAudioStreamStatus RTAUDIO_INPUT_OVERFLOW = 0x1;    // Input data was discarded because of an overflow condition at the driver.
-static const RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW = 0x2;  // The output buffer ran low, likely causing a gap in the output sound.
-
-//! RtAudio callback function prototype.
-/*!
-   All RtAudio clients must create a function of type RtAudioCallback
-   to read and/or write data from/to the audio stream.  When the
-   underlying audio system is ready for new input or output data, this
-   function will be invoked.
-
-   \param outputBuffer For output (or duplex) streams, the client
-          should write \c nFrames of audio sample frames into this
-          buffer.  This argument should be recast to the datatype
-          specified when the stream was opened.  For input-only
-          streams, this argument will be NULL.
-
-   \param inputBuffer For input (or duplex) streams, this buffer will
-          hold \c nFrames of input audio sample frames.  This
-          argument should be recast to the datatype specified when the
-          stream was opened.  For output-only streams, this argument
-          will be NULL.
-
-   \param nFrames The number of sample frames of input or output
-          data in the buffers.  The actual buffer size in bytes is
-          dependent on the data type and number of channels in use.
-
-   \param streamTime The number of seconds that have elapsed since the
-          stream was started.
-
-   \param status If non-zero, this argument indicates a data overflow
-          or underflow condition for the stream.  The particular
-          condition can be determined by comparison with the
-          RtAudioStreamStatus flags.
-
-   \param userData A pointer to optional data provided by the client
-          when opening the stream (default = NULL).
-
-   \return
-   To continue normal stream operation, the RtAudioCallback function
-   should return a value of zero.  To stop the stream and drain the
-   output buffer, the function should return a value of one.  To abort
-   the stream immediately, the client should return a value of two.
- */
-typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer,
-                                unsigned int nFrames,
-                                double streamTime,
-                                RtAudioStreamStatus status,
-                                void *userData );
-
-/************************************************************************/
-/*! \class RtAudioError
-    \brief Exception handling class for RtAudio.
-
-    The RtAudioError class is quite simple but it does allow errors to be
-    "caught" by RtAudioError::Type. See the RtAudio documentation to know
-    which methods can throw an RtAudioError.
-*/
-/************************************************************************/
-
-class RTAUDIO_DLL_PUBLIC RtAudioError : public std::runtime_error
-{
- public:
-  //! Defined RtAudioError types.
-  enum Type {
-    WARNING,           /*!< A non-critical error. */
-    DEBUG_WARNING,     /*!< A non-critical error which might be useful for debugging. */
-    UNSPECIFIED,       /*!< The default, unspecified error type. */
-    NO_DEVICES_FOUND,  /*!< No devices found on system. */
-    INVALID_DEVICE,    /*!< An invalid device ID was specified. */
-    MEMORY_ERROR,      /*!< An error occured during memory allocation. */
-    INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */
-    INVALID_USE,       /*!< The function was called incorrectly. */
-    DRIVER_ERROR,      /*!< A system driver error occured. */
-    SYSTEM_ERROR,      /*!< A system error occured. */
-    THREAD_ERROR       /*!< A thread error occured. */
-  };
-
-  //! The constructor.
-  RtAudioError( const std::string& message,
-                Type type = RtAudioError::UNSPECIFIED )
-    : std::runtime_error(message), type_(type) {}
-
-  //! Prints thrown error message to stderr.
-  virtual void printMessage( void ) const
-    { std::cerr << '\n' << what() << "\n\n"; }
-
-  //! Returns the thrown error message type.
-  virtual const Type& getType(void) const { return type_; }
-
-  //! Returns the thrown error message string.
-  virtual const std::string getMessage(void) const
-    { return std::string(what()); }
-
- protected:
-  Type type_;
-};
-
-//! RtAudio error callback function prototype.
-/*!
-    \param type Type of error.
-    \param errorText Error description.
- */
-typedef void (*RtAudioErrorCallback)( RtAudioError::Type type, const std::string &errorText );
-
-// **************************************************************** //
-//
-// RtAudio class declaration.
-//
-// RtAudio is a "controller" used to select an available audio i/o
-// interface.  It presents a common API for the user to call but all
-// functionality is implemented by the class RtApi and its
-// subclasses.  RtAudio creates an instance of an RtApi subclass
-// based on the user's API choice.  If no choice is made, RtAudio
-// attempts to make a "logical" API selection.
-//
-// **************************************************************** //
-
-class RtApi;
-
-class RTAUDIO_DLL_PUBLIC RtAudio
-{
- public:
-
-  //! Audio API specifier arguments.
-  enum Api {
-    UNSPECIFIED,    /*!< Search for a working compiled API. */
-    LINUX_ALSA,     /*!< The Advanced Linux Sound Architecture API. */
-    LINUX_PULSE,    /*!< The Linux PulseAudio API. */
-    LINUX_OSS,      /*!< The Linux Open Sound System API. */
-    UNIX_JACK,      /*!< The Jack Low-Latency Audio Server API. */
-    MACOSX_CORE,    /*!< Macintosh OS-X Core Audio API. */
-    WINDOWS_WASAPI, /*!< The Microsoft WASAPI API. */
-    WINDOWS_ASIO,   /*!< The Steinberg Audio Stream I/O API. */
-    WINDOWS_DS,     /*!< The Microsoft DirectSound API. */
-    RTAUDIO_DUMMY,  /*!< A compilable but non-functional API. */
-    NUM_APIS        /*!< Number of values in this enum. */
-  };
-
-  //! The public device information structure for returning queried values.
-  struct DeviceInfo {
-    bool probed;                  /*!< true if the device capabilities were successfully probed. */
-    std::string name;             /*!< Character string device identifier. */
-    unsigned int outputChannels;  /*!< Maximum output channels supported by device. */
-    unsigned int inputChannels;   /*!< Maximum input channels supported by device. */
-    unsigned int duplexChannels;  /*!< Maximum simultaneous input/output channels supported by device. */
-    bool isDefaultOutput;         /*!< true if this is the default output device. */
-    bool isDefaultInput;          /*!< true if this is the default input device. */
-    std::vector<unsigned int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
-    unsigned int preferredSampleRate; /*!< Preferred sample rate, e.g. for WASAPI the system sample rate. */
-    RtAudioFormat nativeFormats;  /*!< Bit mask of supported data formats. */
-
-    // Default constructor.
-    DeviceInfo()
-      :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0),
-       isDefaultOutput(false), isDefaultInput(false), preferredSampleRate(0), nativeFormats(0) {}
-  };
-
-  //! The structure for specifying input or ouput stream parameters.
-  struct StreamParameters {
-    unsigned int deviceId;     /*!< Device index (0 to getDeviceCount() - 1). */
-    unsigned int nChannels;    /*!< Number of channels. */
-    unsigned int firstChannel; /*!< First channel index on device (default = 0). */
-
-    // Default constructor.
-    StreamParameters()
-      : deviceId(0), nChannels(0), firstChannel(0) {}
-  };
-
-  //! The structure for specifying stream options.
-  /*!
-    The following flags can be OR'ed together to allow a client to
-    make changes to the default stream behavior:
-
-    - \e RTAUDIO_NONINTERLEAVED:    Use non-interleaved buffers (default = interleaved).
-    - \e RTAUDIO_MINIMIZE_LATENCY:  Attempt to set stream parameters for lowest possible latency.
-    - \e RTAUDIO_HOG_DEVICE:        Attempt grab device for exclusive use.
-    - \e RTAUDIO_SCHEDULE_REALTIME: Attempt to select realtime scheduling for callback thread.
-    - \e RTAUDIO_ALSA_USE_DEFAULT:  Use the "default" PCM device (ALSA only).
-
-    By default, RtAudio streams pass and receive audio data from the
-    client in an interleaved format.  By passing the
-    RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
-    data will instead be presented in non-interleaved buffers.  In
-    this case, each buffer argument in the RtAudioCallback function
-    will point to a single array of data, with \c nFrames samples for
-    each channel concatenated back-to-back.  For example, the first
-    sample of data for the second channel would be located at index \c
-    nFrames (assuming the \c buffer pointer was recast to the correct
-    data type for the stream).
-
-    Certain audio APIs offer a number of parameters that influence the
-    I/O latency of a stream.  By default, RtAudio will attempt to set
-    these parameters internally for robust (glitch-free) performance
-    (though some APIs, like Windows DirectSound, make this difficult).
-    By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream()
-    function, internal stream settings will be influenced in an attempt
-    to minimize stream latency, though possibly at the expense of stream
-    performance.
-
-    If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
-    open the input and/or output stream device(s) for exclusive use.
-    Note that this is not possible with all supported audio APIs.
-
-    If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt 
-    to select realtime scheduling (round-robin) for the callback thread.
-    The \c priority parameter will only be used if the RTAUDIO_SCHEDULE_REALTIME
-    flag is set. It defines the thread's realtime priority.
-
-    If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
-    open the "default" PCM device when using the ALSA API. Note that this
-    will override any specified input or output device id.
-
-    The \c numberOfBuffers parameter can be used to control stream
-    latency in the Windows DirectSound, Linux OSS, and Linux Alsa APIs
-    only.  A value of two is usually the smallest allowed.  Larger
-    numbers can potentially result in more robust stream performance,
-    though likely at the cost of stream latency.  The value set by the
-    user is replaced during execution of the RtAudio::openStream()
-    function by the value actually used by the system.
-
-    The \c streamName parameter can be used to set the client name
-    when using the Jack API.  By default, the client name is set to
-    RtApiJack.  However, if you wish to create multiple instances of
-    RtAudio with Jack, each instance must have a unique client name.
-  */
-  struct StreamOptions {
-    RtAudioStreamFlags flags;      /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE, RTAUDIO_ALSA_USE_DEFAULT). */
-    unsigned int numberOfBuffers;  /*!< Number of stream buffers. */
-    std::string streamName;        /*!< A stream name (currently used only in Jack). */
-    int priority;                  /*!< Scheduling priority of callback thread (only used with flag RTAUDIO_SCHEDULE_REALTIME). */
-
-    // Default constructor.
-    StreamOptions()
-    : flags(0), numberOfBuffers(0), priority(0) {}
-  };
-
-  //! A static function to determine the current RtAudio version.
-  static std::string getVersion( void );
-
-  //! A static function to determine the available compiled audio APIs.
-  /*!
-    The values returned in the std::vector can be compared against
-    the enumerated list values.  Note that there can be more than one
-    API compiled for certain operating systems.
-  */
-  static void getCompiledApi( std::vector<RtAudio::Api> &apis );
-
-  //! Return the name of a specified compiled audio API.
-  /*!
-    This obtains a short lower-case name used for identification purposes.
-    This value is guaranteed to remain identical across library versions.
-    If the API is unknown, this function will return the empty string.
-  */
-  static std::string getApiName( RtAudio::Api api );
-
-  //! Return the display name of a specified compiled audio API.
-  /*!
-    This obtains a long name used for display purposes.
-    If the API is unknown, this function will return the empty string.
-  */
-  static std::string getApiDisplayName( RtAudio::Api api );
-
-  //! Return the compiled audio API having the given name.
-  /*!
-    A case insensitive comparison will check the specified name
-    against the list of compiled APIs, and return the one which
-    matches. On failure, the function returns UNSPECIFIED.
-  */
-  static RtAudio::Api getCompiledApiByName( const std::string &name );
-
-  //! The class constructor.
-  /*!
-    The constructor performs minor initialization tasks.  An exception
-    can be thrown if no API support is compiled.
-
-    If no API argument is specified and multiple API support has been
-    compiled, the default order of use is JACK, ALSA, OSS (Linux
-    systems) and ASIO, DS (Windows systems).
-  */
-  RtAudio( RtAudio::Api api=UNSPECIFIED );
-
-  //! The destructor.
-  /*!
-    If a stream is running or open, it will be stopped and closed
-    automatically.
-  */
-  ~RtAudio();
-
-  //! Returns the audio API specifier for the current instance of RtAudio.
-  RtAudio::Api getCurrentApi( void );
-
-  //! A public function that queries for the number of audio devices available.
-  /*!
-    This function performs a system query of available devices each time it
-    is called, thus supporting devices connected \e after instantiation. If
-    a system error occurs during processing, a warning will be issued. 
-  */
-  unsigned int getDeviceCount( void );
-
-  //! Return an RtAudio::DeviceInfo structure for a specified device number.
-  /*!
-
-    Any device integer between 0 and getDeviceCount() - 1 is valid.
-    If an invalid argument is provided, an RtAudioError (type = INVALID_USE)
-    will be thrown.  If a device is busy or otherwise unavailable, the
-    structure member "probed" will have a value of "false" and all
-    other members are undefined.  If the specified device is the
-    current default input or output device, the corresponding
-    "isDefault" member will have a value of "true".
-  */
-  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
-
-  //! A function that returns the index of the default output device.
-  /*!
-    If the underlying audio API does not provide a "default
-    device", or if no devices are available, the return value will be
-    0.  Note that this is a valid device identifier and it is the
-    client's responsibility to verify that a device is available
-    before attempting to open a stream.
-  */
-  unsigned int getDefaultOutputDevice( void );
-
-  //! A function that returns the index of the default input device.
-  /*!
-    If the underlying audio API does not provide a "default
-    device", or if no devices are available, the return value will be
-    0.  Note that this is a valid device identifier and it is the
-    client's responsibility to verify that a device is available
-    before attempting to open a stream.
-  */
-  unsigned int getDefaultInputDevice( void );
-
-  //! A public function for opening a stream with the specified parameters.
-  /*!
-    An RtAudioError (type = SYSTEM_ERROR) is thrown if a stream cannot be
-    opened with the specified parameters or an error occurs during
-    processing.  An RtAudioError (type = INVALID_USE) is thrown if any
-    invalid device ID or channel number parameters are specified.
-
-    \param outputParameters Specifies output stream parameters to use
-           when opening a stream, including a device ID, number of channels,
-           and starting channel number.  For input-only streams, this
-           argument should be NULL.  The device ID is an index value between
-           0 and getDeviceCount() - 1.
-    \param inputParameters Specifies input stream parameters to use
-           when opening a stream, including a device ID, number of channels,
-           and starting channel number.  For output-only streams, this
-           argument should be NULL.  The device ID is an index value between
-           0 and getDeviceCount() - 1.
-    \param format An RtAudioFormat specifying the desired sample data format.
-    \param sampleRate The desired sample rate (sample frames per second).
-    \param *bufferFrames A pointer to a value indicating the desired
-           internal buffer size in sample frames.  The actual value
-           used by the device is returned via the same pointer.  A
-           value of zero can be specified, in which case the lowest
-           allowable value is determined.
-    \param callback A client-defined function that will be invoked
-           when input data is available and/or output data is needed.
-    \param userData An optional pointer to data that can be accessed
-           from within the callback function.
-    \param options An optional pointer to a structure containing various
-           global stream options, including a list of OR'ed RtAudioStreamFlags
-           and a suggested number of stream buffers that can be used to 
-           control stream latency.  More buffers typically result in more
-           robust performance, though at a cost of greater latency.  If a
-           value of zero is specified, a system-specific median value is
-           chosen.  If the RTAUDIO_MINIMIZE_LATENCY flag bit is set, the
-           lowest allowable value is used.  The actual value used is
-           returned via the structure argument.  The parameter is API dependent.
-    \param errorCallback A client-defined function that will be invoked
-           when an error has occured.
-  */
-  void openStream( RtAudio::StreamParameters *outputParameters,
-                   RtAudio::StreamParameters *inputParameters,
-                   RtAudioFormat format, unsigned int sampleRate,
-                   unsigned int *bufferFrames, RtAudioCallback callback,
-                   void *userData = NULL, RtAudio::StreamOptions *options = NULL, RtAudioErrorCallback errorCallback = NULL );
-
-  //! A function that closes a stream and frees any associated stream memory.
-  /*!
-    If a stream is not open, this function issues a warning and
-    returns (no exception is thrown).
-  */
-  void closeStream( void );
-
-  //! A function that starts a stream.
-  /*!
-    An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
-    during processing.  An RtAudioError (type = INVALID_USE) is thrown if a
-    stream is not open.  A warning is issued if the stream is already
-    running.
-  */
-  void startStream( void );
-
-  //! Stop a stream, allowing any samples remaining in the output queue to be played.
-  /*!
-    An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
-    during processing.  An RtAudioError (type = INVALID_USE) is thrown if a
-    stream is not open.  A warning is issued if the stream is already
-    stopped.
-  */
-  void stopStream( void );
-
-  //! Stop a stream, discarding any samples remaining in the input/output queue.
-  /*!
-    An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
-    during processing.  An RtAudioError (type = INVALID_USE) is thrown if a
-    stream is not open.  A warning is issued if the stream is already
-    stopped.
-  */
-  void abortStream( void );
-
-  //! Returns true if a stream is open and false if not.
-  bool isStreamOpen( void ) const;
-
-  //! Returns true if the stream is running and false if it is stopped or not open.
-  bool isStreamRunning( void ) const;
-
-  //! Returns the number of elapsed seconds since the stream was started.
-  /*!
-    If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown.
-  */
-  double getStreamTime( void );
-
-  //! Set the stream time to a time in seconds greater than or equal to 0.0.
-  /*!
-    If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown.
-  */
-  void setStreamTime( double time );
-
-  //! Returns the internal stream latency in sample frames.
-  /*!
-    The stream latency refers to delay in audio input and/or output
-    caused by internal buffering by the audio system and/or hardware.
-    For duplex streams, the returned value will represent the sum of
-    the input and output latencies.  If a stream is not open, an
-    RtAudioError (type = INVALID_USE) will be thrown.  If the API does not
-    report latency, the return value will be zero.
-  */
-  long getStreamLatency( void );
-
- //! Returns actual sample rate in use by the stream.
- /*!
-   On some systems, the sample rate used may be slightly different
-   than that specified in the stream parameters.  If a stream is not
-   open, an RtAudioError (type = INVALID_USE) will be thrown.
- */
-  unsigned int getStreamSampleRate( void );
-
-  //! Specify whether warning messages should be printed to stderr.
-  void showWarnings( bool value = true );
-
- protected:
-
-  void openRtApi( RtAudio::Api api );
-  RtApi *rtapi_;
-};
-
-// Operating system dependent thread functionality.
-#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__)
-
-  #ifndef NOMINMAX
-    #define NOMINMAX
-  #endif
-  #include <WinSock2.h>
-  #include <Windows.h>
-  #include <process.h>
-  #include <stdint.h>
-
-  typedef uintptr_t ThreadHandle;
-  typedef CRITICAL_SECTION StreamMutex;
-
-#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
-  // Using pthread library for various flavors of unix.
-  #include <pthread.h>
-
-  typedef pthread_t ThreadHandle;
-  typedef pthread_mutex_t StreamMutex;
-
-#else // Setup for "dummy" behavior
-
-  #define __RTAUDIO_DUMMY__
-  typedef int ThreadHandle;
-  typedef int StreamMutex;
-
-#endif
-
-// This global structure type is used to pass callback information
-// between the private RtAudio stream structure and global callback
-// handling functions.
-struct CallbackInfo {
-  void *object;    // Used as a "this" pointer.
-  ThreadHandle thread;
-  void *callback;
-  void *userData;
-  void *errorCallback;
-  void *apiInfo;   // void pointer for API specific callback information
-  bool isRunning;
-  bool doRealtime;
-  int priority;
-
-  // Default constructor.
-  CallbackInfo()
-  :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false), priority(0) {}
-};
-
-// **************************************************************** //
-//
-// RtApi class declaration.
-//
-// Subclasses of RtApi contain all API- and OS-specific code necessary
-// to fully implement the RtAudio API.
-//
-// Note that RtApi is an abstract base class and cannot be
-// explicitly instantiated.  The class RtAudio will create an
-// instance of an RtApi subclass (RtApiOss, RtApiAlsa,
-// RtApiJack, RtApiCore, RtApiDs, or RtApiAsio).
-//
-// **************************************************************** //
-
-#pragma pack(push, 1)
-class S24 {
-
- protected:
-  unsigned char c3[3];
-
- public:
-  S24() {}
-
-  S24& operator = ( const int& i ) {
-    c3[0] = (i & 0x000000ff);
-    c3[1] = (i & 0x0000ff00) >> 8;
-    c3[2] = (i & 0x00ff0000) >> 16;
-    return *this;
-  }
-
-  S24( const double& d ) { *this = (int) d; }
-  S24( const float& f ) { *this = (int) f; }
-  S24( const signed short& s ) { *this = (int) s; }
-  S24( const char& c ) { *this = (int) c; }
-
-  int asInt() {
-    int i = c3[0] | (c3[1] << 8) | (c3[2] << 16);
-    if (i & 0x800000) i |= ~0xffffff;
-    return i;
-  }
-};
-#pragma pack(pop)
-
-#if defined( HAVE_GETTIMEOFDAY )
-  #include <sys/time.h>
-#endif
-
-#include <sstream>
-
-class RTAUDIO_DLL_PUBLIC RtApi
-{
-public:
-
-  RtApi();
-  virtual ~RtApi();
-  virtual RtAudio::Api getCurrentApi( void ) = 0;
-  virtual unsigned int getDeviceCount( void ) = 0;
-  virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0;
-  virtual unsigned int getDefaultInputDevice( void );
-  virtual unsigned int getDefaultOutputDevice( void );
-  void openStream( RtAudio::StreamParameters *outputParameters,
-                   RtAudio::StreamParameters *inputParameters,
-                   RtAudioFormat format, unsigned int sampleRate,
-                   unsigned int *bufferFrames, RtAudioCallback callback,
-                   void *userData, RtAudio::StreamOptions *options,
-                   RtAudioErrorCallback errorCallback );
-  virtual void closeStream( void );
-  virtual void startStream( void ) = 0;
-  virtual void stopStream( void ) = 0;
-  virtual void abortStream( void ) = 0;
-  long getStreamLatency( void );
-  unsigned int getStreamSampleRate( void );
-  virtual double getStreamTime( void );
-  virtual void setStreamTime( double time );
-  bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; }
-  bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; }
-  void showWarnings( bool value ) { showWarnings_ = value; }
-
-
-protected:
-
-  static const unsigned int MAX_SAMPLE_RATES;
-  static const unsigned int SAMPLE_RATES[];
-
-  enum { FAILURE, SUCCESS };
-
-  enum StreamState {
-    STREAM_STOPPED,
-    STREAM_STOPPING,
-    STREAM_RUNNING,
-    STREAM_CLOSED = -50
-  };
-
-  enum StreamMode {
-    OUTPUT,
-    INPUT,
-    DUPLEX,
-    UNINITIALIZED = -75
-  };
-
-  // A protected structure used for buffer conversion.
-  struct ConvertInfo {
-    int channels;
-    int inJump, outJump;
-    RtAudioFormat inFormat, outFormat;
-    std::vector<int> inOffset;
-    std::vector<int> outOffset;
-  };
-
-  // A protected structure for audio streams.
-  struct RtApiStream {
-    unsigned int device[2];    // Playback and record, respectively.
-    void *apiHandle;           // void pointer for API specific stream handle information
-    StreamMode mode;           // OUTPUT, INPUT, or DUPLEX.
-    StreamState state;         // STOPPED, RUNNING, or CLOSED
-    char *userBuffer[2];       // Playback and record, respectively.
-    char *deviceBuffer;
-    bool doConvertBuffer[2];   // Playback and record, respectively.
-    bool userInterleaved;
-    bool deviceInterleaved[2]; // Playback and record, respectively.
-    bool doByteSwap[2];        // Playback and record, respectively.
-    unsigned int sampleRate;
-    unsigned int bufferSize;
-    unsigned int nBuffers;
-    unsigned int nUserChannels[2];    // Playback and record, respectively.
-    unsigned int nDeviceChannels[2];  // Playback and record channels, respectively.
-    unsigned int channelOffset[2];    // Playback and record, respectively.
-    unsigned long latency[2];         // Playback and record, respectively.
-    RtAudioFormat userFormat;
-    RtAudioFormat deviceFormat[2];    // Playback and record, respectively.
-    StreamMutex mutex;
-    CallbackInfo callbackInfo;
-    ConvertInfo convertInfo[2];
-    double streamTime;         // Number of elapsed seconds since the stream started.
-
-#if defined(HAVE_GETTIMEOFDAY)
-    struct timeval lastTickTimestamp;
-#endif
-
-    RtApiStream()
-      :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; }
-  };
-
-  typedef S24 Int24;
-  typedef signed short Int16;
-  typedef signed int Int32;
-  typedef float Float32;
-  typedef double Float64;
-
-  std::ostringstream errorStream_;
-  std::string errorText_;
-  bool showWarnings_;
-  RtApiStream stream_;
-  bool firstErrorOccurred_;
-
-  /*!
-    Protected, api-specific method that attempts to open a device
-    with the given parameters.  This function MUST be implemented by
-    all subclasses.  If an error is encountered during the probe, a
-    "warning" message is reported and FAILURE is returned. A
-    successful probe is indicated by a return value of SUCCESS.
-  */
-  virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
-                                unsigned int firstChannel, unsigned int sampleRate,
-                                RtAudioFormat format, unsigned int *bufferSize,
-                                RtAudio::StreamOptions *options );
-
-  //! A protected function used to increment the stream time.
-  void tickStreamTime( void );
-
-  //! Protected common method to clear an RtApiStream structure.
-  void clearStreamInfo();
-
-  /*!
-    Protected common method that throws an RtAudioError (type =
-    INVALID_USE) if a stream is not open.
-  */
-  void verifyStream( void );
-
-  //! Protected common error method to allow global control over error handling.
-  void error( RtAudioError::Type type );
-
-  /*!
-    Protected method used to perform format, channel number, and/or interleaving
-    conversions between the user and device buffers.
-  */
-  void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
-
-  //! Protected common method used to perform byte-swapping on buffers.
-  void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format );
-
-  //! Protected common method that returns the number of bytes for a given format.
-  unsigned int formatBytes( RtAudioFormat format );
-
-  //! Protected common method that sets up the parameters for buffer conversion.
-  void setConvertInfo( StreamMode mode, unsigned int firstChannel );
-};
-
-// **************************************************************** //
-//
-// Inline RtAudio definitions.
-//
-// **************************************************************** //
-
-inline RtAudio::Api RtAudio :: getCurrentApi( void ) { return rtapi_->getCurrentApi(); }
-inline unsigned int RtAudio :: getDeviceCount( void ) { return rtapi_->getDeviceCount(); }
-inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); }
-inline unsigned int RtAudio :: getDefaultInputDevice( void ) { return rtapi_->getDefaultInputDevice(); }
-inline unsigned int RtAudio :: getDefaultOutputDevice( void ) { return rtapi_->getDefaultOutputDevice(); }
-inline void RtAudio :: closeStream( void ) { return rtapi_->closeStream(); }
-inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); }
-inline void RtAudio :: stopStream( void )  { return rtapi_->stopStream(); }
-inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
-inline bool RtAudio :: isStreamOpen( void ) const { return rtapi_->isStreamOpen(); }
-inline bool RtAudio :: isStreamRunning( void ) const { return rtapi_->isStreamRunning(); }
-inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); }
-inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); }
-inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); }
-inline void RtAudio :: setStreamTime( double time ) { return rtapi_->setStreamTime( time ); }
-inline void RtAudio :: showWarnings( bool value ) { rtapi_->showWarnings( value ); }
-
-// RtApi Subclass prototypes.
-
-#if defined(__MACOSX_CORE__)
-
-#include <CoreAudio/AudioHardware.h>
-
-class RtApiCore: public RtApi
-{
-public:
-
-  RtApiCore();
-  ~RtApiCore();
-  RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; }
-  unsigned int getDeviceCount( void );
-  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
-  unsigned int getDefaultOutputDevice( void );
-  unsigned int getDefaultInputDevice( void );
-  void closeStream( void );
-  void startStream( void );
-  void stopStream( void );
-  void abortStream( void );
-
-  // This function is intended for internal use only.  It must be
-  // public because it is called by the internal callback handler,
-  // which is not a member of RtAudio.  External use of this function
-  // will most likely produce highly undesireable results!
-  bool callbackEvent( AudioDeviceID deviceId,
-                      const AudioBufferList *inBufferList,
-                      const AudioBufferList *outBufferList );
-
-  private:
-
-  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
-                        unsigned int firstChannel, unsigned int sampleRate,
-                        RtAudioFormat format, unsigned int *bufferSize,
-                        RtAudio::StreamOptions *options );
-  static const char* getErrorCode( OSStatus code );
-};
-
-#endif
-
-#if defined(__UNIX_JACK__)
-
-class RtApiJack: public RtApi
-{
-public:
-
-  RtApiJack();
-  ~RtApiJack();
-  RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; }
-  unsigned int getDeviceCount( void );
-  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
-  void closeStream( void );
-  void startStream( void );
-  void stopStream( void );
-  void abortStream( void );
-
-  // This function is intended for internal use only.  It must be
-  // public because it is called by the internal callback handler,
-  // which is not a member of RtAudio.  External use of this function
-  // will most likely produce highly undesireable results!
-  bool callbackEvent( unsigned long nframes );
-
-  private:
-
-  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
-                        unsigned int firstChannel, unsigned int sampleRate,
-                        RtAudioFormat format, unsigned int *bufferSize,
-                        RtAudio::StreamOptions *options );
-
-  bool shouldAutoconnect_;
-};
-
-#endif
-
-#if defined(__WINDOWS_ASIO__)
-
-class RtApiAsio: public RtApi
-{
-public:
-
-  RtApiAsio();
-  ~RtApiAsio();
-  RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; }
-  unsigned int getDeviceCount( void );
-  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
-  void closeStream( void );
-  void startStream( void );
-  void stopStream( void );
-  void abortStream( void );
-
-  // This function is intended for internal use only.  It must be
-  // public because it is called by the internal callback handler,
-  // which is not a member of RtAudio.  External use of this function
-  // will most likely produce highly undesireable results!
-  bool callbackEvent( long bufferIndex );
-
-  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,
-                        RtAudioFormat format, unsigned int *bufferSize,
-                        RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__WINDOWS_DS__)
-
-class RtApiDs: public RtApi
-{
-public:
-
-  RtApiDs();
-  ~RtApiDs();
-  RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; }
-  unsigned int getDeviceCount( void );
-  unsigned int getDefaultOutputDevice( void );
-  unsigned int getDefaultInputDevice( void );
-  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
-  void closeStream( void );
-  void startStream( void );
-  void stopStream( void );
-  void abortStream( void );
-
-  // This function is intended for internal use only.  It must be
-  // public because it is called by the internal callback handler,
-  // which is not a member of RtAudio.  External use of this function
-  // will most likely produce highly undesireable results!
-  void callbackEvent( void );
-
-  private:
-
-  bool coInitialized_;
-  bool buffersRolling;
-  long duplexPrerollBytes;
-  std::vector<struct DsDevice> dsDevices;
-  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
-                        unsigned int firstChannel, unsigned int sampleRate,
-                        RtAudioFormat format, unsigned int *bufferSize,
-                        RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__WINDOWS_WASAPI__)
-
-struct IMMDeviceEnumerator;
-
-class RtApiWasapi : public RtApi
-{
-public:
-  RtApiWasapi();
-  virtual ~RtApiWasapi();
-
-  RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_WASAPI; }
-  unsigned int getDeviceCount( void );
-  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
-  unsigned int getDefaultOutputDevice( void );
-  unsigned int getDefaultInputDevice( void );
-  void closeStream( void );
-  void startStream( void );
-  void stopStream( void );
-  void abortStream( void );
-
-private:
-  bool coInitialized_;
-  IMMDeviceEnumerator* deviceEnumerator_;
-
-  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
-                        unsigned int firstChannel, unsigned int sampleRate,
-                        RtAudioFormat format, unsigned int* bufferSize,
-                        RtAudio::StreamOptions* options );
-
-  static DWORD WINAPI runWasapiThread( void* wasapiPtr );
-  static DWORD WINAPI stopWasapiThread( void* wasapiPtr );
-  static DWORD WINAPI abortWasapiThread( void* wasapiPtr );
-  void wasapiThread();
-};
-
-#endif
-
-#if defined(__LINUX_ALSA__)
-
-class RtApiAlsa: public RtApi
-{
-public:
-
-  RtApiAlsa();
-  ~RtApiAlsa();
-  RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; }
-  unsigned int getDeviceCount( void );
-  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
-  void closeStream( void );
-  void startStream( void );
-  void stopStream( void );
-  void abortStream( void );
-
-  // This function is intended for internal use only.  It must be
-  // public because it is called by the internal callback handler,
-  // which is not a member of RtAudio.  External use of this function
-  // will most likely produce highly undesireable results!
-  void callbackEvent( void );
-
-  private:
-
-  std::vector<RtAudio::DeviceInfo> devices_;
-  void saveDeviceInfo( void );
-  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
-                        unsigned int firstChannel, unsigned int sampleRate,
-                        RtAudioFormat format, unsigned int *bufferSize,
-                        RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__LINUX_PULSE__)
-
-class RtApiPulse: public RtApi
-{
-public:
-  ~RtApiPulse();
-  RtAudio::Api getCurrentApi() { return RtAudio::LINUX_PULSE; }
-  unsigned int getDeviceCount( void );
-  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
-  void closeStream( void );
-  void startStream( void );
-  void stopStream( void );
-  void abortStream( void );
-
-  // This function is intended for internal use only.  It must be
-  // public because it is called by the internal callback handler,
-  // which is not a member of RtAudio.  External use of this function
-  // will most likely produce highly undesireable results!
-  void callbackEvent( void );
-
-  private:
-
-  std::vector<RtAudio::DeviceInfo> devices_;
-  void saveDeviceInfo( void );
-  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
-                        unsigned int firstChannel, unsigned int sampleRate,
-                        RtAudioFormat format, unsigned int *bufferSize,
-                        RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__LINUX_OSS__)
-
-class RtApiOss: public RtApi
-{
-public:
-
-  RtApiOss();
-  ~RtApiOss();
-  RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; }
-  unsigned int getDeviceCount( void );
-  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
-  void closeStream( void );
-  void startStream( void );
-  void stopStream( void );
-  void abortStream( void );
-
-  // This function is intended for internal use only.  It must be
-  // public because it is called by the internal callback handler,
-  // which is not a member of RtAudio.  External use of this function
-  // will most likely produce highly undesireable results!
-  void callbackEvent( void );
-
-  private:
-
-  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
-                        unsigned int firstChannel, unsigned int sampleRate,
-                        RtAudioFormat format, unsigned int *bufferSize,
-                        RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__RTAUDIO_DUMMY__)
-
-class RtApiDummy: public RtApi
-{
-public:
-
-  RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtAudioError::WARNING ); }
-  RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; }
-  unsigned int getDeviceCount( void ) { return 0; }
-  RtAudio::DeviceInfo getDeviceInfo( unsigned int /*device*/ ) { RtAudio::DeviceInfo info; return info; }
-  void closeStream( void ) {}
-  void startStream( void ) {}
-  void stopStream( void ) {}
-  void abortStream( void ) {}
-
-  private:
-
-  bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/, 
-                        unsigned int /*firstChannel*/, unsigned int /*sampleRate*/,
-                        RtAudioFormat /*format*/, unsigned int * /*bufferSize*/,
-                        RtAudio::StreamOptions * /*options*/ ) { return false; }
-};
-
-#endif
-
-#endif
-
-// Indentation settings for Vim and Emacs
-//
-// Local Variables:
-// c-basic-offset: 2
-// indent-tabs-mode: nil
-// End:
-//
-// vim: et sts=2 sw=2

+ 0 - 12
source/AudioDecode/AudioDecoder/lib/RtAudio/src/rtaudio.pc.in

@@ -1,12 +0,0 @@
-prefix=@prefix@
-exec_prefix=${prefix}
-libdir=${exec_prefix}/lib
-includedir=${prefix}/include/rtaudio        
-
-Name: librtaudio
-Description: RtAudio - a set of C++ classes that provide a common API for realtime audio input/output
-Version: @PACKAGE_VERSION@
-Requires: @req@ 
-Libs: -L${libdir} -lrtaudio
-Libs.private: -lpthread
-Cflags: -pthread -I${includedir} @api@

+ 0 - 261
source/AudioDecode/AudioDecoder/lib/RtAudio/src/rtaudio_c.cpp

@@ -1,261 +0,0 @@
-#include "rtaudio_c.h"
-#include "RtAudio.h"
-
-#include <cstring>
-
-#define MAX_ERROR_MESSAGE_LENGTH 512
-
-struct rtaudio {
-  RtAudio *audio;
-
-  rtaudio_cb_t cb;
-  void *userdata;
-
-  int has_error;
-  char errmsg[MAX_ERROR_MESSAGE_LENGTH];
-};
-
-const char *rtaudio_version() { return RTAUDIO_VERSION; }
-
-extern "C" const RtAudio::Api rtaudio_compiled_apis[];
-const rtaudio_api_t *rtaudio_compiled_api() {
-  return (rtaudio_api_t *) &rtaudio_compiled_apis[0];
-}
-
-extern "C" const unsigned int rtaudio_num_compiled_apis;
-unsigned int rtaudio_get_num_compiled_apis(void) {
-  return rtaudio_num_compiled_apis;
-}
-
-extern "C" const char* rtaudio_api_names[][2];
-const char *rtaudio_api_name(rtaudio_api_t api) {
-    if (api < 0 || api >= RTAUDIO_API_NUM)
-        return NULL;
-    return rtaudio_api_names[api][0];
-}
-
-const char *rtaudio_api_display_name(rtaudio_api_t api)
-{
-    if (api < 0 || api >= RTAUDIO_API_NUM)
-        return "Unknown";
-    return rtaudio_api_names[api][1];
-}
-
-rtaudio_api_t rtaudio_compiled_api_by_name(const char *name) {
-    RtAudio::Api api = RtAudio::UNSPECIFIED;
-    if (name) {
-        api = RtAudio::getCompiledApiByName(name);
-    }
-    return (rtaudio_api_t)api;
-}
-
-const char *rtaudio_error(rtaudio_t audio) {
-  if (audio->has_error) {
-    return audio->errmsg;
-  }
-  return NULL;
-}
-
-rtaudio_t rtaudio_create(rtaudio_api_t api) {
-  rtaudio_t audio = new struct rtaudio();
-  try {
-    audio->audio = new RtAudio((RtAudio::Api)api);
-  } catch (RtAudioError &err) {
-    audio->has_error = 1;
-    strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
-  }
-  return audio;
-}
-
-void rtaudio_destroy(rtaudio_t audio) { delete audio->audio; }
-
-rtaudio_api_t rtaudio_current_api(rtaudio_t audio) {
-  return (rtaudio_api_t)audio->audio->getCurrentApi();
-}
-
-int rtaudio_device_count(rtaudio_t audio) {
-  return audio->audio->getDeviceCount();
-}
-
-rtaudio_device_info_t rtaudio_get_device_info(rtaudio_t audio, int i) {
-  rtaudio_device_info_t result;
-  std::memset(&result, 0, sizeof(result));
-  try {
-    audio->has_error = 0;
-    RtAudio::DeviceInfo info = audio->audio->getDeviceInfo(i);
-    result.probed = info.probed;
-    result.output_channels = info.outputChannels;
-    result.input_channels = info.inputChannels;
-    result.duplex_channels = info.duplexChannels;
-    result.is_default_output = info.isDefaultOutput;
-    result.is_default_input = info.isDefaultInput;
-    result.native_formats = info.nativeFormats;
-    result.preferred_sample_rate = info.preferredSampleRate;
-    strncpy(result.name, info.name.c_str(), sizeof(result.name) - 1);
-    for (unsigned int j = 0; j < info.sampleRates.size(); j++) {
-      if (j < sizeof(result.sample_rates) / sizeof(result.sample_rates[0])) {
-        result.sample_rates[j] = info.sampleRates[j];
-      }
-    }
-  } catch (RtAudioError &err) {
-    audio->has_error = 1;
-    strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
-  }
-  return result;
-}
-
-unsigned int rtaudio_get_default_output_device(rtaudio_t audio) {
-  return audio->audio->getDefaultOutputDevice();
-}
-
-unsigned int rtaudio_get_default_input_device(rtaudio_t audio) {
-  return audio->audio->getDefaultInputDevice();
-}
-
-static int proxy_cb_func(void *out, void *in, unsigned int nframes, double time,
-                         RtAudioStreamStatus status, void *userdata) {
-  rtaudio_t audio = (rtaudio_t)userdata;
-  return audio->cb(out, in, nframes, time, (rtaudio_stream_status_t)status,
-                   audio->userdata);
-}
-
-int rtaudio_open_stream(rtaudio_t audio,
-                        rtaudio_stream_parameters_t *output_params,
-                        rtaudio_stream_parameters_t *input_params,
-                        rtaudio_format_t format, unsigned int sample_rate,
-                        unsigned int *buffer_frames, rtaudio_cb_t cb,
-                        void *userdata, rtaudio_stream_options_t *options,
-                        rtaudio_error_cb_t /*errcb*/) {
-  try {
-    audio->has_error = 0;
-    RtAudio::StreamParameters *in = NULL;
-    RtAudio::StreamParameters *out = NULL;
-    RtAudio::StreamOptions *opts = NULL;
-
-    RtAudio::StreamParameters inparams;
-    RtAudio::StreamParameters outparams;
-    RtAudio::StreamOptions stream_opts;
-
-    if (input_params != NULL) {
-      inparams.deviceId = input_params->device_id;
-      inparams.nChannels = input_params->num_channels;
-      inparams.firstChannel = input_params->first_channel;
-      in = &inparams;
-    }
-    if (output_params != NULL) {
-      outparams.deviceId = output_params->device_id;
-      outparams.nChannels = output_params->num_channels;
-      outparams.firstChannel = output_params->first_channel;
-      out = &outparams;
-    }
-
-    if (options != NULL) {
-      stream_opts.flags = (RtAudioStreamFlags)options->flags;
-      stream_opts.numberOfBuffers = options->num_buffers;
-      stream_opts.priority = options->priority;
-      if (strlen(options->name) > 0) {
-        stream_opts.streamName = std::string(options->name);
-      }
-      opts = &stream_opts;
-    }
-    audio->cb = cb;
-    audio->userdata = userdata;
-    audio->audio->openStream(out, in, (RtAudioFormat)format, sample_rate,
-                             buffer_frames, proxy_cb_func, (void *)audio, opts,
-                             NULL);
-    return 0;
-  } catch (RtAudioError &err) {
-    audio->has_error = 1;
-    strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
-    return -1;
-  }
-}
-
-void rtaudio_close_stream(rtaudio_t audio) { audio->audio->closeStream(); }
-
-int rtaudio_start_stream(rtaudio_t audio) {
-  try {
-    audio->has_error = 0;
-    audio->audio->startStream();
-  } catch (RtAudioError &err) {
-    audio->has_error = 1;
-    strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
-  }
-  return 0;
-}
-
-int rtaudio_stop_stream(rtaudio_t audio) {
-  try {
-    audio->has_error = 0;
-    audio->audio->stopStream();
-  } catch (RtAudioError &err) {
-    audio->has_error = 1;
-    strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
-  }
-  return 0;
-}
-
-int rtaudio_abort_stream(rtaudio_t audio) {
-  try {
-    audio->has_error = 0;
-    audio->audio->abortStream();
-  } catch (RtAudioError &err) {
-    audio->has_error = 1;
-    strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
-  }
-  return 0;
-}
-
-int rtaudio_is_stream_open(rtaudio_t audio) {
-  return !!audio->audio->isStreamOpen();
-}
-
-int rtaudio_is_stream_running(rtaudio_t audio) {
-  return !!audio->audio->isStreamRunning();
-}
-
-double rtaudio_get_stream_time(rtaudio_t audio) {
-  try {
-    audio->has_error = 0;
-    return audio->audio->getStreamTime();
-  } catch (RtAudioError &err) {
-    audio->has_error = 1;
-    strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
-    return 0;
-  }
-}
-
-void rtaudio_set_stream_time(rtaudio_t audio, double time) {
-  try {
-    audio->has_error = 0;
-    audio->audio->setStreamTime(time);
-  } catch (RtAudioError &err) {
-    audio->has_error = 1;
-    strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
-  }
-}
-
-int rtaudio_get_stream_latency(rtaudio_t audio) {
-  try {
-    audio->has_error = 0;
-    return audio->audio->getStreamLatency();
-  } catch (RtAudioError &err) {
-    audio->has_error = 1;
-    strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
-    return -1;
-  }
-}
-
-unsigned int rtaudio_get_stream_sample_rate(rtaudio_t audio) {
-  try {
-    return audio->audio->getStreamSampleRate();
-  } catch (RtAudioError &err) {
-    audio->has_error = 1;
-    strncpy(audio->errmsg, err.what(), sizeof(audio->errmsg) - 1);
-    return -1;
-  }
-}
-
-void rtaudio_show_warnings(rtaudio_t audio, int show) {
-  audio->audio->showWarnings(!!show);
-}

+ 0 - 306
source/AudioDecode/AudioDecoder/lib/RtAudio/src/rtaudio_c.h

@@ -1,306 +0,0 @@
-/************************************************************************/
-/*! \defgroup C-interface
-    @{
-
-    \brief C interface to realtime audio i/o C++ classes.
-
-    RtAudio offers a C-style interface, principally for use in binding
-    RtAudio to other programming languages.  All structs, enums, and
-    functions listed here have direct analogs (and simply call to)
-    items in the C++ RtAudio class and its supporting classes and
-    types
-*/
-/************************************************************************/
-
-/*!
-  \file rtaudio_c.h
- */
-
-#ifndef RTAUDIO_C_H
-#define RTAUDIO_C_H
-
-#if defined(RTAUDIO_EXPORT)
-#if defined _WIN32 || defined __CYGWIN__
-#define RTAUDIOAPI __declspec(dllexport)
-#else
-#define RTAUDIOAPI __attribute__((visibility("default")))
-#endif
-#else
-#define RTAUDIOAPI //__declspec(dllimport)
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*! \typedef typedef unsigned long rtaudio_format_t;
-    \brief RtAudio data format type.
-
-    - \e RTAUDIO_FORMAT_SINT8:   8-bit signed integer.
-    - \e RTAUDIO_FORMAT_SINT16:  16-bit signed integer.
-    - \e RTAUDIO_FORMAT_SINT24:  24-bit signed integer.
-    - \e RTAUDIO_FORMAT_SINT32:  32-bit signed integer.
-    - \e RTAUDIO_FORMAT_FLOAT32: Normalized between plus/minus 1.0.
-    - \e RTAUDIO_FORMAT_FLOAT64: Normalized between plus/minus 1.0.
-
-    See \ref RtAudioFormat.
-*/
-typedef unsigned long rtaudio_format_t;
-
-#define RTAUDIO_FORMAT_SINT8 0x01
-#define RTAUDIO_FORMAT_SINT16 0x02
-#define RTAUDIO_FORMAT_SINT24 0x04
-#define RTAUDIO_FORMAT_SINT32 0x08
-#define RTAUDIO_FORMAT_FLOAT32 0x10
-#define RTAUDIO_FORMAT_FLOAT64 0x20
-
-/*! \typedef typedef unsigned long rtaudio_stream_flags_t;
-    \brief RtAudio stream option flags.
-
-    The following flags can be OR'ed together to allow a client to
-    make changes to the default stream behavior:
-
-    - \e RTAUDIO_FLAGS_NONINTERLEAVED:   Use non-interleaved buffers (default = interleaved).
-    - \e RTAUDIO_FLAGS_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
-    - \e RTAUDIO_FLAGS_HOG_DEVICE:       Attempt grab device for exclusive use.
-    - \e RTAUDIO_FLAGS_ALSA_USE_DEFAULT: Use the "default" PCM device (ALSA only).
-    - \e RTAUDIO_FLAGS_JACK_DONT_CONNECT: Do not automatically connect ports (JACK only).
-
-    See \ref RtAudioStreamFlags.
-*/
-typedef unsigned int rtaudio_stream_flags_t;
-
-#define RTAUDIO_FLAGS_NONINTERLEAVED 0x1
-#define RTAUDIO_FLAGS_MINIMIZE_LATENCY 0x2
-#define RTAUDIO_FLAGS_HOG_DEVICE 0x4
-#define RTAUDIO_FLAGS_SCHEDULE_REALTIME 0x8
-#define RTAUDIO_FLAGS_ALSA_USE_DEFAULT 0x10
-#define RTAUDIO_FLAGS_JACK_DONT_CONNECT = 0x20
-
-/*! \typedef typedef unsigned long rtaudio_stream_status_t;
-    \brief RtAudio stream status (over- or underflow) flags.
-
-    Notification of a stream over- or underflow is indicated by a
-    non-zero stream \c status argument in the RtAudioCallback function.
-    The stream status can be one of the following two options,
-    depending on whether the stream is open for output and/or input:
-
-    - \e RTAUDIO_STATUS_INPUT_OVERFLOW:   Input data was discarded because of an overflow condition at the driver.
-    - \e RTAUDIO_STATUS_OUTPUT_UNDERFLOW: The output buffer ran low, likely producing a break in the output sound.
-
-    See \ref RtAudioStreamStatus.
-*/
-typedef unsigned int rtaudio_stream_status_t;
-
-#define RTAUDIO_STATUS_INPUT_OVERFLOW 0x1
-#define RTAUDIO_STATUS_OUTPUT_UNDERFLOW 0x2
-
-//! RtAudio callback function prototype.
-/*!
-   All RtAudio clients must create a function of this type to read
-   and/or write data from/to the audio stream.  When the underlying
-   audio system is ready for new input or output data, this function
-   will be invoked.
-
-   See \ref RtAudioCallback.
- */
-typedef int (*rtaudio_cb_t)(void *out, void *in, unsigned int nFrames,
-                            double stream_time, rtaudio_stream_status_t status,
-                            void *userdata);
-
-/*! \brief Error codes for RtAudio.
-
-    See \ref RtAudioError.
-*/
-typedef enum rtaudio_error {
-  RTAUDIO_ERROR_WARNING,           /*!< A non-critical error. */
-  RTAUDIO_ERROR_DEBUG_WARNING,     /*!< A non-critical error which might be useful for debugging. */
-  RTAUDIO_ERROR_UNSPECIFIED,       /*!< The default, unspecified error type. */
-  RTAUDIO_ERROR_NO_DEVICES_FOUND,  /*!< No devices found on system. */
-  RTAUDIO_ERROR_INVALID_DEVICE,    /*!< An invalid device ID was specified. */
-  RTAUDIO_ERROR_MEMORY_ERROR,      /*!< An error occured during memory allocation. */
-  RTAUDIO_ERROR_INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */
-  RTAUDIO_ERROR_INVALID_USE,       /*!< The function was called incorrectly. */
-  RTAUDIO_ERROR_DRIVER_ERROR,      /*!< A system driver error occured. */
-  RTAUDIO_ERROR_SYSTEM_ERROR,      /*!< A system error occured. */
-  RTAUDIO_ERROR_THREAD_ERROR,      /*!< A thread error occured. */
-} rtaudio_error_t;
-
-//! RtAudio error callback function prototype.
-/*!
-    \param err Type of error.
-    \param msg Error description.
-
-    See \ref RtAudioErrorCallback.
- */
-typedef void (*rtaudio_error_cb_t)(rtaudio_error_t err, const char *msg);
-
-//! Audio API specifier.  See \ref RtAudio::Api.
-typedef enum rtaudio_api {
-  RTAUDIO_API_UNSPECIFIED,    /*!< Search for a working compiled API. */
-  RTAUDIO_API_LINUX_ALSA,     /*!< The Advanced Linux Sound Architecture API. */
-  RTAUDIO_API_LINUX_PULSE,    /*!< The Linux PulseAudio API. */
-  RTAUDIO_API_LINUX_OSS,      /*!< The Linux Open Sound System API. */
-  RTAUDIO_API_UNIX_JACK,      /*!< The Jack Low-Latency Audio Server API. */
-  RTAUDIO_API_MACOSX_CORE,    /*!< Macintosh OS-X Core Audio API. */
-  RTAUDIO_API_WINDOWS_WASAPI, /*!< The Microsoft WASAPI API. */
-  RTAUDIO_API_WINDOWS_ASIO,   /*!< The Steinberg Audio Stream I/O API. */
-  RTAUDIO_API_WINDOWS_DS,     /*!< The Microsoft DirectSound API. */
-  RTAUDIO_API_DUMMY,          /*!< A compilable but non-functional API. */
-  RTAUDIO_API_NUM,            /*!< Number of values in this enum. */
-} rtaudio_api_t;
-
-#define NUM_SAMPLE_RATES 16
-#define MAX_NAME_LENGTH 512
-
-//! The public device information structure for returning queried values.
-//! See \ref RtAudio::DeviceInfo.
-typedef struct rtaudio_device_info {
-  int probed;
-  unsigned int output_channels;
-  unsigned int input_channels;
-  unsigned int duplex_channels;
-
-  int is_default_output;
-  int is_default_input;
-
-  rtaudio_format_t native_formats;
-
-  unsigned int preferred_sample_rate;
-  int sample_rates[NUM_SAMPLE_RATES];
-
-  char name[MAX_NAME_LENGTH];
-} rtaudio_device_info_t;
-
-//! The structure for specifying input or ouput stream parameters.
-//! See \ref RtAudio::StreamParameters.
-typedef struct rtaudio_stream_parameters {
-  unsigned int device_id;
-  unsigned int num_channels;
-  unsigned int first_channel;
-} rtaudio_stream_parameters_t;
-
-//! The structure for specifying stream options.
-//! See \ref RtAudio::StreamOptions.
-typedef struct rtaudio_stream_options {
-  rtaudio_stream_flags_t flags;
-  unsigned int num_buffers;
-  int priority;
-  char name[MAX_NAME_LENGTH];
-} rtaudio_stream_options_t;
-
-typedef struct rtaudio *rtaudio_t;
-
-//! Determine the current RtAudio version.  See \ref RtAudio::getVersion().
-RTAUDIOAPI const char *rtaudio_version(void);
-
-//! Determine the number of available compiled audio APIs, the length
-//! of the array returned by rtaudio_compiled_api().  See \ref
-//! RtAudio::getCompiledApi().
-RTAUDIOAPI unsigned int rtaudio_get_num_compiled_apis(void);
-
-//! Return an array of rtaudio_api_t compiled into this instance of
-//! RtAudio.  This array is static (do not free it) and has the length
-//! returned by rtaudio_get_num_compiled_apis().  See \ref
-//! RtAudio::getCompiledApi().
-RTAUDIOAPI const rtaudio_api_t *rtaudio_compiled_api(void);
-
-//! Return the name of a specified rtaudio_api_t.  This string can be
-//! used to look up an API by rtaudio_compiled_api_by_name().  See
-//! \ref RtAudio::getApiName().
-RTAUDIOAPI const char *rtaudio_api_name(rtaudio_api_t api);
-
-//! Return the display name of a specified rtaudio_api_t.  See \ref
-//! RtAudio::getApiDisplayName().
-RTAUDIOAPI const char *rtaudio_api_display_name(rtaudio_api_t api);
-
-//! Return the rtaudio_api_t having the given name.  See \ref
-//! RtAudio::getCompiledApiByName().
-RTAUDIOAPI rtaudio_api_t rtaudio_compiled_api_by_name(const char *name);
-
-RTAUDIOAPI const char *rtaudio_error(rtaudio_t audio);
-
-//! Create an instance of struct rtaudio.
-RTAUDIOAPI rtaudio_t rtaudio_create(rtaudio_api_t api);
-
-//! Free an instance of struct rtaudio.
-RTAUDIOAPI void rtaudio_destroy(rtaudio_t audio);
-
-//! Returns the audio API specifier for the current instance of
-//! RtAudio.  See RtAudio::getCurrentApi().
-RTAUDIOAPI rtaudio_api_t rtaudio_current_api(rtaudio_t audio);
-
-//! Queries for the number of audio devices available.  See \ref
-//! RtAudio::getDeviceCount().
-RTAUDIOAPI int rtaudio_device_count(rtaudio_t audio);
-
-//! Return a struct rtaudio_device_info for a specified device number.
-//! See \ref RtAudio::getDeviceInfo().
-RTAUDIOAPI rtaudio_device_info_t rtaudio_get_device_info(rtaudio_t audio,
-                                                         int i);
-
-//! Returns the index of the default output device.  See \ref
-//! RtAudio::getDefaultOutputDevice().
-RTAUDIOAPI unsigned int rtaudio_get_default_output_device(rtaudio_t audio);
-
-//! Returns the index of the default input device.  See \ref
-//! RtAudio::getDefaultInputDevice().
-RTAUDIOAPI unsigned int rtaudio_get_default_input_device(rtaudio_t audio);
-
-//! Opens a stream with the specified parameters.  See \ref RtAudio::openStream().
-//! \return an \ref rtaudio_error.
-RTAUDIOAPI int
-rtaudio_open_stream(rtaudio_t audio, rtaudio_stream_parameters_t *output_params,
-                    rtaudio_stream_parameters_t *input_params,
-                    rtaudio_format_t format, unsigned int sample_rate,
-                    unsigned int *buffer_frames, rtaudio_cb_t cb,
-                    void *userdata, rtaudio_stream_options_t *options,
-                    rtaudio_error_cb_t errcb);
-
-//! Closes a stream and frees any associated stream memory.  See \ref RtAudio::closeStream().
-RTAUDIOAPI void rtaudio_close_stream(rtaudio_t audio);
-
-//! Starts a stream.  See \ref RtAudio::startStream().
-RTAUDIOAPI int rtaudio_start_stream(rtaudio_t audio);
-
-//! Stop a stream, allowing any samples remaining in the output queue
-//! to be played.  See \ref RtAudio::stopStream().
-RTAUDIOAPI int rtaudio_stop_stream(rtaudio_t audio);
-
-//! Stop a stream, discarding any samples remaining in the
-//! input/output queue.  See \ref RtAudio::abortStream().
-RTAUDIOAPI int rtaudio_abort_stream(rtaudio_t audio);
-
-//! Returns 1 if a stream is open and false if not.  See \ref RtAudio::isStreamOpen().
-RTAUDIOAPI int rtaudio_is_stream_open(rtaudio_t audio);
-
-//! Returns 1 if a stream is running and false if it is stopped or not
-//! open.  See \ref RtAudio::isStreamRunning().
-RTAUDIOAPI int rtaudio_is_stream_running(rtaudio_t audio);
-
-//! Returns the number of elapsed seconds since the stream was
-//! started.  See \ref RtAudio::getStreamTime().
-RTAUDIOAPI double rtaudio_get_stream_time(rtaudio_t audio);
-
-//! Set the stream time to a time in seconds greater than or equal to
-//! 0.0.  See \ref RtAudio::setStreamTime().
-RTAUDIOAPI void rtaudio_set_stream_time(rtaudio_t audio, double time);
-
-//! Returns the internal stream latency in sample frames.  See \ref
-//! RtAudio::getStreamLatency().
-RTAUDIOAPI int rtaudio_get_stream_latency(rtaudio_t audio);
-
-//! Returns actual sample rate in use by the stream.  See \ref
-//! RtAudio::getStreamSampleRate().
-RTAUDIOAPI unsigned int rtaudio_get_stream_sample_rate(rtaudio_t audio);
-
-//! Specify whether warning messages should be printed to stderr.  See
-//! \ref RtAudio::showWarnings().
-RTAUDIOAPI void rtaudio_show_warnings(rtaudio_t audio, int show);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* RTAUDIO_C_H */
-
-/*! }@ */

+ 6 - 45
source/AudioEncode/AudioEncode.pro

@@ -13,12 +13,16 @@ OBJECTS_DIR = obj/Obj
 #DESTDIR=$$PWD/bin/
 contains(QT_ARCH, i386) {
     message("32-bit")
-    DESTDIR = $${PWD}/bin32
+    DESTDIR = $${PWD}/../../bin/win32
 } else {
     message("64-bit")
-    DESTDIR = $${PWD}/bin64
+    DESTDIR = $${PWD}/../../bin/win64
 }
 
+include($$PWD/../../lib/lib.pri)
+
+INCLUDEPATH += $$PWD/src
+
 SOURCES += \
         src/AppConfig.cpp \
         src/Audio/AudioEncoder.cpp \
@@ -41,46 +45,3 @@ HEADERS += \
     src/Mix/PcmMix.h \
     src/Mutex/Cond.h \
     src/Mutex/Mutex.h
-
-win32{
-
-    contains(QT_ARCH, i386) {
-        message("32-bit")
-        INCLUDEPATH += $$PWD/lib/win32/ffmpeg/include \
-                       $$PWD/src
-
-        LIBS += -L$$PWD/lib/win32/ffmpeg/lib -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lpostproc -lswresample -lswscale
-
-    } else {
-        message("64-bit")
-        INCLUDEPATH += $$PWD/lib/win64/ffmpeg/include \
-                       $$PWD/src
-
-        LIBS += -L$$PWD/lib/win64/ffmpeg/lib -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lpostproc -lswresample -lswscale
-
-    }
-
-    LIBS += -lWS2_32 -lUser32 -lGDI32 -lAdvAPI32 -lwinmm -lshell32
-}
-
-unix{
-    contains(QT_ARCH, i386) {
-        message("32-bit, 请自行编译32位库!")
-    } else {
-        message("64-bit")
-        INCLUDEPATH += $$PWD/lib/linux/ffmpeg/include \
-                       $$PWD/src
-
-        LIBS += -L$$PWD/lib/linux/ffmpeg/lib  -lavformat  -lavcodec -lavdevice -lavfilter -lavutil -lswresample -lswscale -lpostproc
-
-        LIBS += -lpthread -ldl
-    }
-
-#QMAKE_POST_LINK 表示编译后执行内容
-#QMAKE_PRE_LINK 表示编译前执行内容
-
-#解压库文件
-#QMAKE_PRE_LINK += "cd $$PWD/lib/linux && tar xvzf ffmpeg.tar.gz "
-system("cd $$PWD/lib/linux && tar xvzf ffmpeg.tar.gz")
-
-}

+ 6 - 3
source/FFMPEG_Qt/FFMPEG_Qt.pro

@@ -12,18 +12,21 @@ OBJECTS_DIR = obj/Obj
 #DESTDIR=$$PWD/bin/
 contains(QT_ARCH, i386) {
     message("32-bit")
-    DESTDIR = $${PWD}/bin/bin32
+    DESTDIR = $${PWD}/../../bin/win32
 } else {
     message("64-bit")
-    DESTDIR = $${PWD}/bin/bin64
+    DESTDIR = $${PWD}/../../bin/win64
 }
 
-include($$PWD/lib/lib.pri)
+include($$PWD/../../lib/lib.pri)
 
 INCLUDEPATH += $$PWD/src
 
 win32{
     INCLUDEPATH += $$PWD/src/compat/atomics/win32
+
+    INCLUDEPATH += $$PWD/../../lib/ffmpeg/include/libavutil
+    INCLUDEPATH += $$PWD/../../lib/ffmpeg/include/libavformat
 }
 
 HEADERS += \

+ 2 - 2
source/FFmpegDemo.pro

@@ -4,5 +4,5 @@ SUBDIRS += FFMPEG_Qt/FFMPEG_Qt.pro
 SUBDIRS += OtherDemo/mydemo/mydemo.pro
 SUBDIRS += AudioEncode/AudioEncode.pro
 SUBDIRS += AudioDecode/AudioDecode.pro
-SUBDIRS += VideoEncode/VideoEncode.pro
-SUBDIRS += VideoDecode/VideoDecode.pro
+#SUBDIRS += VideoEncode/VideoEncode.pro
+#SUBDIRS += VideoDecode/VideoDecode.pro

+ 3 - 3
source/OtherDemo/mydemo/FilterDemo/TestAvFilter.pro

@@ -12,13 +12,13 @@ OBJECTS_DIR = obj/Obj
 #DESTDIR=$$PWD/bin/
 contains(QT_ARCH, i386) {
     message("32-bit")
-    DESTDIR = $${PWD}/../../bin/bin32
+    DESTDIR = $${PWD}/../../../../bin/win32
 } else {
     message("64-bit")
-    DESTDIR = $${PWD}/../../bin/bin64
+    DESTDIR = $${PWD}/../../../../bin/win64
 }
 
-include($$PWD/../../lib/lib.pri)
+include($$PWD/../../../../lib/lib.pri)
 
 SOURCES += src/main.cpp \
            src/crop.cpp \

+ 3 - 0
拷贝依赖dll.bat

@@ -0,0 +1,3 @@
+%~dp0
+xcopy %~dp0\lib\ffmpeg\bin\win32\*.dll %~dp0\bin\win32 /y
+xcopy %~dp0\lib\SDL2\bin\win32\*.dll %~dp0\bin\win32 /y