]> Repos - portaudio/commitdiff
Add asio lib.
authorDaShun <dashun.c@tc-gaming.com>
Tue, 17 Apr 2018 03:36:55 +0000 (11:36 +0800)
committerDaShun <dashun.c@tc-gaming.com>
Tue, 17 Apr 2018 03:36:55 +0000 (11:36 +0800)
42 files changed:
src/hostapi/asio/ASIOSDK/ASIO SDK 2.3.pdf [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/Steinberg ASIO Licensing Agreement.pdf [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/asio/asio.dsw [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/asio/asio.opt [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/changes.txt [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/asio.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/asio.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/asiodrvr.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/asiodrvr.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/asiosys.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/combase.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/combase.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/debugmessage.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/dllentry.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/iasiodrv.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/register.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/common/wxdebug.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample.def [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample.txt [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample/asiosample.dsp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample/asiosample.vcproj [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/driver/asiosample/asiosmpl.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/driver/asiosample/asiosmpl.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/driver/asiosample/macnanosecs.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/driver/asiosample/mactimer.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/driver/asiosample/makesamp.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/driver/asiosample/wintimer.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/ASIOConvertSamples.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/ASIOConvertSamples.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/asiodrivers.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/asiodrivers.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/ginclude.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/mac/asioshlib.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/mac/codefragments.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/mac/codefragments.hpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/pc/asiolist.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/pc/asiolist.h [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/sample/hostsample.cpp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/sample/hostsample.dsp [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/host/sample/hostsample.vcproj [new file with mode: 0644]
src/hostapi/asio/ASIOSDK/readme.txt [new file with mode: 0644]
src/hostapi/asio/asiosdk2.3.zip [new file with mode: 0644]

diff --git a/src/hostapi/asio/ASIOSDK/ASIO SDK 2.3.pdf b/src/hostapi/asio/ASIOSDK/ASIO SDK 2.3.pdf
new file mode 100644 (file)
index 0000000..378553c
Binary files /dev/null and b/src/hostapi/asio/ASIOSDK/ASIO SDK 2.3.pdf differ
diff --git a/src/hostapi/asio/ASIOSDK/Steinberg ASIO Licensing Agreement.pdf b/src/hostapi/asio/ASIOSDK/Steinberg ASIO Licensing Agreement.pdf
new file mode 100644 (file)
index 0000000..492db70
Binary files /dev/null and b/src/hostapi/asio/ASIOSDK/Steinberg ASIO Licensing Agreement.pdf differ
diff --git a/src/hostapi/asio/ASIOSDK/asio/asio.dsw b/src/hostapi/asio/ASIOSDK/asio/asio.dsw
new file mode 100644 (file)
index 0000000..14bc965
--- /dev/null
@@ -0,0 +1,41 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "asiosample"="..\driver\asiosample\asiosample\asiosample.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "hostsample"="..\host\sample\hostsample.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/hostapi/asio/ASIOSDK/asio/asio.opt b/src/hostapi/asio/ASIOSDK/asio/asio.opt
new file mode 100644 (file)
index 0000000..ef444d6
Binary files /dev/null and b/src/hostapi/asio/ASIOSDK/asio/asio.opt differ
diff --git a/src/hostapi/asio/ASIOSDK/changes.txt b/src/hostapi/asio/ASIOSDK/changes.txt
new file mode 100644 (file)
index 0000000..22c4428
--- /dev/null
@@ -0,0 +1,12 @@
+Changes in ASIO 2.3 since ASIO 2.2
+- added host queries to detect the driver's buffering and drop-out detection capabilities
+- some additional documentation on MMCSS; see page 46 of 'ASIO SDK 2.3.pdf'
+- dropped support for Mac OS 8 and 9
+
+Changes in ASIO 2.2 since ASIO 2.1
+- added support for Windows 64 bit
+
+Changes in ASIO 2.1 since ASIO 2.0
+- Sony DSD support added
+- fixed Windows registry sample to HKEY_LOCAL_MACHINE
+- fixed a definition problem for input monitoring
diff --git a/src/hostapi/asio/ASIOSDK/common/asio.cpp b/src/hostapi/asio/ASIOSDK/common/asio.cpp
new file mode 100644 (file)
index 0000000..747b9e8
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+       Steinberg Audio Stream I/O API
+       (c) 1996, Steinberg Soft- und Hardware GmbH
+
+       asio.cpp
+       
+       asio functions entries which translate the
+       asio interface to the asiodrvr class methods
+*/ 
+       
+#include <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 "windows.h"
+#include "iasiodrv.h"
+#include "asiodrivers.h"
+
+IASIO *theAsioDriver = 0;
+extern AsioDrivers *asioDrivers;
+
+#elif SGI || SUN || BEOS || LINUX
+#include "asiodrvr.h"
+static AsioDriver *theAsioDriver = 0;
+#endif
+
+//-----------------------------------------------------------------------------------------------------
+ASIOError ASIOInit(ASIODriverInfo *info)
+{
+#if MAC || SGI || SUN || BEOS || LINUX
+       if(theAsioDriver)
+       {
+               delete theAsioDriver;
+               theAsioDriver = 0;
+       }               
+       info->driverVersion = 0;
+       strcpy(info->name, "No ASIO Driver");
+       theAsioDriver = getDriver();
+       if(!theAsioDriver)
+       {
+               strcpy(info->errorMessage, "Not enough memory for the ASIO driver!"); 
+               return ASE_NotPresent;
+       }
+       if(!theAsioDriver->init(info->sysRef))
+       {
+               theAsioDriver->getErrorMessage(info->errorMessage);
+               delete theAsioDriver;
+               theAsioDriver = 0;
+               return ASE_NotPresent;
+       }
+       strcpy(info->errorMessage, "No ASIO Driver Error");
+       theAsioDriver->getDriverName(info->name);
+       info->driverVersion = theAsioDriver->getDriverVersion();
+       return ASE_OK;
+
+#else
+
+       info->driverVersion = 0;
+       strcpy(info->name, "No ASIO Driver");
+       if(theAsioDriver)       // must be loaded!
+       {
+               if(!theAsioDriver->init(info->sysRef))
+               {
+                       theAsioDriver->getErrorMessage(info->errorMessage);
+                       theAsioDriver = 0;
+                       return ASE_NotPresent;
+               }               
+
+               strcpy(info->errorMessage, "No ASIO Driver Error");
+               theAsioDriver->getDriverName(info->name);
+               info->driverVersion = theAsioDriver->getDriverVersion();
+               return ASE_OK;
+       }
+       return ASE_NotPresent;
+
+#endif // !MAC
+}
+
+ASIOError ASIOExit(void)
+{
+       if(theAsioDriver)
+       {
+#if WINDOWS
+               asioDrivers->removeCurrentDriver();
+#else
+               delete theAsioDriver;
+#endif
+       }               
+       theAsioDriver = 0;
+       return ASE_OK;
+}
+
+ASIOError ASIOStart(void)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->start();
+}
+
+ASIOError ASIOStop(void)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->stop();
+}
+
+ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels)
+{
+       if(!theAsioDriver)
+       {
+               *numInputChannels = *numOutputChannels = 0;
+               return ASE_NotPresent;
+       }
+       return theAsioDriver->getChannels(numInputChannels, numOutputChannels);
+}
+
+ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency)
+{
+       if(!theAsioDriver)
+       {
+               *inputLatency = *outputLatency = 0;
+               return ASE_NotPresent;
+       }
+       return theAsioDriver->getLatencies(inputLatency, outputLatency);
+}
+
+ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity)
+{
+       if(!theAsioDriver)
+       {
+               *minSize = *maxSize = *preferredSize = *granularity = 0;
+               return ASE_NotPresent;
+       }
+       return theAsioDriver->getBufferSize(minSize, maxSize, preferredSize, granularity);
+}
+
+ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->canSampleRate(sampleRate);
+}
+
+ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->getSampleRate(currentRate);
+}
+
+ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->setSampleRate(sampleRate);
+}
+
+ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources)
+{
+       if(!theAsioDriver)
+       {
+               *numSources = 0;
+               return ASE_NotPresent;
+       }
+       return theAsioDriver->getClockSources(clocks, numSources);
+}
+
+ASIOError ASIOSetClockSource(long reference)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->setClockSource(reference);
+}
+
+ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->getSamplePosition(sPos, tStamp);
+}
+
+ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info)
+{
+       if(!theAsioDriver)
+       {
+               info->channelGroup = -1;
+               info->type = ASIOSTInt16MSB;
+               strcpy(info->name, "None");
+               return ASE_NotPresent;
+       }
+       return theAsioDriver->getChannelInfo(info);
+}
+
+ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
+       long bufferSize, ASIOCallbacks *callbacks)
+{
+       if(!theAsioDriver)
+       {
+               ASIOBufferInfo *info = bufferInfos;
+               for(long i = 0; i < numChannels; i++, info++)
+                       info->buffers[0] = info->buffers[1] = 0;
+               return ASE_NotPresent;
+       }
+       return theAsioDriver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks);
+}
+
+ASIOError ASIODisposeBuffers(void)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->disposeBuffers();
+}
+
+ASIOError ASIOControlPanel(void)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->controlPanel();
+}
+
+ASIOError ASIOFuture(long selector, void *opt)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->future(selector, opt);
+}
+
+ASIOError ASIOOutputReady(void)
+{
+       if(!theAsioDriver)
+               return ASE_NotPresent;
+       return theAsioDriver->outputReady();
+}
+
+#if MAC
+}      // extern "C"
+#pragma export off
+#endif
+
+
diff --git a/src/hostapi/asio/ASIOSDK/common/asio.h b/src/hostapi/asio/ASIOSDK/common/asio.h
new file mode 100644 (file)
index 0000000..341e755
--- /dev/null
@@ -0,0 +1,1070 @@
+//---------------------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------------------
+
+/*
+       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
+
diff --git a/src/hostapi/asio/ASIOSDK/common/asiodrvr.cpp b/src/hostapi/asio/ASIOSDK/common/asiodrvr.cpp
new file mode 100644 (file)
index 0000000..6ada6f6
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+       Steinberg Audio Stream I/O API
+       (c) 1996, Steinberg Soft- und Hardware GmbH
+       charlie (May 1996)
+
+       asiodrvr.cpp
+       c++ superclass to implement asio functionality. from this,
+       you can derive whatever required
+*/
+
+#include <string.h>
+#include "asiosys.h"
+#include "asiodrvr.h"
+
+#if WINDOWS
+#error do not use this
+AsioDriver::AsioDriver (LPUNKNOWN pUnk, HRESULT *phr) : CUnknown("My AsioDriver", pUnk, phr)
+{
+}
+
+#else
+
+AsioDriver::AsioDriver()
+{
+}
+
+#endif
+
+AsioDriver::~AsioDriver()
+{
+}
+
+ASIOBool AsioDriver::init(void *sysRef)
+{
+       return ASE_NotPresent;
+}
+
+void AsioDriver::getDriverName(char *name)
+{
+       strcpy(name, "No Driver");
+}
+
+long AsioDriver::getDriverVersion()
+{
+       return 0;
+}
+
+void AsioDriver::getErrorMessage(char *string)
+{
+       strcpy(string, "ASIO Driver Implementation Error!");
+}
+
+ASIOError AsioDriver::start()
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::stop()
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::getChannels(long *numInputChannels, long *numOutputChannels)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::getLatencies(long *inputLatency, long *outputLatency)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::getBufferSize(long *minSize, long *maxSize,
+               long *preferredSize, long *granularity)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::canSampleRate(ASIOSampleRate sampleRate)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::getSampleRate(ASIOSampleRate *sampleRate)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::setSampleRate(ASIOSampleRate sampleRate)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::getClockSources(ASIOClockSource *clocks, long *numSources)
+{
+       *numSources = 0;
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::setClockSource(long reference)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::getChannelInfo(ASIOChannelInfo *info)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::createBuffers(ASIOBufferInfo *channelInfos, long numChannels,
+               long bufferSize, ASIOCallbacks *callbacks)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::disposeBuffers()
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::controlPanel()
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::future(long selector, void *opt)
+{
+       return ASE_NotPresent;
+}
+
+ASIOError AsioDriver::outputReady()
+{
+       return ASE_NotPresent;
+}
\ No newline at end of file
diff --git a/src/hostapi/asio/ASIOSDK/common/asiodrvr.h b/src/hostapi/asio/ASIOSDK/common/asiodrvr.h
new file mode 100644 (file)
index 0000000..1670dfa
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+       Steinberg Audio Stream I/O API
+       (c) 1996, Steinberg Soft- und Hardware GmbH
+       charlie (May 1996)
+
+       asiodrvr.h
+       c++ superclass to implement asio functionality. from this,
+       you can derive whatever required
+*/
+
+#ifndef _asiodrvr_
+#define _asiodrvr_
+
+// cpu and os system we are running on
+#include "asiosys.h"
+// basic "C" interface
+#include "asio.h"
+
+class AsioDriver;
+extern AsioDriver *getDriver();                // for generic constructor 
+
+#if WINDOWS
+#include <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
diff --git a/src/hostapi/asio/ASIOSDK/common/asiosys.h b/src/hostapi/asio/ASIOSDK/common/asiosys.h
new file mode 100644 (file)
index 0000000..b4c7a8b
--- /dev/null
@@ -0,0 +1,82 @@
+#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
diff --git a/src/hostapi/asio/ASIOSDK/common/combase.cpp b/src/hostapi/asio/ASIOSDK/common/combase.cpp
new file mode 100644 (file)
index 0000000..84b64f8
--- /dev/null
@@ -0,0 +1,202 @@
+//==========================================================================;
+//
+//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+//  PURPOSE.
+//
+//  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
+//
+//--------------------------------------------------------------------------;
+
+// Base class hierachy for creating COM objects, December 1994
+
+#include <windows.h>
+#include "wxdebug.h"
+#include "combase.h"
+#pragma warning( disable : 4514 )   // Disable warnings re unused inline functions
+
+
+/* Define the static member variable */
+
+LONG CBaseObject::m_cObjects = 0;
+
+
+/* Constructor */
+
+CBaseObject::CBaseObject(TCHAR *pName)
+{
+    /* Increment the number of active objects */
+    InterlockedIncrement(&m_cObjects);
+
+#ifdef DEBUG
+    m_dwCookie = DbgRegisterObjectCreation(pName);
+#endif
+}
+
+
+/* Destructor */
+
+CBaseObject::~CBaseObject()
+{
+    /* Decrement the number of objects active */
+    InterlockedDecrement(&m_cObjects);
+
+#ifdef DEBUG
+    DbgRegisterObjectDestruction(m_dwCookie);
+#endif
+}
+
+
+/* Constructor */
+
+// We know we use "this" in the initialization list, we also know we don't modify *phr.
+#pragma warning( disable : 4355 4100 ) 
+CUnknown::CUnknown(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr) 
+: CBaseObject(pName)
+/* Start the object with a reference count of zero - when the      */
+/* object is queried for it's first interface this may be          */
+/* incremented depending on whether or not this object is          */
+/* currently being aggregated upon                                 */
+, m_cRef(0)
+/* Set our pointer to our IUnknown interface.                      */
+/* If we have an outer, use its, otherwise use ours.               */
+/* This pointer effectivly points to the owner of                  */
+/* this object and can be accessed by the GetOwner() method.       */
+, m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
+ /* Why the double cast?  Well, the inner cast is a type-safe cast */
+ /* to pointer to a type from which we inherit.  The second is     */
+ /* type-unsafe but works because INonDelegatingUnknown "behaves   */
+ /* like" IUnknown. (Only the names on the methods change.)        */
+{
+    // Everything we need to do has been done in the initializer list
+}
+#pragma warning( default : 4355 4100 ) 
+
+/* QueryInterface */
+
+STDMETHODIMP CUnknown::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
+{
+    CheckPointer(ppv,E_POINTER);
+    ValidateReadWritePtr(ppv,sizeof(PVOID));
+
+    /* We know only about IUnknown */
+
+    if (riid == IID_IUnknown) {
+        GetInterface((LPUNKNOWN) (PNDUNKNOWN) this, ppv);
+        return NOERROR;
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+}
+
+/* We have to ensure that we DON'T use a max macro, since these will typically   */
+/* lead to one of the parameters being evaluated twice.  Since we are worried    */
+/* about concurrency, we can't afford to access the m_cRef twice since we can't  */
+/* afford to run the risk that its value having changed between accesses.        */
+#ifdef max
+    #undef max
+#endif
+
+template<class T> inline static T max( const T & a, const T & b )
+{
+    return a > b ? a : b;
+}
+
+/* AddRef */
+
+STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef()
+{
+    LONG lRef = InterlockedIncrement( &m_cRef );
+    ASSERT(lRef > 0);
+    DbgLog((LOG_MEMORY,3,TEXT("    Obj %d ref++ = %d"),
+           m_dwCookie, m_cRef));
+    return max(ULONG(m_cRef), 1ul);
+}
+
+
+
+/* Release */
+
+STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease()
+{
+    /* If the reference count drops to zero delete ourselves */
+
+    LONG lRef = InterlockedDecrement( &m_cRef );
+    ASSERT(lRef >= 0);
+
+    DbgLog((LOG_MEMORY,3,TEXT("    Object %d ref-- = %d"),
+           m_dwCookie, m_cRef));
+    if (lRef == 0) {
+
+        // COM rules say we must protect against re-entrancy.
+        // If we are an aggregator and we hold our own interfaces
+        // on the aggregatee, the QI for these interfaces will
+        // addref ourselves. So after doing the QI we must release
+        // a ref count on ourselves. Then, before releasing the
+        // private interface, we must addref ourselves. When we do
+        // this from the destructor here it will result in the ref
+        // count going to 1 and then back to 0 causing us to
+        // re-enter the destructor. Hence we add an extra refcount here
+        // once we know we will delete the object.
+        // for an example aggregator see filgraph\distrib.cpp.
+
+        m_cRef++;
+
+        delete this;
+        return ULONG(0);
+    } else {
+        return max(ULONG(m_cRef), 1ul);
+    }
+}
+
+
+/* Return an interface pointer to a requesting client
+   performing a thread safe AddRef as necessary */
+
+HRESULT CUnknown::GetInterface(LPUNKNOWN pUnk, void **ppv)
+{
+    CheckPointer(ppv, E_POINTER);
+    *ppv = pUnk;
+    pUnk->AddRef();
+    return NOERROR;
+}
+
+
+/* Compares two interfaces and returns TRUE if they are on the same object */
+
+BOOL IsEqualObject(IUnknown *pFirst, IUnknown *pSecond)
+{
+    /*  Different objects can't have the same interface pointer for
+        any interface
+    */
+    if (pFirst == pSecond) {
+        return TRUE;
+    }
+    /*  OK - do it the hard way - check if they have the same
+        IUnknown pointers - a single object can only have one of these
+    */
+    LPUNKNOWN pUnknown1;     // Retrieve the IUnknown interface
+    LPUNKNOWN pUnknown2;     // Retrieve the other IUnknown interface
+    HRESULT hr;              // General OLE return code
+
+    ASSERT(pFirst);
+    ASSERT(pSecond);
+
+    /* See if the IUnknown pointers match */
+
+    hr = pFirst->QueryInterface(IID_IUnknown,(void **) &pUnknown1);
+    ASSERT(SUCCEEDED(hr));
+    ASSERT(pUnknown1);
+
+    hr = pSecond->QueryInterface(IID_IUnknown,(void **) &pUnknown2);
+    ASSERT(SUCCEEDED(hr));
+    ASSERT(pUnknown2);
+
+    /* Release the extra interfaces we hold */
+
+    pUnknown1->Release();
+    pUnknown2->Release();
+    return (pUnknown1 == pUnknown2);
+}
diff --git a/src/hostapi/asio/ASIOSDK/common/combase.h b/src/hostapi/asio/ASIOSDK/common/combase.h
new file mode 100644 (file)
index 0000000..6141803
--- /dev/null
@@ -0,0 +1,284 @@
+//==========================================================================;
+//
+//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+//  PURPOSE.
+//
+//  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
+//
+//--------------------------------------------------------------------------;
+
+// Base class hierachy for creating COM objects, December 1994
+
+/*
+
+a. Derive your COM object from CUnknown
+
+b. Make a static CreateInstance function that takes an LPUNKNOWN, an HRESULT *
+   and a TCHAR *. The LPUNKNOWN defines the object to delegate IUnknown calls
+   to. The HRESULT * allows error codes to be passed around constructors and
+   the TCHAR * is a descriptive name that can be printed on the debugger.
+
+   It is important that constructors only change the HRESULT * if they have
+   to set an ERROR code, if it was successful then leave it alone or you may
+   overwrite an error code from an object previously created.
+
+   When you call a constructor the descriptive name should be in static store
+   as we do not copy the string. To stop large amounts of memory being used
+   in retail builds by all these static strings use the NAME macro,
+
+   CMyFilter = new CImplFilter(NAME("My filter"),pUnknown,phr);
+   if (FAILED(hr)) {
+       return hr;
+   }
+
+   In retail builds NAME(_x_) compiles to NULL, the base CBaseObject class
+   knows not to do anything with objects that don't have a name.
+
+c. Have a constructor for your object that passes the LPUNKNOWN, HRESULT * and
+   TCHAR * to the CUnknown constructor. You can set the HRESULT if you have an
+   error, or just simply pass it through to the constructor.
+
+   The object creation will fail in the class factory if the HRESULT indicates
+   an error (ie FAILED(HRESULT) == TRUE)
+
+d. Create a FactoryTemplate with your object's class id and CreateInstance
+   function.
+
+Then (for each interface) either
+
+Multiple inheritance
+
+1. Also derive it from ISomeInterface
+2. Include DECLARE_IUNKNOWN in your class definition to declare
+   implementations of QueryInterface, AddRef and Release that
+   call the outer unknown
+3. Override NonDelegatingQueryInterface to expose ISomeInterface by
+   code something like
+
+     if (riid == IID_ISomeInterface) {
+         return GetInterface((ISomeInterface *) this, ppv);
+     } else {
+         return CUnknown::NonDelegatingQueryInterface(riid, ppv);
+     }
+
+4. Declare and implement the member functions of ISomeInterface.
+
+or: Nested interfaces
+
+1. Declare a class derived from CUnknown
+2. Include DECLARE_IUNKNOWN in your class definition
+3. Override NonDelegatingQueryInterface to expose ISomeInterface by
+   code something like
+
+     if (riid == IID_ISomeInterface) {
+         return GetInterface((ISomeInterface *) this, ppv);
+     } else {
+         return CUnknown::NonDelegatingQueryInterface(riid, ppv);
+     }
+
+4. Implement the member functions of ISomeInterface. Use GetOwner() to
+   access the COM object class.
+
+And in your COM object class:
+
+5. Make the nested class a friend of the COM object class, and declare
+   an instance of the nested class as a member of the COM object class.
+
+   NOTE that because you must always pass the outer unknown and an hResult
+   to the CUnknown constructor you cannot use a default constructor, in
+   other words you will have to make the member variable a pointer to the
+   class and make a NEW call in your constructor to actually create it.
+
+6. override the NonDelegatingQueryInterface with code like this:
+
+     if (riid == IID_ISomeInterface) {
+         return m_pImplFilter->
+            NonDelegatingQueryInterface(IID_ISomeInterface, ppv);
+     } else {
+         return CUnknown::NonDelegatingQueryInterface(riid, ppv);
+     }
+
+You can have mixed classes which support some interfaces via multiple
+inheritance and some via nested classes
+
+*/
+
+#ifndef __COMBASE__
+#define __COMBASE__
+
+/* The DLLENTRY module initialises the module handle on loading */
+
+extern HINSTANCE g_hInst;
+
+/* On DLL load remember which platform we are running on */
+
+extern DWORD g_amPlatform;
+extern OSVERSIONINFO g_osInfo;     // Filled in by GetVersionEx
+
+/* Version of IUnknown that is renamed to allow a class to support both
+   non delegating and delegating IUnknowns in the same COM object */
+
+DECLARE_INTERFACE(INonDelegatingUnknown)
+{
+    STDMETHOD(NonDelegatingQueryInterface) (THIS_ REFIID, LPVOID *) PURE;
+    STDMETHOD_(ULONG, NonDelegatingAddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, NonDelegatingRelease)(THIS) PURE;
+};
+
+typedef INonDelegatingUnknown *PNDUNKNOWN;
+
+
+/* This is the base object class that supports active object counting. As
+   part of the debug facilities we trace every time a C++ object is created
+   or destroyed. The name of the object has to be passed up through the class
+   derivation list during construction as you cannot call virtual functions
+   in the constructor. The downside of all this is that every single object
+   constructor has to take an object name parameter that describes it */
+
+class CBaseObject
+{
+
+private:
+
+    // Disable the copy constructor and assignment by default so you will get
+    //   compiler errors instead of unexpected behaviour if you pass objects
+    //   by value or assign objects.
+    CBaseObject(const CBaseObject& objectSrc);          // no implementation
+    void operator=(const CBaseObject& objectSrc);       // no implementation
+
+private:
+    static LONG m_cObjects;     /* Total number of objects active */
+
+protected:
+#ifdef DEBUG
+    DWORD m_dwCookie;           /* Cookie identifying this object */
+#endif
+
+
+public:
+
+    /* These increment and decrement the number of active objects */
+
+    CBaseObject(TCHAR *pName);
+    ~CBaseObject();
+
+    /* Call this to find if there are any CUnknown derived objects active */
+
+    static LONG ObjectsActive() {
+        return m_cObjects;
+    };
+};
+
+
+/* An object that supports one or more COM interfaces will be based on
+   this class. It supports counting of total objects for DLLCanUnloadNow
+   support, and an implementation of the core non delegating IUnknown */
+
+class CUnknown : public INonDelegatingUnknown,
+                 public CBaseObject
+{
+
+private:
+    const LPUNKNOWN m_pUnknown; /* Owner of this object */
+
+protected:                      /* So we can override NonDelegatingRelease() */
+    volatile LONG m_cRef;       /* Number of reference counts */
+
+public:
+
+    CUnknown(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr);
+    virtual ~CUnknown() {};
+
+    /* Return the owner of this object */
+
+    LPUNKNOWN GetOwner() const {
+        return m_pUnknown;
+    };
+
+    /* Called from the class factory to create a new instance, it is
+       pure virtual so it must be overriden in your derived class */
+
+    /* static CUnknown *CreateInstance(LPUNKNOWN, HRESULT *) */
+
+    /* Non delegating unknown implementation */
+
+    STDMETHODIMP NonDelegatingQueryInterface(REFIID, void **);
+    STDMETHODIMP_(ULONG) NonDelegatingAddRef();
+    STDMETHODIMP_(ULONG) NonDelegatingRelease();
+
+    /* Return an interface pointer to a requesting client
+       performing a thread safe AddRef as necessary */
+
+    HRESULT GetInterface(LPUNKNOWN pUnk, void **ppv);
+
+
+};
+
+#if WINVER < 0x0501
+
+/* The standard InterlockedXXX functions won't take volatiles */
+static inline LONG InterlockedIncrement( volatile LONG * plong )
+{ return InterlockedIncrement( const_cast<LONG*>( plong ) ); }
+
+static inline LONG InterlockedDecrement( volatile LONG * plong )
+{ return InterlockedDecrement( const_cast<LONG*>( plong ) ); }
+
+static inline LONG InterlockedExchange( volatile LONG * plong, LONG new_value )
+{ return InterlockedExchange( const_cast<LONG*>( plong ), new_value ); }
+
+#endif
+
+/* A function that can create a new COM object */
+
+typedef CUnknown *(*LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr);
+
+/*  A function (can be NULL) which is called from the DLL entrypoint
+    routine for each factory template:
+
+    bLoading - TRUE on DLL load, FALSE on DLL unload
+    rclsid   - the m_ClsID of the entry
+*/
+typedef void (*LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid);
+
+/* Create one of these per object class in an array so that
+   the default class factory code can create new instances */
+
+class CFactoryTemplate {
+
+public:
+
+    const WCHAR *m_Name;
+    const CLSID *m_ClsID;
+    LPFNNewCOMObject m_lpfnNew;
+    LPFNInitRoutine  m_lpfnInit;
+
+    BOOL IsClassID(REFCLSID rclsid) const {
+        return (IsEqualCLSID(*m_ClsID,rclsid));
+    };
+
+    CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) const {
+        return m_lpfnNew(pUnk, phr);
+    };
+};
+
+
+/* You must override the (pure virtual) NonDelegatingQueryInterface to return
+   interface pointers (using GetInterface) to the interfaces your derived
+   class supports (the default implementation only supports IUnknown) */
+
+#define DECLARE_IUNKNOWN                                        \
+    STDMETHODIMP QueryInterface(REFIID riid, void **ppv) {      \
+        return GetOwner()->QueryInterface(riid,ppv);            \
+    };                                                          \
+    STDMETHODIMP_(ULONG) AddRef() {                             \
+        return GetOwner()->AddRef();                            \
+    };                                                          \
+    STDMETHODIMP_(ULONG) Release() {                            \
+        return GetOwner()->Release();                           \
+    };
+
+#endif /* __COMBASE__ */
+
+
diff --git a/src/hostapi/asio/ASIOSDK/common/debugmessage.cpp b/src/hostapi/asio/ASIOSDK/common/debugmessage.cpp
new file mode 100644 (file)
index 0000000..2f47926
--- /dev/null
@@ -0,0 +1,14 @@
+#include "asiosys.h"
+
+#if DEBUG
+#if MAC
+#include <TextUtils.h>
+void DEBUGGERMESSAGE(char *string)
+{
+       c2pstr(string);
+       DebugStr((unsigned char *)string);
+}
+#else
+#error debugmessage
+#endif
+#endif
diff --git a/src/hostapi/asio/ASIOSDK/common/dllentry.cpp b/src/hostapi/asio/ASIOSDK/common/dllentry.cpp
new file mode 100644 (file)
index 0000000..be717d4
--- /dev/null
@@ -0,0 +1,323 @@
+//==========================================================================;
+//
+//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+//  PURPOSE.
+//
+//  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
+//
+//--------------------------------------------------------------------------;
+
+//
+// classes used to support dll entrypoints for COM objects.
+//
+// #include "switches.h"
+
+#include <windows.h>
+#include "wxdebug.h"
+#include "combase.h"
+#ifdef DEBUG
+#include <tchar.h>
+#endif
+
+#include <stdio.h>
+
+extern CFactoryTemplate g_Templates[];
+extern int g_cTemplates;
+
+HINSTANCE hinstance = 0;
+DWORD    g_amPlatform;         // VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx)
+OSVERSIONINFO g_osInfo;
+
+//
+// an instance of this is created by the DLLGetClassObject entrypoint
+// it uses the CFactoryTemplate object it is given to support the
+// IClassFactory interface
+
+class CClassFactory : public IClassFactory
+{
+
+private:
+    const CFactoryTemplate * m_pTemplate;
+
+    ULONG m_cRef;
+
+    static int m_cLocked;
+public:
+    CClassFactory(const CFactoryTemplate *);
+
+    // IUnknown
+    STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
+    STDMETHODIMP_(ULONG)AddRef();
+    STDMETHODIMP_(ULONG)Release();
+
+    // IClassFactory
+    STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **pv);
+    STDMETHODIMP LockServer(BOOL fLock);
+
+    // allow DLLGetClassObject to know about global server lock status
+    static BOOL IsLocked() {
+        return (m_cLocked > 0);
+    };
+};
+
+// process-wide dll locked state
+int CClassFactory::m_cLocked = 0;
+
+CClassFactory::CClassFactory(const CFactoryTemplate *pTemplate)
+{
+    m_cRef = 0;
+    m_pTemplate = pTemplate;
+}
+
+
+STDMETHODIMP CClassFactory::QueryInterface(REFIID riid,void **ppv)
+{
+    CheckPointer(ppv,E_POINTER)
+    ValidateReadWritePtr(ppv,sizeof(PVOID));
+    *ppv = NULL;
+
+    // any interface on this object is the object pointer.
+    if ((riid == IID_IUnknown) || (riid == IID_IClassFactory)) {
+        *ppv = (LPVOID) this;
+       // AddRef returned interface pointer
+        ((LPUNKNOWN) *ppv)->AddRef();
+        return NOERROR;
+    }
+
+    return ResultFromScode(E_NOINTERFACE);
+}
+
+
+STDMETHODIMP_(ULONG) CClassFactory::AddRef()
+{
+    return ++m_cRef;
+}
+
+STDMETHODIMP_(ULONG) CClassFactory::Release()
+{
+       LONG    rc;
+
+    if (--m_cRef == 0) {
+               delete this;
+               rc = 0;
+    } else rc = m_cRef;
+
+       return rc;
+}
+
+STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,REFIID riid,void **pv)
+{
+       CheckPointer(pv,E_POINTER)
+    ValidateReadWritePtr(pv,sizeof(void *));
+
+    /* Enforce the normal OLE rules regarding interfaces and delegation */
+
+    if (pUnkOuter != NULL) {
+        if (IsEqualIID(riid,IID_IUnknown) == FALSE) {
+            return ResultFromScode(E_NOINTERFACE);
+        }
+    }
+
+    /* Create the new object through the derived class's create function */
+
+    HRESULT hr = NOERROR;
+    CUnknown *pObj = m_pTemplate->CreateInstance(pUnkOuter, &hr);
+
+    if (pObj == NULL) {
+        return E_OUTOFMEMORY;
+    }
+
+    /* Delete the object if we got a construction error */
+
+       if (FAILED(hr)) {
+               delete pObj;
+      return hr;
+   }
+
+    /* Get a reference counted interface on the object */
+
+    /* We wrap the non-delegating QI with NDAddRef & NDRelease. */
+    /* This protects any outer object from being prematurely    */
+    /* released by an inner object that may have to be created  */
+    /* in order to supply the requested interface.              */
+    pObj->NonDelegatingAddRef();
+    hr = pObj->NonDelegatingQueryInterface(riid, pv);
+    pObj->NonDelegatingRelease();
+    /* Note that if NonDelegatingQueryInterface fails, it will  */
+    /* not increment the ref count, so the NonDelegatingRelease */
+    /* will drop the ref back to zero and the object will "self-*/
+    /* destruct".  Hence we don't need additional tidy-up code  */
+    /* to cope with NonDelegatingQueryInterface failing.        */
+
+    if (SUCCEEDED(hr)) {
+        ASSERT(*pv);
+    }
+
+    return hr;
+}
+
+STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
+{
+    if (fLock) {
+        m_cLocked++;
+    } else {
+        m_cLocked--;
+    }
+    return NOERROR;
+}
+
+
+// --- COM entrypoints -----------------------------------------
+// DllRegisterServer
+
+//called by COM to get the class factory object for a given class
+STDAPI DllGetClassObject(REFCLSID rClsID,REFIID riid,void **pv)
+{
+       // DebugBreak();
+
+    if (!(riid == IID_IUnknown) && !(riid == IID_IClassFactory)) {
+            return E_NOINTERFACE;
+    }
+
+    // traverse the array of templates looking for one with this
+    // class id
+    for (int i = 0; i < g_cTemplates; i++) {
+        const CFactoryTemplate * pT = &g_Templates[i];
+        if (pT->IsClassID(rClsID)) {
+
+            // found a template - make a class factory based on this
+            // template
+
+            *pv = (LPVOID) (LPUNKNOWN) new CClassFactory(pT);
+            if (*pv == NULL) {
+                return E_OUTOFMEMORY;
+            }
+            ((LPUNKNOWN)*pv)->AddRef();
+            return NOERROR;
+        }
+    }
+    return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+//
+//  Call any initialization routines
+//
+void DllInitClasses(BOOL bLoading)
+{
+   int i;
+
+       // DebugBreak();
+
+       // traverse the array of templates calling the init routine
+   // if they have one
+   for (i = 0; i < g_cTemplates; i++) {
+               const CFactoryTemplate * pT = &g_Templates[i];
+      if (pT->m_lpfnInit != NULL) {
+                       (*pT->m_lpfnInit)(bLoading, pT->m_ClsID);
+      }
+   }
+
+}
+
+// called by COM to determine if this dll can be unloaded
+// return ok unless there are outstanding objects or a lock requested
+// by IClassFactory::LockServer
+//
+// CClassFactory has a static function that can tell us about the locks,
+// and CCOMObject has a static function that can tell us about the active
+// object count
+STDAPI DllCanUnloadNow()
+{
+       // DebugBreak();
+
+       DbgLog((LOG_MEMORY,2,TEXT("DLLCanUnloadNow called - IsLocked = %d, Active objects = %d"),
+        CClassFactory::IsLocked(),
+        CBaseObject::ObjectsActive()));
+
+   if (CClassFactory::IsLocked() || CBaseObject::ObjectsActive()) {
+       
+               return S_FALSE;
+   } 
+       else {
+               return S_OK;
+   }
+}
+
+
+// --- standard WIN32 entrypoints --------------------------------------
+
+
+//extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
+//BOOL WINAPI DllEntryPoint(HINSTANCE hInstance,ULONG ulReason,LPVOID pv)
+//BOOL WINAPI DllMain (HINSTANCE hInstance,ULONG ulReason,LPVOID pv)
+BOOL WINAPI DllEntryPoint (HINSTANCE hInstance,ULONG ulReason,LPVOID pv)
+{
+
+       // DebugBreak();
+   
+       switch (ulReason) {
+       
+               case DLL_PROCESS_ATTACH:
+                       DisableThreadLibraryCalls(hInstance);
+                       DbgInitialise(hInstance);
+                       {
+                               // The platform identifier is used to work out whether
+                               // full unicode support is available or not.  Hence the
+                               // default will be the lowest common denominator - i.e. N/A
+            g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails
+
+            g_osInfo.dwOSVersionInfoSize = sizeof(g_osInfo);
+            if (GetVersionEx(&g_osInfo)) {
+                               g_amPlatform = g_osInfo.dwPlatformId;
+                               } 
+                               else {
+                                       DbgLog((LOG_ERROR, 1, "Failed to get the OS platform, assuming Win95"));
+                               }
+                       }
+                       hinstance = hInstance;
+                       DllInitClasses(TRUE);
+                       
+                       break;
+
+               case DLL_PROCESS_DETACH:
+                       DllInitClasses(FALSE);
+
+#ifdef DEBUG
+                       if (CBaseObject::ObjectsActive()) {
+                               DbgSetModuleLevel(LOG_MEMORY, 2);
+            TCHAR szInfo[512];
+            extern TCHAR m_ModuleName[];     // Cut down module name
+
+            TCHAR FullName[_MAX_PATH];      // Load the full path and module name
+            TCHAR *pName;                   // Searches from the end for a backslash
+
+            GetModuleFileName(NULL,FullName,_MAX_PATH);
+            pName = _tcsrchr(FullName,'\\');
+            if (pName == NULL) {
+                pName = FullName;
+            } 
+                               else {
+                                       pName++;
+            }
+
+                               DWORD cch = wsprintf(szInfo, TEXT("Executable: %s  Pid %x  Tid %x. "),
+                                       pName, GetCurrentProcessId(), GetCurrentThreadId());
+
+            wsprintf(szInfo+cch, TEXT("Module %s, %d objects left active!"),
+                     m_ModuleName, CBaseObject::ObjectsActive());
+            DbgAssert(szInfo, TEXT(__FILE__),__LINE__);
+
+                               // If running remotely wait for the Assert to be acknowledged
+                               // before dumping out the object register
+            DbgDumpObjectRegister();
+                       }
+                       DbgTerminate();
+#endif
+                       break;
+    }
+    return TRUE;
+}
+
+
diff --git a/src/hostapi/asio/ASIOSDK/common/iasiodrv.h b/src/hostapi/asio/ASIOSDK/common/iasiodrv.h
new file mode 100644 (file)
index 0000000..1496f0f
--- /dev/null
@@ -0,0 +1,37 @@
+#include "asiosys.h"
+#include "asio.h"
+
+/* Forward Declarations */ 
+
+#ifndef __ASIODRIVER_FWD_DEFINED__
+#define __ASIODRIVER_FWD_DEFINED__
+typedef interface IASIO IASIO;
+#endif         /* __ASIODRIVER_FWD_DEFINED__ */
+
+interface IASIO : public IUnknown
+{
+
+       virtual ASIOBool init(void *sysHandle) = 0;
+       virtual void getDriverName(char *name) = 0;     
+       virtual long getDriverVersion() = 0;
+       virtual void getErrorMessage(char *string) = 0; 
+       virtual ASIOError start() = 0;
+       virtual ASIOError stop() = 0;
+       virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0;
+       virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0;
+       virtual ASIOError getBufferSize(long *minSize, long *maxSize,
+               long *preferredSize, long *granularity) = 0;
+       virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0;
+       virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0;
+       virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0;
+       virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0;
+       virtual ASIOError setClockSource(long reference) = 0;
+       virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;
+       virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0;
+       virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
+               long bufferSize, ASIOCallbacks *callbacks) = 0;
+       virtual ASIOError disposeBuffers() = 0;
+       virtual ASIOError controlPanel() = 0;
+       virtual ASIOError future(long selector,void *opt) = 0;
+       virtual ASIOError outputReady() = 0;
+};
diff --git a/src/hostapi/asio/ASIOSDK/common/register.cpp b/src/hostapi/asio/ASIOSDK/common/register.cpp
new file mode 100644 (file)
index 0000000..8c6cbea
--- /dev/null
@@ -0,0 +1,332 @@
+#include <windows.h>
+#include <stdio.h>
+
+typedef struct keylist
+{
+       HKEY            mainKey;
+       HKEY            subKey;
+       char            *keyname;
+       struct keylist  *next;
+} KEYLIST,     *LPKEYLIST;
+
+#define CLSID_STRING_LEN                               100
+#define MAX_PATH_LEN                                   360
+
+#define DEV_ERR_SELFREG                                        -100
+#define ERRSREG_MODULE_NOT_FOUND               DEV_ERR_SELFREG-1
+#define ERRSREG_MODPATH_NOT_FOUND              DEV_ERR_SELFREG-2
+#define ERRSREG_STRING_FROM_CLSID              DEV_ERR_SELFREG-3
+#define ERRSREG_CHAR_TO_MULTIBYTE              DEV_ERR_SELFREG-4
+
+#define SZREGSTR_DESCRIPTION                   "Description"
+#define SZREGSTR_CLSID                                 "CLSID"
+#define SZREGSTR_INPROCSERVER32                        "InprocServer32"
+#define SZREGSTR_THREADINGMODEL                        "ThreadingModel"
+#define SZREGSTR_SOFTWARE                              "SOFTWARE"
+#define SZREGSTR_ASIO                                  "ASIO"
+
+LONG RegisterAsioDriver (CLSID,char *,char *,char *,char *);
+LONG UnregisterAsioDriver (CLSID,char *,char *);
+
+static LONG findRegPath (HKEY,char *);
+static LONG createRegPath (HKEY,char *,char *);
+static LONG createRegStringValue (HKEY,char *,char *,char *);
+static LONG getRegString (HKEY,char *,char *,LPVOID,DWORD);
+static LPKEYLIST findAllSubKeys (HKEY,HKEY,DWORD,char *,LPKEYLIST);
+static LONG deleteRegPath (HKEY,char *,char *);
+
+static char    subkeybuf[MAX_PATH_LEN];
+
+
+// ------------------------------------------
+// Global Functions 
+// ------------------------------------------
+LONG RegisterAsioDriver (CLSID clsid,char *szdllname,char *szregname,char *szasiodesc,char *szthreadmodel)
+{
+       HMODULE                 hMod;
+       char                    szDLLPath[MAX_PATH_LEN];
+       char                    szModuleName[MAX_PATH_LEN];
+       char                    szregpath[MAX_PATH_LEN];
+       char                    szclsid[CLSID_STRING_LEN];
+       LPOLESTR                wszCLSID = NULL;
+       BOOL                    newregentry = FALSE;
+       LONG                    rc;
+
+       hMod = GetModuleHandle(szdllname);
+       if (!hMod) return ERRSREG_MODULE_NOT_FOUND;
+       szModuleName[0] = 0;
+       GetModuleFileName(hMod,szModuleName,MAX_PATH_LEN);
+       if (!szModuleName[0]) return ERRSREG_MODPATH_NOT_FOUND;
+       CharLower((LPTSTR)szModuleName);
+
+       rc = (LONG)StringFromCLSID(clsid,&wszCLSID);
+       if (rc != S_OK) return ERRSREG_STRING_FROM_CLSID;
+       rc = (LONG)WideCharToMultiByte(CP_ACP,0,(LPWSTR)wszCLSID,-1,szclsid,CLSID_STRING_LEN,0,0);
+       if (!rc) return ERRSREG_CHAR_TO_MULTIBYTE;
+
+       sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid);
+       rc = findRegPath(HKEY_CLASSES_ROOT,szregpath);
+       if (rc) {
+               sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_CLSID,szclsid,SZREGSTR_INPROCSERVER32);
+               getRegString (HKEY_CLASSES_ROOT,szregpath,0,(LPVOID)szDLLPath,MAX_PATH_LEN);
+               CharLower((LPTSTR)szDLLPath);
+               rc = (LONG)strcmp(szDLLPath,szModuleName);
+               if (rc) {
+                       // delete old regentry
+                       sprintf(szregpath,"%s",SZREGSTR_CLSID);
+                       deleteRegPath(HKEY_CLASSES_ROOT,szregpath,szclsid);
+                       newregentry = TRUE;
+               }
+       }
+       else newregentry = TRUE;
+
+       if (newregentry) {
+               // HKEY_CLASSES_ROOT\CLSID\{...}
+               sprintf(szregpath,"%s",SZREGSTR_CLSID);
+               createRegPath (HKEY_CLASSES_ROOT,szregpath,szclsid);
+               // HKEY_CLASSES_ROOT\CLSID\{...} -> Description
+               sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid);
+               createRegStringValue(HKEY_CLASSES_ROOT,szregpath,0,szasiodesc);
+               // HKEY_CLASSES_ROOT\CLSID\InProcServer32
+               sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid);
+               createRegPath (HKEY_CLASSES_ROOT,szregpath,SZREGSTR_INPROCSERVER32);
+               // HKEY_CLASSES_ROOT\CLSID\InProcServer32 -> DLL path
+               sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_CLSID,szclsid,SZREGSTR_INPROCSERVER32);
+               createRegStringValue(HKEY_CLASSES_ROOT,szregpath,0,szModuleName);
+               // HKEY_CLASSES_ROOT\CLSID\InProcServer32 -> ThreadingModel
+               createRegStringValue(HKEY_CLASSES_ROOT,szregpath,SZREGSTR_THREADINGMODEL,szthreadmodel);
+       }
+
+       // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO
+       sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO);
+       rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath);
+       if (rc) {
+               sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO,szregname);
+               rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath);
+               if (rc) {
+                       sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO);
+                       deleteRegPath(HKEY_LOCAL_MACHINE,szregpath,szregname);
+               }
+       }
+       else {
+               // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO
+               sprintf(szregpath,"%s",SZREGSTR_SOFTWARE);
+               createRegPath (HKEY_LOCAL_MACHINE,szregpath,SZREGSTR_ASIO);
+       }
+
+       // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\<szregname>
+       sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO);
+       createRegPath (HKEY_LOCAL_MACHINE,szregpath,szregname);
+
+       // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\<szregname> -> CLSID 
+       // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\<szregname> -> Description
+       sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO,szregname);
+       createRegStringValue(HKEY_LOCAL_MACHINE,szregpath,SZREGSTR_CLSID,szclsid);
+       createRegStringValue(HKEY_LOCAL_MACHINE,szregpath,SZREGSTR_DESCRIPTION,szasiodesc);
+
+       return 0;
+}
+
+
+LONG UnregisterAsioDriver (CLSID clsid,char *szdllname,char *szregname)
+{
+       LONG                    rc;
+       HMODULE                 hMod;
+       char                    szregpath[MAX_PATH_LEN];
+       char                    szModuleName[MAX_PATH_LEN];
+       char                    szclsid[CLSID_STRING_LEN];
+       LPOLESTR                wszCLSID = NULL;
+
+
+       hMod = GetModuleHandle(szdllname);
+       if (!hMod) return ERRSREG_MODULE_NOT_FOUND;
+       szModuleName[0] = 0;
+       GetModuleFileName(hMod,szModuleName,MAX_PATH_LEN);
+       if (!szModuleName[0]) return ERRSREG_MODPATH_NOT_FOUND;
+       CharLower((LPTSTR)szModuleName);
+
+       rc = (LONG)StringFromCLSID(clsid,&wszCLSID) ;
+       if (rc != S_OK) return ERRSREG_STRING_FROM_CLSID;
+       rc = (LONG)WideCharToMultiByte(CP_ACP,0,(LPWSTR)wszCLSID,-1,szclsid,CLSID_STRING_LEN,0,0);
+       if (!rc) return ERRSREG_CHAR_TO_MULTIBYTE;
+
+
+       sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid);
+       rc = findRegPath(HKEY_CLASSES_ROOT,szregpath);
+       if (rc) {
+               // delete old regentry
+               sprintf(szregpath,"%s",SZREGSTR_CLSID);
+               deleteRegPath(HKEY_CLASSES_ROOT,szregpath,szclsid);
+       }
+
+
+       // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO
+       sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO);
+       rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath);
+       if (rc) {
+               sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO,szregname);
+               rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath);
+               if (rc) {
+                       sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO);
+                       deleteRegPath(HKEY_LOCAL_MACHINE,szregpath,szregname);
+               }
+       }
+
+       return 0;
+}
+
+
+// ------------------------------------------
+// Local Functions 
+// ------------------------------------------
+static LONG findRegPath (HKEY mainkey,char *szregpath)
+{
+       HKEY    hkey;
+       LONG    cr,rc = -1;
+       
+       if (szregpath) {
+               if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) {
+                       RegCloseKey(hkey);
+                       rc = 1;
+               }
+               else rc = 0;
+       }
+
+       return rc;
+}
+
+static LONG createRegPath (HKEY mainkey,char *szregpath,char *sznewpath)
+{
+       HKEY    hkey,hksub;
+       LONG    cr,rc = -1;
+       char    newregpath[MAX_PATH_LEN];
+       
+       sprintf(newregpath,"%s\\%s",szregpath,sznewpath);
+       if (!(cr = findRegPath(mainkey,newregpath))) {
+               if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) {
+                       if ((cr = RegCreateKey(hkey,sznewpath,&hksub)) == ERROR_SUCCESS) {
+                               RegCloseKey(hksub);
+                               rc = 0;
+                       }
+                       RegCloseKey(hkey);
+               }
+       }
+       else if (cr > 0) rc = 0;
+
+       return rc;
+}
+
+static LONG createRegStringValue (HKEY mainkey,char *szregpath,char *valname,char *szvalstr)
+{
+       LONG    cr,rc = -1;
+       HKEY    hkey;
+
+       if (szregpath) {
+               if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) {
+                       cr = RegSetValueEx(hkey,(LPCTSTR)valname,0,REG_SZ,(const BYTE *)szvalstr,(DWORD)strlen(szvalstr));
+                       RegCloseKey(hkey);
+                       if (cr == ERROR_SUCCESS) rc = 0;
+               }
+       } 
+
+       return rc;
+}
+
+
+static LONG getRegString (HKEY mainkey,char *szregpath,char *valname,LPVOID pval,DWORD vsize)
+{
+       HKEY    hkey;
+       LONG    cr,rc = -1;
+       DWORD   hsize,htype;
+
+       if (szregpath) {
+               if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) {
+                       cr = RegQueryValueEx(hkey,valname,0,&htype,0,&hsize);
+                       if (cr == ERROR_SUCCESS) {
+                               if (hsize <= vsize) {
+                                       cr = RegQueryValueEx(hkey,valname,0,&htype,(LPBYTE)pval,&hsize);
+                                       rc = 0;
+                               }
+                       }
+                       RegCloseKey(hkey);
+               }
+       }
+       return rc;
+}
+
+static LPKEYLIST findAllSubKeys (HKEY hkey,HKEY hksub,DWORD index,char *keyname,LPKEYLIST kl)
+{
+       HKEY    hknew = 0;
+       char    *newkey;
+       LONG    cr;
+
+       if (!hksub) {
+               cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_ALL_ACCESS,&hknew);
+               if (cr != ERROR_SUCCESS) return kl;
+       }
+       else hknew = hksub;
+               
+       cr = RegEnumKey(hknew,index,(LPTSTR)subkeybuf,MAX_PATH_LEN);
+       if (cr == ERROR_SUCCESS) {
+               newkey = new char[strlen(subkeybuf)+1];
+               strcpy(newkey,subkeybuf);
+
+               kl = findAllSubKeys(hknew,0,0,newkey,kl);
+               kl = findAllSubKeys(hkey,hknew,index+1,keyname,kl);
+               
+               return kl;
+
+       }       
+       
+       if (!kl->next) {
+               kl->next = new KEYLIST[1];
+               kl = kl->next;
+               kl->mainKey = hkey;
+               kl->subKey = hknew;
+               kl->keyname = keyname;
+               kl->next = 0;
+       }
+
+       return kl;
+}
+
+static LONG deleteRegPath (HKEY mainkey,char *szregpath,char *szdelpath)
+{
+       HKEY            hkey;
+       LONG            cr,rc = -1;
+       KEYLIST         klist;
+       LPKEYLIST       pkl,k;
+       char            *keyname = 0;
+       
+       if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) {
+
+               keyname = new char[strlen(szdelpath)+1];
+               if (!keyname) {
+                       RegCloseKey(hkey);
+                       return rc;
+               }
+               strcpy(keyname,szdelpath);
+               klist.next = 0;
+
+               findAllSubKeys(hkey,0,0,keyname,&klist);
+       
+               if (klist.next) {
+                       pkl = klist.next;
+       
+                       while (pkl) {
+                               RegCloseKey(pkl->subKey);
+                               cr = RegDeleteKey(pkl->mainKey,pkl->keyname);
+                               delete pkl->keyname;
+                               k = pkl;
+                               pkl = pkl->next;
+                               delete k;
+                       }
+                       rc = 0;
+               }
+
+               RegCloseKey(hkey);
+       }
+
+       return rc;
+}
+
diff --git a/src/hostapi/asio/ASIOSDK/common/wxdebug.h b/src/hostapi/asio/ASIOSDK/common/wxdebug.h
new file mode 100644 (file)
index 0000000..9273eeb
--- /dev/null
@@ -0,0 +1,326 @@
+//==========================================================================;
+//
+//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+//  PURPOSE.
+//
+//  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
+//
+//--------------------------------------------------------------------------;
+
+// Debugging facilities, January 1995
+
+#ifndef __WXDEBUG__
+#define __WXDEBUG__
+
+// Avoid conflict with MFC
+#undef ASSERT
+
+// This library provides fairly straight forward debugging functionality, this
+// is split into two main sections. The first is assertion handling, there are
+// three types of assertions provided here. The most commonly used one is the
+// ASSERT(condition) macro which will pop up a message box including the file
+// and line number if the condition evaluates to FALSE. Then there is the
+// EXECUTE_ASSERT macro which is the same as ASSERT except the condition will
+// still be executed in NON debug builds. The final type of assertion is the
+// KASSERT macro which is more suitable for pure (perhaps kernel) filters as
+// the condition is printed onto the debugger rather than in a message box.
+//
+// The other part of the debug module facilties is general purpose logging.
+// This is accessed by calling DbgLog(). The function takes a type and level
+// field which define the type of informational string you are presenting and
+// it's relative importance. The type field can be a combination (one or more)
+// of LOG_TIMING, LOG_TRACE, LOG_MEMORY, LOG_LOCKING and LOG_ERROR. The level
+// is a DWORD value where zero defines highest important. Use of zero as the
+// debug logging level is to be encouraged ONLY for major errors or events as
+// they will ALWAYS be displayed on the debugger. Other debug output has it's
+// level matched against the current debug output level stored in the registry
+// for this module and if less than the current setting it will be displayed.
+//
+// Each module or executable has it's own debug output level for each of the
+// five types. These are read in when the DbgInitialise function is called
+// for DLLs linking to STRMBASE.LIB this is done automatically when the DLL
+// is loaded, executables must call it explicitely with the module instance
+// handle given to them through the WINMAIN entry point. An executable must
+// also call DbgTerminate when they have finished to clean up the resources
+// the debug library uses, once again this is done automatically for DLLs
+
+// These are the five different categories of logging information
+
+enum {  LOG_TIMING = 0x01,    // Timing and performance measurements
+        LOG_TRACE = 0x02,     // General step point call tracing
+        LOG_MEMORY =  0x04,   // Memory and object allocation/destruction
+        LOG_LOCKING = 0x08,   // Locking/unlocking of critical sections
+        LOG_ERROR = 0x10 };   // Debug error notification
+
+enum {  CDISP_HEX = 0x01,
+        CDISP_DEC = 0x02};
+
+// For each object created derived from CBaseObject (in debug builds) we
+// create a descriptor that holds it's name (statically allocated memory)
+// and a cookie we assign it. We keep a list of all the active objects
+// we have registered so that we can dump a list of remaining objects
+
+typedef struct tag_ObjectDesc {
+    TCHAR *m_pName;
+    DWORD m_dwCookie;
+    tag_ObjectDesc *m_pNext;
+} ObjectDesc;
+
+#define DLLIMPORT __declspec(dllimport)
+#define DLLEXPORT __declspec(dllexport)
+
+#ifdef DEBUG
+
+    #define NAME(x) TEXT(x)
+
+    // These are used internally by the debug library (PRIVATE)
+
+    void DbgInitKeyLevels(HKEY hKey);
+    void DbgInitGlobalSettings();
+    void DbgInitModuleSettings();
+    void DbgInitModuleName();
+    DWORD DbgRegisterObjectCreation(TCHAR *pObjectName);
+    BOOL DbgRegisterObjectDestruction(DWORD dwCookie);
+
+    // These are the PUBLIC entry points
+
+    BOOL DbgCheckModuleLevel(DWORD Type,DWORD Level);
+    void DbgSetModuleLevel(DWORD Type,DWORD Level);
+
+    // Initialise the library with the module handle
+
+    void DbgInitialise(HINSTANCE hInst);
+    void DbgTerminate();
+
+    void DbgDumpObjectRegister();
+
+    // Display error and logging to the user
+
+    void DbgAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
+    void DbgBreakPoint(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
+    void DbgKernelAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
+    void DbgLogInfo(DWORD Type,DWORD Level,const TCHAR *pFormat,...);
+    void DbgOutString(LPCTSTR psz);
+
+    //  Debug infinite wait stuff
+    DWORD DbgWaitForSingleObject(HANDLE h);
+    DWORD DbgWaitForMultipleObjects(DWORD nCount,
+                                    CONST HANDLE *lpHandles,
+                                    BOOL bWaitAll);
+    void DbgSetWaitTimeout(DWORD dwTimeout);
+
+#ifdef __strmif_h__
+    void DisplayType(LPSTR label, const AM_MEDIA_TYPE *pmtIn);
+#endif
+
+    #define KASSERT(_x_) if (!(_x_))         \
+        DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
+
+    //  Break on the debugger without putting up a message box
+    //  message goes to debugger instead
+
+    #define KDbgBreak(_x_)                   \
+        DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
+
+    #define ASSERT(_x_) if (!(_x_))         \
+        DbgAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
+
+    //  Put up a message box informing the user of a halt
+    //  condition in the program
+
+    #define DbgBreak(_x_)                   \
+        DbgBreakPoint(TEXT(#_x_),TEXT(__FILE__),__LINE__)
+
+    #define EXECUTE_ASSERT(_x_) ASSERT(_x_)
+    #define DbgLog(_x_) DbgLogInfo _x_
+
+    // MFC style trace macros
+
+    #define NOTE(_x_)             DbgLog((LOG_TRACE,5,TEXT(_x_)));
+    #define NOTE1(_x_,a)          DbgLog((LOG_TRACE,5,TEXT(_x_),a));
+    #define NOTE2(_x_,a,b)        DbgLog((LOG_TRACE,5,TEXT(_x_),a,b));
+    #define NOTE3(_x_,a,b,c)      DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c));
+    #define NOTE4(_x_,a,b,c,d)    DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d));
+    #define NOTE5(_x_,a,b,c,d,e)  DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d,e));
+
+#else
+
+    // Retail builds make public debug functions inert  - WARNING the source
+    // files do not define or build any of the entry points in debug builds
+    // (public entry points compile to nothing) so if you go trying to call
+    // any of the private entry points in your source they won't compile
+
+    #define NAME(_x_) NULL
+
+    #define DbgInitialise(hInst)
+    #define DbgTerminate()
+    #define DbgLog(_x_)
+    #define DbgOutString(psz)
+
+    #define DbgRegisterObjectCreation(pObjectName)
+    #define DbgRegisterObjectDestruction(dwCookie)
+    #define DbgDumpObjectRegister()
+
+    #define DbgCheckModuleLevel(Type,Level)
+    #define DbgSetModuleLevel(Type,Level)
+
+    #define DbgWaitForSingleObject(h)  WaitForSingleObject(h, INFINITE)
+    #define DbgWaitForMultipleObjects(nCount, lpHandles, bWaitAll)     \
+               WaitForMultipleObjects(nCount, lpHandles, bWaitAll, INFINITE)
+    #define DbgSetWaitTimeout(dwTimeout)
+
+    #define KDbgBreak(_x_)
+    #define DbgBreak(_x_)
+
+    #define KASSERT(_x_)
+    #define ASSERT(_x_)
+    #define EXECUTE_ASSERT(_x_) _x_
+
+    // MFC style trace macros
+
+    #define NOTE(_x_)
+    #define NOTE1(_x_,a)
+    #define NOTE2(_x_,a,b)
+    #define NOTE3(_x_,a,b,c)
+    #define NOTE4(_x_,a,b,c,d)
+    #define NOTE5(_x_,a,b,c,d,e)
+
+    #define DisplayType(label, pmtIn)
+
+#endif
+
+
+// Checks a pointer which should be non NULL - can be used as follows.
+
+#define CheckPointer(p,ret) {if((p)==NULL) return (ret);}
+
+//   HRESULT Foo(VOID *pBar)
+//   {
+//       CheckPointer(pBar,E_INVALIDARG)
+//   }
+//
+//   Or if the function returns a boolean
+//
+//   BOOL Foo(VOID *pBar)
+//   {
+//       CheckPointer(pBar,FALSE)
+//   }
+
+// These validate pointers when symbol VFWROBUST is defined
+// This will normally be defined in debug not retail builds
+
+#ifdef DEBUG
+    #define VFWROBUST
+#endif
+
+#ifdef VFWROBUST
+
+    #define ValidateReadPtr(p,cb) \
+        {if(IsBadReadPtr((PVOID)p,cb) == TRUE) \
+            DbgBreak("Invalid read pointer");}
+
+    #define ValidateWritePtr(p,cb) \
+        {if(IsBadWritePtr((PVOID)p,cb) == TRUE) \
+            DbgBreak("Invalid write pointer");}
+
+    #define ValidateReadWritePtr(p,cb) \
+        {ValidateReadPtr(p,cb) ValidateWritePtr(p,cb)}
+
+    #define ValidateStringPtr(p) \
+        {if(IsBadStringPtr((LPCTSTR)p,INFINITE) == TRUE) \
+            DbgBreak("Invalid string pointer");}
+
+    #define ValidateStringPtrA(p) \
+        {if(IsBadStringPtrA((LPCSTR)p,INFINITE) == TRUE) \
+            DbgBreak("Invalid ANSII string pointer");}
+
+    #define ValidateStringPtrW(p) \
+        {if(IsBadStringPtrW((LPCWSTR)p,INFINITE) == TRUE) \
+            DbgBreak("Invalid UNICODE string pointer");}
+
+#else
+    #define ValidateReadPtr(p,cb)
+    #define ValidateWritePtr(p,cb)
+    #define ValidateReadWritePtr(p,cb)
+    #define ValidateStringPtr(p)
+    #define ValidateStringPtrA(p)
+    #define ValidateStringPtrW(p)
+#endif
+
+
+#ifdef _OBJBASE_H_
+
+    //  Outputting GUID names.  If you want to include the name
+    //  associated with a GUID (eg CLSID_...) then
+    //
+    //      GuidNames[yourGUID]
+    //
+    //  Returns the name defined in uuids.h as a string
+
+    typedef struct {
+        TCHAR   *szName;
+        GUID    guid;
+    } GUID_STRING_ENTRY;
+
+    class CGuidNameList {
+    public:
+        TCHAR *operator [] (const GUID& guid);
+    };
+
+    extern CGuidNameList GuidNames;
+
+#endif
+
+
+//  REMIND macro - generates warning as reminder to complete coding
+//  (eg) usage:
+//
+//  #pragma message (REMIND("Add automation support"))
+
+
+#define QUOTE(x) #x
+#define QQUOTE(y) QUOTE(y)
+#define REMIND(str) __FILE__ "(" QQUOTE(__LINE__) ") :  " str
+
+
+//  Hack to display objects in a useful format
+//
+//  eg If you want to display a LONGLONG ll in a debug string do (eg)
+//
+//  DbgLog((LOG_TRACE, n, TEXT("Value is %s"), (LPCTSTR)CDisp(ll, CDISP_HEX)));
+
+
+class CDispBasic
+{
+public:
+    CDispBasic() { m_pString = m_String; };
+    ~CDispBasic();
+protected:
+    PTCHAR m_pString;  // normally points to m_String... unless too much data
+    TCHAR m_String[50];
+};
+class CDisp : public CDispBasic
+{
+public:
+    CDisp(LONGLONG ll, int Format = CDISP_HEX); // Display a LONGLONG in CDISP_HEX or CDISP_DEC form
+    CDisp(REFCLSID clsid);      // Display a GUID
+    CDisp(double d);            // Display a floating point number
+#ifdef __strmif_h__
+#ifdef __STREAMS__
+    CDisp(CRefTime t);          // Display a Reference Time
+#endif
+    CDisp(IPin *pPin);          // Display a pin as {filter clsid}(pin name)
+#endif // __strmif_h__
+    ~CDisp();
+
+    //  Implement cast to (LPCTSTR) as parameter to logger
+    operator LPCTSTR()
+    {
+        return (LPCTSTR)m_pString;
+    };
+};
+
+#endif // __WXDEBUG__
+
diff --git a/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample.def b/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample.def
new file mode 100644 (file)
index 0000000..963b98c
--- /dev/null
@@ -0,0 +1,9 @@
+LIBRARY                        ASIOSample
+DESCRIPTION            'ASIO Sample Driver'
+PROTMODE
+EXPORTS        
+                               DllMain
+                               DllGetClassObject
+                               DllCanUnloadNow
+                               DllRegisterServer
+                               DllUnregisterServer
diff --git a/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample.txt b/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample.txt
new file mode 100644 (file)
index 0000000..8f28b9b
--- /dev/null
@@ -0,0 +1,23 @@
+Asiosample
+
+This sample driver illustrates the implementation of an ASIO driver.
+
+
+
+Windows notes:
+
+For Windows a COM implementation is provided. The final driver can be
+installed in the system by dragging the asiosample.dll onto the
+regsvr32.exe in the windows\system directory.
+
+It is normal that the LNK4104 warning is issued for the following 4
+exported symbols:
+
+DllGetClassObject
+DllCanUnloadNow
+DllRegisterServer
+DllUnregisterServer
+
+
+Macintosh notes:
+The supplied project is created with CodeWarrior Pro 5.
diff --git a/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample/asiosample.dsp b/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample/asiosample.dsp
new file mode 100644 (file)
index 0000000..f0a0b01
--- /dev/null
@@ -0,0 +1,151 @@
+# Microsoft Developer Studio Project File - Name="asiosample" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=asiosample - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "asiosample.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "asiosample.mak" CFG="asiosample - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "asiosample - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "asiosample - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "asiosample - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\Common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  winmm.lib /nologo /subsystem:windows /dll /machine:I386
+
+!ELSEIF  "$(CFG)" == "asiosample - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
+# ADD CPP /nologo /G5 /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\Common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "asiosample - Win32 Release"
+# Name "asiosample - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\asiosample.def
+# End Source File
+# Begin Source File
+
+SOURCE=..\asiosmpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\common\combase.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\common\dllentry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\common\register.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\wintimer.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\..\common\asio.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\Asiodrvr.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\asiosmpl.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\common\asiosys.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\common\combase.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\common\iasiodrv.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample/asiosample.vcproj b/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosample/asiosample.vcproj
new file mode 100644 (file)
index 0000000..9f49594
--- /dev/null
@@ -0,0 +1,629 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8.00"
+       Name="asiosample"
+       ProjectGUID="{D514DF49-CE45-4F09-9BAD-8FDA4BEF4DE3}"
+       RootNamespace="asiosample"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+               <Platform
+                       Name="x64"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="2"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               PreprocessorDefinitions="_DEBUG"
+                               MkTypLibCompatible="true"
+                               SuppressStartupBanner="true"
+                               TargetEnvironment="1"
+                               TypeLibraryName=".\Debug/asiosample.tlb"
+                               HeaderFileName=""
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="..\..\..\Common"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="1"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="_DEBUG"
+                               Culture="1033"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
+                               OutputFile="$(PlatformName)\$(ConfigurationName)\asiosample.dll"
+                               LinkIncremental="2"
+                               SuppressStartupBanner="true"
+                               ModuleDefinitionFile="..\asiosample.def"
+                               GenerateDebugInformation="true"
+                               SubSystem="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCWebDeploymentTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|x64"
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="2"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               PreprocessorDefinitions="_DEBUG"
+                               MkTypLibCompatible="true"
+                               SuppressStartupBanner="true"
+                               TargetEnvironment="3"
+                               TypeLibraryName=".\Debug/asiosample.tlb"
+                               HeaderFileName=""
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="..\..\..\Common"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="1"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="_DEBUG"
+                               Culture="1033"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
+                               OutputFile="$(PlatformName)\$(ConfigurationName)\asiosample.dll"
+                               LinkIncremental="2"
+                               SuppressStartupBanner="true"
+                               ModuleDefinitionFile="..\asiosample.def"
+                               GenerateDebugInformation="true"
+                               SubSystem="2"
+                               TargetMachine="17"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCWebDeploymentTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="2"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               PreprocessorDefinitions="NDEBUG"
+                               MkTypLibCompatible="true"
+                               SuppressStartupBanner="true"
+                               TargetEnvironment="1"
+                               TypeLibraryName=".\Release/asiosample.tlb"
+                               HeaderFileName=""
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               InlineFunctionExpansion="1"
+                               AdditionalIncludeDirectories="..\..\..\Common"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE"
+                               StringPooling="true"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="NDEBUG"
+                               Culture="1033"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
+                               OutputFile="$(PlatformName)\$(ConfigurationName)\asiosample.dll"
+                               LinkIncremental="1"
+                               SuppressStartupBanner="true"
+                               ModuleDefinitionFile="..\asiosample.def"
+                               SubSystem="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCWebDeploymentTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|x64"
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="2"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               PreprocessorDefinitions="NDEBUG"
+                               MkTypLibCompatible="true"
+                               SuppressStartupBanner="true"
+                               TargetEnvironment="3"
+                               TypeLibraryName=".\Release/asiosample.tlb"
+                               HeaderFileName=""
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               InlineFunctionExpansion="1"
+                               AdditionalIncludeDirectories="..\..\..\Common"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE"
+                               StringPooling="true"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="NDEBUG"
+                               Culture="1033"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
+                               OutputFile="$(PlatformName)\$(ConfigurationName)\asiosample.dll"
+                               LinkIncremental="1"
+                               SuppressStartupBanner="true"
+                               ModuleDefinitionFile="..\asiosample.def"
+                               SubSystem="2"
+                               TargetMachine="17"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCWebDeploymentTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+                       >
+                       <File
+                               RelativePath="..\asiosample.def"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\asiosmpl.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\..\..\common\combase.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\..\..\common\dllentry.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\..\..\common\register.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\wintimer.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl"
+                       >
+                       <File
+                               RelativePath="..\..\..\common\asio.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\Common\Asiodrvr.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\asiosmpl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\common\asiosys.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\common\combase.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\common\iasiodrv.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosmpl.cpp b/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosmpl.cpp
new file mode 100644 (file)
index 0000000..ca72be7
--- /dev/null
@@ -0,0 +1,660 @@
+/*
+       Steinberg Audio Stream I/O API
+       (c) 1996, Steinberg Soft- und Hardware GmbH
+       charlie (May 1996)
+
+       asiosmpl.cpp
+       
+       sample implementation of asio. can be set to simulate input with some
+       stupid oscillators.
+       this driver doesn't output sound at all...
+       timing is done via the extended time manager on the mac, and
+       a simple thread on pc.
+       you may test various configurations by changing the kNumInputs/Outputs,
+       and kBlockFrames. note that when using wave generation, as i/o is not optimized
+       at all, it moves quite a bit of memory, too many i/o channels may make it
+       pretty slow.
+
+       if you use this file as a template, make sure to resolve places where the
+       search string !!! can be found...
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "asiosmpl.h"
+//#include "virtape.h"
+
+//------------------------------------------------------------------------------------------
+
+// extern
+void getNanoSeconds(ASIOTimeStamp *time);
+
+// local
+
+double AsioSamples2double (ASIOSamples* samples);
+
+static const double twoRaisedTo32 = 4294967296.;
+static const double twoRaisedTo32Reciprocal = 1. / twoRaisedTo32;
+
+//------------------------------------------------------------------------------------------
+// on windows, we do the COM stuff.
+
+#if WINDOWS
+#include "windows.h"
+#include "mmsystem.h"
+
+// class id. !!! NOTE: !!! you will obviously have to create your own class id!
+// {188135E1-D565-11d2-854F-00A0C99F5D19}
+CLSID IID_ASIO_DRIVER = { 0x188135e1, 0xd565, 0x11d2, { 0x85, 0x4f, 0x0, 0xa0, 0xc9, 0x9f, 0x5d, 0x19 } };
+
+CFactoryTemplate g_Templates[1] = {
+    {L"ASIOSAMPLE", &IID_ASIO_DRIVER, AsioSample::CreateInstance} 
+};
+int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
+
+CUnknown* AsioSample::CreateInstance (LPUNKNOWN pUnk, HRESULT *phr)
+{
+       return (CUnknown*)new AsioSample (pUnk,phr);
+};
+
+STDMETHODIMP AsioSample::NonDelegatingQueryInterface (REFIID riid, void ** ppv)
+{
+       if (riid == IID_ASIO_DRIVER)
+       {
+               return GetInterface (this, ppv);
+       }
+       return CUnknown::NonDelegatingQueryInterface (riid, ppv);
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//             Register ASIO Driver
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+extern LONG RegisterAsioDriver (CLSID,char *,char *,char *,char *);
+extern LONG UnregisterAsioDriver (CLSID,char *,char *);
+
+//
+// Server registration, called on REGSVR32.EXE "the dllname.dll"
+//
+HRESULT _stdcall DllRegisterServer()
+{
+       LONG    rc;
+       char    errstr[128];
+
+       rc = RegisterAsioDriver (IID_ASIO_DRIVER,"ASIOSample.dll","ASIO Sample Driver","ASIO Sample","Apartment");
+
+       if (rc) {
+               memset(errstr,0,128);
+               sprintf(errstr,"Register Server failed ! (%d)",rc);
+               MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"ASIO sample Driver",MB_OK);
+               return -1;
+       }
+
+       return S_OK;
+}
+
+//
+// Server unregistration
+//
+HRESULT _stdcall DllUnregisterServer()
+{
+       LONG    rc;
+       char    errstr[128];
+
+       rc = UnregisterAsioDriver (IID_ASIO_DRIVER,"ASIOSample.dll","ASIO Sample Driver");
+
+       if (rc) {
+               memset(errstr,0,128);
+               sprintf(errstr,"Unregister Server failed ! (%d)",rc);
+               MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"ASIO Korg1212 I/O Driver",MB_OK);
+               return -1;
+       }
+
+       return S_OK;
+}
+
+//------------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------------
+AsioSample::AsioSample (LPUNKNOWN pUnk, HRESULT *phr)
+       : CUnknown("ASIOSAMPLE", pUnk, phr)
+
+//------------------------------------------------------------------------------------------
+
+#else
+
+// when not on windows, we derive from AsioDriver
+AsioSample::AsioSample () : AsioDriver ()
+
+#endif
+{
+       long i;
+
+       blockFrames = kBlockFrames;
+       inputLatency = blockFrames;             // typically
+       outputLatency = blockFrames * 2;
+       // typically blockFrames * 2; try to get 1 by offering direct buffer
+       // access, and using asioPostOutput for lower latency
+       samplePosition = 0;
+       sampleRate = 44100.;
+       milliSeconds = (long)((double)(kBlockFrames * 1000) / sampleRate);
+       active = false;
+       started = false;
+       timeInfoMode = false;
+       tcRead = false;
+       for (i = 0; i < kNumInputs; i++)
+       {
+               inputBuffers[i] = 0;
+               inMap[i] = 0;
+       }
+#if TESTWAVES
+       sawTooth = sineWave = 0;
+#endif
+       for (i = 0; i < kNumOutputs; i++)
+       {
+               outputBuffers[i] = 0;
+               outMap[i] = 0;
+       }
+       callbacks = 0;
+       activeInputs = activeOutputs = 0;
+       toggle = 0;
+}
+
+//------------------------------------------------------------------------------------------
+AsioSample::~AsioSample ()
+{
+       stop ();
+       outputClose ();
+       inputClose ();
+       disposeBuffers ();
+}
+
+//------------------------------------------------------------------------------------------
+void AsioSample::getDriverName (char *name)
+{
+       strcpy (name, "Sample ASIO");
+}
+
+//------------------------------------------------------------------------------------------
+long AsioSample::getDriverVersion ()
+{
+       return 0x00000001L;
+}
+
+//------------------------------------------------------------------------------------------
+void AsioSample::getErrorMessage (char *string)
+{
+       strcpy (string, errorMessage);
+}
+
+//------------------------------------------------------------------------------------------
+ASIOBool AsioSample::init (void* sysRef)
+{
+       sysRef = sysRef;
+       if (active)
+               return true;
+       strcpy (errorMessage, "ASIO Driver open Failure!");
+       if (inputOpen ())
+       {
+               if (outputOpen ())
+               {
+                       active = true;
+                       return true;
+               }
+       }
+       timerOff ();            // de-activate 'hardware'
+
+       outputClose ();
+       inputClose ();
+       return false;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::start ()
+{
+       if (callbacks)
+       {
+               started = false;
+               samplePosition = 0;
+               theSystemTime.lo = theSystemTime.hi = 0;
+               toggle = 0;
+
+               timerOn ();                     // activate 'hardware'
+               started = true;
+
+               return ASE_OK;
+       }
+       return ASE_NotPresent;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::stop ()
+{
+       started = false;
+       timerOff ();            // de-activate 'hardware'
+       return ASE_OK;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::getChannels (long *numInputChannels, long *numOutputChannels)
+{
+       *numInputChannels = kNumInputs;
+       *numOutputChannels = kNumOutputs;
+       return ASE_OK;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::getLatencies (long *_inputLatency, long *_outputLatency)
+{
+       *_inputLatency = inputLatency;
+       *_outputLatency = outputLatency;
+       return ASE_OK;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::getBufferSize (long *minSize, long *maxSize,
+       long *preferredSize, long *granularity)
+{
+       *minSize = *maxSize = *preferredSize = blockFrames;             // allow this size only
+       *granularity = 0;
+       return ASE_OK;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::canSampleRate (ASIOSampleRate sampleRate)
+{
+       if (sampleRate == 44100. || sampleRate == 48000.)               // allow these rates only
+               return ASE_OK;
+       return ASE_NoClock;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::getSampleRate (ASIOSampleRate *sampleRate)
+{
+       *sampleRate = this->sampleRate;
+       return ASE_OK;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::setSampleRate (ASIOSampleRate sampleRate)
+{
+       if (sampleRate != 44100. && sampleRate != 48000.)
+               return ASE_NoClock;
+       if (sampleRate != this->sampleRate)
+       {
+               this->sampleRate = sampleRate;
+               asioTime.timeInfo.sampleRate = sampleRate;
+               asioTime.timeInfo.flags |= kSampleRateChanged;
+               milliSeconds = (long)((double)(kBlockFrames * 1000) / this->sampleRate);
+               if (callbacks && callbacks->sampleRateDidChange)
+                       callbacks->sampleRateDidChange (this->sampleRate);
+       }
+       return ASE_OK;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::getClockSources (ASIOClockSource *clocks, long *numSources)
+{
+       // internal
+       clocks->index = 0;
+       clocks->associatedChannel = -1;
+       clocks->associatedGroup = -1;
+       clocks->isCurrentSource = ASIOTrue;
+       strcpy(clocks->name, "Internal");
+       *numSources = 1;
+       return ASE_OK;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::setClockSource (long index)
+{
+       if (!index)
+       {
+               asioTime.timeInfo.flags |= kClockSourceChanged;
+               return ASE_OK;
+       }
+       return ASE_NotPresent;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::getSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp)
+{
+       tStamp->lo = theSystemTime.lo;
+       tStamp->hi = theSystemTime.hi;
+       if (samplePosition >= twoRaisedTo32)
+       {
+               sPos->hi = (unsigned long)(samplePosition * twoRaisedTo32Reciprocal);
+               sPos->lo = (unsigned long)(samplePosition - (sPos->hi * twoRaisedTo32));
+       }
+       else
+       {
+               sPos->hi = 0;
+               sPos->lo = (unsigned long)samplePosition;
+       }
+       return ASE_OK;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::getChannelInfo (ASIOChannelInfo *info)
+{
+       if (info->channel < 0 || (info->isInput ? info->channel >= kNumInputs : info->channel >= kNumOutputs))
+               return ASE_InvalidParameter;
+#if WINDOWS
+       info->type = ASIOSTInt16LSB;
+#else
+       info->type = ASIOSTInt16MSB;
+#endif
+       info->channelGroup = 0;
+       info->isActive = ASIOFalse;
+       long i;
+       if (info->isInput)
+       {
+               for (i = 0; i < activeInputs; i++)
+               {
+                       if (inMap[i] == info->channel)
+                       {
+                               info->isActive = ASIOTrue;
+                               break;
+                       }
+               }
+       }
+       else
+       {
+               for (i = 0; i < activeOutputs; i++)
+               {
+                       if (outMap[i] == info->channel)
+                       {
+                               info->isActive = ASIOTrue;
+                               break;
+                       }
+               }
+       }
+       strcpy(info->name, "Sample ");
+       return ASE_OK;
+}
+
+//------------------------------------------------------------------------------------------
+ASIOError AsioSample::createBuffers (ASIOBufferInfo *bufferInfos, long numChannels,
+       long bufferSize, ASIOCallbacks *callbacks)
+{
+       ASIOBufferInfo *info = bufferInfos;
+       long i;
+       bool notEnoughMem = false;
+
+       activeInputs = 0;
+       activeOutputs = 0;
+       blockFrames = bufferSize;
+       for (i = 0; i < numChannels; i++, info++)
+       {
+               if (info->isInput)
+               {
+                       if (info->channelNum < 0 || info->channelNum >= kNumInputs)
+                               goto error;
+                       inMap[activeInputs] = info->channelNum;
+                       inputBuffers[activeInputs] = new short[blockFrames * 2];        // double buffer
+                       if (inputBuffers[activeInputs])
+                       {
+                               info->buffers[0] = inputBuffers[activeInputs];
+                               info->buffers[1] = inputBuffers[activeInputs] + blockFrames;
+                       }
+                       else
+                       {
+                               info->buffers[0] = info->buffers[1] = 0;
+                               notEnoughMem = true;
+                       }
+                       activeInputs++;
+                       if (activeInputs > kNumInputs)
+                       {
+error:
+                               disposeBuffers();
+                               return ASE_InvalidParameter;
+                       }
+               }
+               else    // output                       
+               {
+                       if (info->channelNum < 0 || info->channelNum >= kNumOutputs)
+                               goto error;
+                       outMap[activeOutputs] = info->channelNum;
+                       outputBuffers[activeOutputs] = new short[blockFrames * 2];      // double buffer
+                       if (outputBuffers[activeOutputs])
+                       {
+                               info->buffers[0] = outputBuffers[activeOutputs];
+                               info->buffers[1] = outputBuffers[activeOutputs] + blockFrames;
+                       }
+                       else
+                       {
+                               info->buffers[0] = info->buffers[1] = 0;
+                               notEnoughMem = true;
+                       }
+                       activeOutputs++;
+                       if (activeOutputs > kNumOutputs)
+                       {
+                               activeOutputs--;
+                               disposeBuffers();
+                               return ASE_InvalidParameter;
+                       }
+               }
+       }               
+       if (notEnoughMem)
+       {
+               disposeBuffers();
+               return ASE_NoMemory;
+       }
+
+       this->callbacks = callbacks;
+       if (callbacks->asioMessage (kAsioSupportsTimeInfo, 0, 0, 0))
+       {
+               timeInfoMode = true;
+               asioTime.timeInfo.speed = 1.;
+               asioTime.timeInfo.systemTime.hi = asioTime.timeInfo.systemTime.lo = 0;
+               asioTime.timeInfo.samplePosition.hi = asioTime.timeInfo.samplePosition.lo = 0;
+               asioTime.timeInfo.sampleRate = sampleRate;
+               asioTime.timeInfo.flags = kSystemTimeValid | kSamplePositionValid | kSampleRateValid;
+
+               asioTime.timeCode.speed = 1.;
+               asioTime.timeCode.timeCodeSamples.lo = asioTime.timeCode.timeCodeSamples.hi = 0;
+               asioTime.timeCode.flags = kTcValid | kTcRunning ;
+       }
+       else
+               timeInfoMode = false;   
+       return ASE_OK;
+}
+
+//---------------------------------------------------------------------------------------------
+ASIOError AsioSample::disposeBuffers()
+{
+       long i;
+       
+       callbacks = 0;
+       stop();
+       for (i = 0; i < activeInputs; i++)
+               delete inputBuffers[i];
+       activeInputs = 0;
+       for (i = 0; i < activeOutputs; i++)
+               delete outputBuffers[i];
+       activeOutputs = 0;
+       return ASE_OK;
+}
+
+//---------------------------------------------------------------------------------------------
+ASIOError AsioSample::controlPanel()
+{
+       return ASE_NotPresent;
+}
+
+//---------------------------------------------------------------------------------------------
+ASIOError AsioSample::future (long selector, void* opt)        // !!! check properties 
+{
+       ASIOTransportParameters* tp = (ASIOTransportParameters*)opt;
+       switch (selector)
+       {
+               case kAsioEnableTimeCodeRead:   tcRead = true;  return ASE_SUCCESS;
+               case kAsioDisableTimeCodeRead:  tcRead = false; return ASE_SUCCESS;
+               case kAsioSetInputMonitor:              return ASE_SUCCESS;     // for testing!!!
+               case kAsioCanInputMonitor:              return ASE_SUCCESS;     // for testing!!!
+               case kAsioCanTimeInfo:                  return ASE_SUCCESS;
+               case kAsioCanTimeCode:                  return ASE_SUCCESS;
+       }
+       return ASE_NotPresent;
+}
+
+//--------------------------------------------------------------------------------------------------------
+// private methods
+//--------------------------------------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------------------------------------
+// input
+//--------------------------------------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------------------------
+bool AsioSample::inputOpen ()
+{
+#if TESTWAVES
+       sineWave = new short[blockFrames];
+       if (!sineWave)
+       {
+               strcpy (errorMessage, "ASIO Sample Driver: Out of Memory!");
+               return false;
+       }
+       makeSine (sineWave);
+
+       sawTooth = new short[blockFrames];
+       if (!sawTooth)
+       {
+               strcpy(errorMessage, "ASIO Sample Driver: Out of Memory!");
+               return false;
+       }
+       makeSaw(sawTooth);
+#endif
+       return true;
+}
+
+#if TESTWAVES
+
+#include <math.h>
+
+const double pi = 0.3141592654;
+
+//---------------------------------------------------------------------------------------------
+void AsioSample::makeSine (short *wave)
+{
+       double frames = (double)blockFrames;
+       double i, f = (pi * 2.) / frames;
+
+       for (i = 0; i < frames; i++)
+               *wave++ = (short)((double)0x7fff * sin(f * i));
+}
+
+//---------------------------------------------------------------------------------------------
+void AsioSample::makeSaw(short *wave)
+{
+       double frames = (double)blockFrames;
+       double i, f = 2. / frames;
+
+       for (i = 0; i < frames; i++)
+               *wave++ = (short)((double)0x7fff * (-1. + f * i));
+}
+#endif
+
+//---------------------------------------------------------------------------------------------
+void AsioSample::inputClose ()
+{
+#if TESTWAVES
+       if (sineWave)
+               delete sineWave;
+       sineWave = 0;
+       if (sawTooth)
+               delete sawTooth;
+       sawTooth = 0;
+#endif
+}
+
+//---------------------------------------------------------------------------------------------
+void AsioSample::input()
+{
+#if TESTWAVES
+       long i;
+       short *in = 0;
+
+       for (i = 0; i < activeInputs; i++)
+       {
+               in = inputBuffers[i];
+               if (in)
+               {
+                       if (toggle)
+                               in += blockFrames;
+                       if ((i & 1) && sawTooth)
+                               memcpy(in, sawTooth, (unsigned long)(blockFrames * 2));
+                       else if (sineWave)
+                               memcpy(in, sineWave, (unsigned long)(blockFrames * 2));
+               }
+       }
+#endif
+}
+
+//------------------------------------------------------------------------------------------------------------------
+// output
+//------------------------------------------------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------------------------
+bool AsioSample::outputOpen()
+{
+       return true;
+}
+
+//---------------------------------------------------------------------------------------------
+void AsioSample::outputClose ()
+{
+}
+
+//---------------------------------------------------------------------------------------------
+void AsioSample::output ()
+{
+}
+
+//---------------------------------------------------------------------------------------------
+void AsioSample::bufferSwitch ()
+{
+       if (started && callbacks)
+       {
+               getNanoSeconds(&theSystemTime);                 // latch system time
+               input();
+               output();
+               samplePosition += blockFrames;
+               if (timeInfoMode)
+                       bufferSwitchX ();
+               else
+                       callbacks->bufferSwitch (toggle, ASIOFalse);
+               toggle = toggle ? 0 : 1;
+       }
+}
+
+//---------------------------------------------------------------------------------------------
+// asio2 buffer switch
+void AsioSample::bufferSwitchX ()
+{
+       getSamplePosition (&asioTime.timeInfo.samplePosition, &asioTime.timeInfo.systemTime);
+       long offset = toggle ? blockFrames : 0;
+       if (tcRead)
+       {       // Create a fake time code, which is 10 minutes ahead of the card's sample position
+               // Please note that for simplicity here time code will wrap after 32 bit are reached
+               asioTime.timeCode.timeCodeSamples.lo = asioTime.timeInfo.samplePosition.lo + 600.0 * sampleRate;
+               asioTime.timeCode.timeCodeSamples.hi = 0;
+       }
+       callbacks->bufferSwitchTimeInfo (&asioTime, toggle, ASIOFalse);
+       asioTime.timeInfo.flags &= ~(kSampleRateChanged | kClockSourceChanged);
+}
+
+//---------------------------------------------------------------------------------------------
+ASIOError AsioSample::outputReady ()
+{
+       return ASE_NotPresent;
+}
+
+//---------------------------------------------------------------------------------------------
+double AsioSamples2double (ASIOSamples* samples)
+{
+       double a = (double)(samples->lo);
+       if (samples->hi)
+               a += (double)(samples->hi) * twoRaisedTo32;
+       return a;
+}
+
diff --git a/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosmpl.h b/src/hostapi/asio/ASIOSDK/driver/asiosample/asiosmpl.h
new file mode 100644 (file)
index 0000000..8316f12
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+       Steinberg Audio Stream I/O API
+       (c) 1999, Steinberg Soft- und Hardware GmbH
+
+       asiosmpl.h
+       
+       test implementation of asio
+*/
+
+#ifndef _asiosmpl_
+#define _asiosmpl_
+
+#include "asiosys.h"
+
+#define TESTWAVES 1
+// when true, will feed the left input (to host) with
+// a sine wave, and the right one with a sawtooth
+
+enum
+{
+       kBlockFrames = 256,
+       kNumInputs = 16,
+       kNumOutputs = 16
+};
+
+#if WINDOWS
+
+#include "rpc.h"
+#include "rpcndr.h"
+#ifndef COM_NO_WINDOWS_H
+#include <windows.h>
+#include "ole2.h"
+#endif
+
+#include "combase.h"
+#include "iasiodrv.h"
+
+class AsioSample : public IASIO, public CUnknown
+{
+public:
+       AsioSample(LPUNKNOWN pUnk, HRESULT *phr);
+       ~AsioSample();
+
+       DECLARE_IUNKNOWN
+    //STDMETHODIMP QueryInterface(REFIID riid, void **ppv) {      \
+    //    return GetOwner()->QueryInterface(riid,ppv);            \
+    //};                                                          \
+    //STDMETHODIMP_(ULONG) AddRef() {                             \
+    //    return GetOwner()->AddRef();                            \
+    //};                                                          \
+    //STDMETHODIMP_(ULONG) Release() {                            \
+    //    return GetOwner()->Release();                           \
+    //};
+
+       // Factory method
+       static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
+       // IUnknown
+       virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject);
+#else
+
+#include "asiodrvr.h"
+
+//---------------------------------------------------------------------------------------------
+class AsioSample : public AsioDriver
+{
+public:
+       AsioSample ();
+       ~AsioSample ();
+#endif
+
+       ASIOBool init (void* sysRef);
+       void getDriverName (char *name);        // max 32 bytes incl. terminating zero
+       long getDriverVersion ();
+       void getErrorMessage (char *string);    // max 128 bytes incl.
+
+       ASIOError start ();
+       ASIOError stop ();
+
+       ASIOError getChannels (long *numInputChannels, long *numOutputChannels);
+       ASIOError getLatencies (long *inputLatency, long *outputLatency);
+       ASIOError getBufferSize (long *minSize, long *maxSize,
+               long *preferredSize, long *granularity);
+
+       ASIOError canSampleRate (ASIOSampleRate sampleRate);
+       ASIOError getSampleRate (ASIOSampleRate *sampleRate);
+       ASIOError setSampleRate (ASIOSampleRate sampleRate);
+       ASIOError getClockSources (ASIOClockSource *clocks, long *numSources);
+       ASIOError setClockSource (long index);
+
+       ASIOError getSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);
+       ASIOError getChannelInfo (ASIOChannelInfo *info);
+
+       ASIOError createBuffers (ASIOBufferInfo *bufferInfos, long numChannels,
+               long bufferSize, ASIOCallbacks *callbacks);
+       ASIOError disposeBuffers ();
+
+       ASIOError controlPanel ();
+       ASIOError future (long selector, void *opt);
+       ASIOError outputReady ();
+
+       void bufferSwitch ();
+       long getMilliSeconds () {return milliSeconds;}
+
+private:
+friend void myTimer();
+
+       bool inputOpen ();
+#if TESTWAVES
+       void makeSine (short *wave);
+       void makeSaw (short *wave);
+#endif
+       void inputClose ();
+       void input ();
+
+       bool outputOpen ();
+       void outputClose ();
+       void output ();
+
+       void timerOn ();
+       void timerOff ();
+       void bufferSwitchX ();
+
+       double samplePosition;
+       double sampleRate;
+       ASIOCallbacks *callbacks;
+       ASIOTime asioTime;
+       ASIOTimeStamp theSystemTime;
+       short *inputBuffers[kNumInputs * 2];
+       short *outputBuffers[kNumOutputs * 2];
+#if TESTWAVES
+       short *sineWave, *sawTooth;
+#endif
+       long inMap[kNumInputs];
+       long outMap[kNumOutputs];
+       long blockFrames;
+       long inputLatency;
+       long outputLatency;
+       long activeInputs;
+       long activeOutputs;
+       long toggle;
+       long milliSeconds;
+       bool active, started;
+       bool timeInfoMode, tcRead;
+       char errorMessage[128];
+};
+
+#endif
+
diff --git a/src/hostapi/asio/ASIOSDK/driver/asiosample/macnanosecs.cpp b/src/hostapi/asio/ASIOSDK/driver/asiosample/macnanosecs.cpp
new file mode 100644 (file)
index 0000000..3a46fb2
--- /dev/null
@@ -0,0 +1,15 @@
+#include "asio.h"
+#include <Timer.h>
+
+void getNanoSeconds(ASIOTimeStamp *time);
+
+static const double twoRaisedTo32 = 4294967296.;
+
+void getNanoSeconds(ASIOTimeStamp *time)
+{
+       UnsignedWide ys;
+       Microseconds(&ys);
+       double r = 1000. * ((double)ys.hi * twoRaisedTo32 + (double)ys.lo);
+       time->hi = (unsigned long)(r / twoRaisedTo32);
+       time->lo = (unsigned long)(r - (double)time->hi * twoRaisedTo32); 
+}
diff --git a/src/hostapi/asio/ASIOSDK/driver/asiosample/mactimer.cpp b/src/hostapi/asio/ASIOSDK/driver/asiosample/mactimer.cpp
new file mode 100644 (file)
index 0000000..1f0008b
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+       Steinberg Audio Stream I/O API
+       (c) 1996, Steinberg Soft- und Hardware GmbH
+       charlie (May 1996)
+
+       asiosmpl.cpp
+       
+       sample implementation of asio.
+       time manager irq
+       **** mac os specific ****
+*/
+
+#include <macheaders.h>
+#include <Timer.h>
+#include <string.h>
+#include "asiosmpl.h"
+
+static TMTask myTmTask;
+static bool tmTaskOn = false;
+static AsioSample *theSound = 0;
+
+void myTimer();
+void myTimer()
+{
+       if(theSound)
+               theSound->bufferSwitch();
+       PrimeTime((QElemPtr)&myTmTask, theSound->milliSeconds);
+}
+
+void AsioSample::timerOn()
+{
+       theSound = this;        // for irq
+       if(!tmTaskOn)
+       {
+               memset(&myTmTask, 0, sizeof(TMTask));
+               myTmTask.tmAddr = NewTimerProc(myTimer);
+               myTmTask.tmWakeUp = 0;
+               tmTaskOn = true;
+               InsXTime((QElemPtr)&myTmTask);
+               PrimeTime((QElemPtr)&myTmTask, theSound->milliSeconds);
+       }
+}
+
+void AsioSample::timerOff()
+{
+       if(tmTaskOn)
+       {
+               RmvTime((QElemPtr)&myTmTask);
+               tmTaskOn = false;
+       }
+       theSound = 0;
+}
diff --git a/src/hostapi/asio/ASIOSDK/driver/asiosample/makesamp.cpp b/src/hostapi/asio/ASIOSDK/driver/asiosample/makesamp.cpp
new file mode 100644 (file)
index 0000000..25a2f41
--- /dev/null
@@ -0,0 +1,6 @@
+#include "asiosmpl.h"
+
+AsioDriver *getDriver()
+{
+       return new AsioSample();
+}
diff --git a/src/hostapi/asio/ASIOSDK/driver/asiosample/wintimer.cpp b/src/hostapi/asio/ASIOSDK/driver/asiosample/wintimer.cpp
new file mode 100644 (file)
index 0000000..c861bb3
--- /dev/null
@@ -0,0 +1,55 @@
+#include <windows.h>
+#include "asiosmpl.h"
+
+static DWORD __stdcall ASIOThread (void *param);
+static HANDLE ASIOThreadHandle = 0;
+static bool done = false;
+const double twoRaisedTo32 = 4294967296.;
+
+AsioSample* theDriver = 0;
+
+//------------------------------------------------------------------------------------------
+void getNanoSeconds (ASIOTimeStamp* ts)
+{
+       double nanoSeconds = (double)((unsigned long)timeGetTime ()) * 1000000.;
+       ts->hi = (unsigned long)(nanoSeconds / twoRaisedTo32);
+       ts->lo = (unsigned long)(nanoSeconds - (ts->hi * twoRaisedTo32));
+}
+
+//------------------------------------------------------------------------------------------
+void AsioSample::timerOn ()
+{
+       theDriver = this;
+       DWORD asioId;
+       done = false;
+       ASIOThreadHandle = CreateThread (0, 0, &ASIOThread, 0, 0, &asioId);
+}
+
+//------------------------------------------------------------------------------------------
+void AsioSample::timerOff ()
+{
+       done = true;
+       if (ASIOThreadHandle)
+               WaitForSingleObject(ASIOThreadHandle, 1000);
+       ASIOThreadHandle = 0;
+}
+
+//------------------------------------------------------------------------------------------
+static DWORD __stdcall ASIOThread (void *param)
+{
+       do
+       {
+               if (theDriver)
+               {
+                       theDriver->bufferSwitch ();
+                       Sleep (theDriver->getMilliSeconds ());
+               }
+               else
+               {
+                       double a = 1000. / 44100.;
+                       Sleep ((long)(a * (double)kBlockFrames));
+
+               }
+       } while (!done);
+       return 0;
+}
diff --git a/src/hostapi/asio/ASIOSDK/host/ASIOConvertSamples.cpp b/src/hostapi/asio/ASIOSDK/host/ASIOConvertSamples.cpp
new file mode 100644 (file)
index 0000000..16e441e
--- /dev/null
@@ -0,0 +1,859 @@
+#include "ginclude.h"
+#include "ASIOConvertSamples.h"
+#include <math.h>
+
+#if MAC
+#define TRUNCATE 0
+
+#elif ASIO_CPU_X86 || ASIO_CPU_SPARC || ASIO_CPU_MIPS
+#define TRUNCATE 1
+#undef MAXFLOAT
+#define MAXFLOAT 0x7fffff00L
+#endif
+
+ASIOConvertSamples::ASIOConvertSamples()
+{
+}
+
+
+//-------------------------------------------------------------------------------------------
+// mono
+
+void ASIOConvertSamples::convertMono8Unsigned(long *source, char *dest, long frames)
+{
+       unsigned char *c = (unsigned char *)source;
+       unsigned char a;
+
+       dest--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = c[3];
+#else
+               a = c[0];
+#endif
+               c += 4;
+               a -= 0x80U;
+               *++dest = a;
+       }
+}
+
+void ASIOConvertSamples::convertMono8(long *source, char *dest, long frames)
+{
+       char *c = (char *)source;
+       char a;
+
+       dest--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = c[3];
+#else
+               a = c[0];
+#endif
+               c += 4;
+               *++dest = a;
+       }
+}
+
+void ASIOConvertSamples::convertMono16(long *source, short *dest, long frames)
+{
+#if ASIO_LITTLE_ENDIAN
+       char* s = (char*)source;
+       char* d = (char*)dest;
+       while(--frames >= 0)
+       {
+               *d++ = s[3];    // dest big endian, msb first
+               *d++ = s[2];
+               s += 4;
+       }
+#else
+       long l;
+
+       source--;
+       dest--;
+       while(--frames >= 0)
+       {
+               l = *++source;
+               *++dest = (short)(l >> 16);
+       }       
+#endif
+}
+
+void ASIOConvertSamples::convertMono24(long *source, char *dest, long frames)
+{
+       // work with chars in order to prevent misalignments
+       char *s = (char *)source;
+       char a, b, c;
+
+       dest--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = s[3];       // msb
+               b = s[2];
+               c = s[1];       // lsb
+#else
+               a = s[0];
+               b = s[1];
+               c = s[2];
+#endif
+               s += 4;
+               *++dest = a;    // big endian, msb first
+               *++dest = b;
+               *++dest = c;
+       }
+}
+
+// small endian
+
+void ASIOConvertSamples::convertMono16SmallEndian(long *source, short *dest, long frames)
+{
+       char *s = (char *)source;
+       char *d = (char *)dest;
+       char a, b;
+
+       d--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = s[3];
+               b = s[2];
+#else
+               a = s[0];
+               b = s[1];
+#endif
+               s += 4;
+               *++d = b;       // dest small endian, lsb first
+               *++d = a;
+       }
+}
+
+void ASIOConvertSamples::convertMono24SmallEndian(long *source, char *dest, long frames)
+{
+       // work with chars in order to prevent misalignments
+       char *s = (char *)source;
+       char a, b, c;
+
+       dest--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = s[3];
+               b = s[2];
+               c = s[1];
+#else
+               a = s[0];
+               b = s[1];
+               c = s[2];
+#endif
+               s += 4;
+               *++dest = c;    // lsb first
+               *++dest = b;
+               *++dest = a;
+       }
+}
+
+
+//-------------------------------------------------------------------------------------------
+// stereo interleaved
+
+void ASIOConvertSamples::convertStereo8InterleavedUnsigned(long *left, long *right, char *dest, long frames)
+{
+       unsigned char *cl = (unsigned char *)left;
+       unsigned char *cr = (unsigned char *)right;
+       unsigned char a, b;
+
+       dest--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = cl[3];
+               b = cr[3];
+#else
+               a = cl[0];
+               b = cr[0];
+#endif
+               cl += 4;
+               cr += 4;
+               a -= 0x80U;
+               b -= 0x80U;
+               *++dest = a;
+               *++dest = b;
+       }       
+}
+
+void ASIOConvertSamples::convertStereo8Interleaved(long *left, long *right, char *dest, long frames)
+{
+       unsigned char *cl = (unsigned char *)left;
+       unsigned char *cr = (unsigned char *)right;
+       unsigned char a, b;
+
+       dest--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = cl[3];
+               b = cr[3];
+#else
+               a = cl[0];
+               b = cr[0];
+#endif
+               cl += 4;
+               cr += 4;
+               *++dest = a;
+               *++dest = b;
+       }       
+}
+
+void ASIOConvertSamples::convertStereo16Interleaved(long *left, long *right, short *dest, long frames)
+{
+#if ASIO_LITTLE_ENDIAN
+       char* sl = (char*)left;
+       char* sr = (char*)right;
+       char* d = (char*)dest;
+       while(--frames >= 0)
+       {
+               *d++ = sl[3];   // msb first
+               *d++ = sl[2];
+               *d++ = sr[3];
+               *d++ = sr[2];
+               sl += 4;
+               sr += 4;
+       }
+#else
+       long l, r;
+
+       left--;
+       right--;
+       dest--;
+       while(--frames >= 0)
+       {
+               l = *++left;
+               r = *++right;
+               *++dest = (short)(l >> 16);
+               *++dest = (short)(r >> 16);
+       }
+#endif 
+}
+
+void ASIOConvertSamples::convertStereo24Interleaved(long *left, long *right, char *dest, long frames)
+{
+       // work with chars in order to prevent misalignments
+       char *sl = (char *)left;
+       char *sr = (char *)right;
+       char al, bl, cl, ar, br, cr;
+
+       dest--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               al = sl[3];
+               bl = sl[2];
+               cl = sl[1];
+               ar = sr[3];
+               br = sr[2];
+               cr = sr[1];
+#else
+               al = sl[0];
+               bl = sl[1];
+               cl = sl[2];
+               ar = sr[0];
+               br = sr[1];
+               cr = sr[2];
+#endif
+               sl += 4;
+               sr += 4;
+               *++dest = al;
+               *++dest = bl;
+               *++dest = cl;
+               *++dest = ar;
+               *++dest = br;
+               *++dest = cr;
+       }
+}
+
+void ASIOConvertSamples::convertStereo16InterleavedSmallEndian(long *left, long *right, short *dest, long frames)
+{
+       char *sl = (char *)left;
+       char *sr = (char *)right;
+       char *d =  (char *)dest;
+       char al, bl, ar, br;
+
+       d--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               al = sl[3];
+               bl = sl[2];
+               ar = sr[3];
+               br = sr[2];
+#else
+               al = sl[0];
+               bl = sl[1];
+               ar = sr[0];
+               br = sr[1];
+#endif
+               sl += 4;
+               sr += 4;
+               *++d = bl;      // lsb first
+               *++d = al;
+               *++d = br;
+               *++d = ar;
+       }
+}
+
+void ASIOConvertSamples::convertStereo24InterleavedSmallEndian(long *left, long *right, char *dest, long frames)
+{
+       // work with chars in order to prevent misalignments
+       char *sl = (char *)left;
+       char *sr = (char *)right;
+       char al, bl, cl, ar, br, cr;
+
+       dest--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               al = sl[3];
+               bl = sl[2];
+               cl = sl[1];
+               ar = sr[3];
+               br = sr[2];
+               cr = sr[1];
+#else
+               al = sl[0];
+               bl = sl[1];
+               cl = sl[2];
+               ar = sr[0];
+               br = sr[1];
+               cr = sr[2];
+#endif
+               sl += 4;
+               sr += 4;
+               *++dest = cl;
+               *++dest = bl;
+               *++dest = al;
+               *++dest = cr;
+               *++dest = br;
+               *++dest = ar;
+       }
+}
+
+
+//-------------------------------------------------------------------------------------------
+// stereo split
+
+void ASIOConvertSamples::convertStereo8Unsigned(long *left, long *right, char *dLeft, char *dRight, long frames)
+{
+       unsigned char *cl = (unsigned char *)left;
+       unsigned char *cr = (unsigned char *)right;
+       unsigned char a, b;
+
+       dLeft--;
+       dRight--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = cl[3];
+               b = cr[3];
+#else
+               a = cl[0];
+               b = cr[0];
+#endif
+               cl += 4;
+               cr += 4;
+               a -= 0x80U;
+               b -= 0x80U;
+               *++dLeft = a;
+               *++dRight = b;
+       }       
+}
+
+void ASIOConvertSamples::convertStereo8(long *left, long *right, char *dLeft, char *dRight, long frames)
+{
+       unsigned char *cl = (unsigned char *)left;
+       unsigned char *cr = (unsigned char *)right;
+       unsigned char a, b;
+
+       dLeft--;
+       dRight--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = cl[3];
+               b = cr[3];
+#else
+               a = cl[0];
+               b = cr[0];
+#endif
+               cl += 4;
+               cr += 4;
+               *++dLeft = a;
+               *++dRight = b;
+       }       
+}
+
+void ASIOConvertSamples::convertStereo16(long *left, long *right, short *dLeft, short *dRight, long frames)
+{
+#if ASIO_LITTLE_ENDIAN
+       char* sl = (char*)left;
+       char* sr = (char*)right;
+       char* dl = (char*)dLeft;
+       char* dr = (char*)dRight;
+       while(--frames >= 0)
+       {
+               *dl++ = sl[3];  // msb first
+               *dl++ = sl[2];
+               *dr++ = sr[3];
+               *dr++ = sr[2];
+               sl += 4;
+               sr += 4;
+       }
+#else
+       long l, r;
+
+       left--;
+       right--;
+       dLeft--;
+       dRight--;
+       while(--frames >= 0)
+       {
+               l = *++left;
+               r = *++right;
+               *++dLeft = (short)(l >> 16);
+               *++dRight = (short)(r >> 16);
+       }
+#endif 
+}
+
+void ASIOConvertSamples::convertStereo24(long *left, long *right, char *dLeft, char *dRight, long frames)
+{
+       // work with chars in order to prevent misalignments
+       char *sl = (char *)left;
+       char *sr = (char *)right;
+       char al, bl, cl, ar, br, cr;
+
+       dLeft--;
+       dRight--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               al = sl[3];
+               bl = sl[2];
+               cl = sl[1];
+               ar = sr[3];
+               br = sr[2];
+               cr = sr[1];
+#else
+               al = sl[0];
+               bl = sl[1];
+               cl = sl[2];
+               ar = sr[0];
+               br = sr[1];
+               cr = sr[2];
+#endif
+               sl += 4;
+               sr += 4;
+               *++dLeft = al;
+               *++dLeft = bl;
+               *++dLeft = cl;
+               *++dRight = ar;
+               *++dRight = br;
+               *++dRight = cr;
+       }
+}
+
+// small endian
+void ASIOConvertSamples::convertStereo16SmallEndian(long *left, long *right, short *dLeft, short *dRight, long frames)
+{
+       char *sl = (char *)left;
+       char *sr = (char *)right;
+       char *dl = (char *)dLeft;
+       char *dr = (char *)dRight;
+       char al, bl, ar, br;
+
+       dl--;
+       dr--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               al = sl[3];
+               bl = sl[2];
+               ar = sr[3];
+               br = sr[2];
+#else
+               al = sl[0];
+               bl = sl[1];
+               ar = sr[0];
+               br = sr[1];
+#endif
+               sl += 4;
+               sr += 4;
+               *++dl = bl;
+               *++dl = al;
+               *++dr = br;
+               *++dr = ar;
+       }
+}
+
+void ASIOConvertSamples::convertStereo24SmallEndian(long *left, long *right, char *dLeft, char *dRight, long frames)
+{
+       // work with chars in order to prevent misalignments
+       char *sl = (char *)left;
+       char *sr = (char *)right;
+       char al, bl, cl, ar, br, cr;
+
+       dLeft--;
+       dRight--;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               al = sl[3];
+               bl = sl[2];
+               cl = sl[1];
+               ar = sr[3];
+               br = sr[2];
+               cr = sr[1];
+#else
+               al = sl[0];
+               bl = sl[1];
+               cl = sl[2];
+               ar = sr[0];
+               br = sr[1];
+               cr = sr[2];
+#endif
+               sl += 4;
+               sr += 4;
+               *++dLeft = cl;
+               *++dLeft = bl;
+               *++dLeft = al;
+               *++dRight = cr;
+               *++dRight = br;
+               *++dRight = ar;
+       }
+}
+
+//------------------------------------------------------------------------------------------
+// in place integer conversions
+
+void ASIOConvertSamples::int32msb16to16inPlace(long *in, long frames)
+{
+       short *d1 = (short *)in;
+       short* out = d1;
+#if ASIO_LITTLE_ENDIAN
+       d1++;
+#endif
+       while(--frames >= 0)
+       {
+               *out++ = *d1;
+               d1 += 2;
+       }
+}
+
+void ASIOConvertSamples::int32lsb16to16inPlace(long *in, long frames)
+{
+       short *d1 = (short *)in;
+       short* out = d1;
+#if !ASIO_LITTLE_ENDIAN
+       d1++;
+#endif
+       while(--frames >= 0)
+       {
+               *out++ = *d1;
+               d1 += 2;
+       }
+}
+
+void ASIOConvertSamples::int32msb16shiftedTo16inPlace(long *in, long frames, long shift)
+{
+       short* out = (short*)in;
+       while(--frames >= 0)
+               *out++ = (short)(*in++ >> shift);
+}
+
+void ASIOConvertSamples::int24msbto16inPlace(unsigned char *in, long frames)
+{
+       short a;
+       short* out = (short*)in;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = (short)in[2];
+               a <<= 8;
+               a |= (in[1] & 0xff);
+#else
+               a = (short)in[0];
+               a <<= 8;
+               a |= (in[1] & 0xff);
+#endif
+               *out++ = a;
+               in += 3;
+       }
+}
+
+//-----------------------------------------------------------------------------------------
+
+void ASIOConvertSamples::shift32(void* buffer, long shiftAmount, long targetByteWidth,
+       bool revertEndian,      long sampleFrames)
+{
+       long a;
+       long frames = sampleFrames;
+       long* source = (long*)buffer;
+       if(revertEndian)
+       {
+               reverseEndian(buffer, 4, sampleFrames);
+               revertEndian = false;
+       }
+
+       if(targetByteWidth == 2)
+       {
+               short* dest = (short*)buffer;
+               short* al = (short*)&a;
+#if ASIO_LITTLE_ENDIAN
+               al++;
+#endif
+               while(--frames >= 0)
+               {
+                       a = *source++;
+                       a <<= shiftAmount;
+                       *dest++ = *al;
+               }
+       }
+       
+       else if(targetByteWidth == 3)
+       {
+               char* dest = (char*)buffer;
+               long* source = (long*)buffer;
+               char* aa = (char*)&a;
+               while(--frames >= 0)
+               {
+                       a = *source++;
+                       a <<= shiftAmount;
+#if ASIO_LITTLE_ENDIAN
+                       dest[0] = aa[1];        // lsb
+                       dest[1] = aa[2];
+                       dest[2] = aa[3];        // msb
+#else
+                       dest[0] = aa[0];        // msb
+                       dest[1] = aa[1];
+                       dest[2] = aa[2];        // lsb
+#endif
+                       dest += 3;
+               }
+       }
+       
+       else if(targetByteWidth == 4)
+       {
+               long* dest = source;
+               while(--frames >= 0)
+                       *dest++ = *source++ << shiftAmount;
+       }
+}
+
+void ASIOConvertSamples::reverseEndian(void* buffer, long byteWidth, long frames)
+{
+       char* a = (char*)buffer;
+       char* b = a;
+       char c; 
+       if(byteWidth == 2)
+       {
+               while(--frames >= 0)
+               {
+                       c = a[0];
+                       a[0] = a[1];
+                       a[1] = c;
+                       a += 2;
+               }
+       }
+       else if(byteWidth == 3)
+       {
+               while(--frames >= 0)
+               {
+                       c = a[0];
+                       a[0] = a[2];
+                       a[2] = c;
+                       a += 3;
+               }
+       }
+       else if(byteWidth == 4)
+       {
+               while(--frames >= 0)
+               {
+                       c = a[0];
+                       a[0] = a[3];
+                       a[3] = c;
+                       c = a[1];
+                       a[1] = a[2];
+                       a[2] = c;
+                       a += 4;
+               }
+       }
+}
+
+//-------------------------------------------------------------------------------------------------
+
+void ASIOConvertSamples::int32to16inPlace(void* buffer, long frames)
+{
+       short* in = (short*)buffer;
+       short* out = in;
+#if ASIO_LITTLE_ENDIAN
+       in++;
+#endif
+       while(--frames >= 0)
+       {
+               *out++ = *in;
+               in += 2;
+       }
+}
+
+void ASIOConvertSamples::int24to16inPlace(void* buffer, long frames)
+{
+       char* from = (char*)buffer;
+       char* to = from;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               to[0] = from[1];
+               to[1] = from[2];
+#else
+               to[0] = from[0];
+               to[1] = from[1];
+#endif
+               from += 3;
+               to += 2;
+       }
+}
+
+void ASIOConvertSamples::int32to24inPlace(void* buffer, long frames)
+{
+       long* in = (long*)buffer;
+       char* out = (char*)buffer;
+       long a;
+       while(--frames >= 0)
+       {
+               a = *in++;
+               a >>= 8;                        // 32->24
+#if ASIO_LITTLE_ENDIAN
+               out[0] = (char)a;       // lsb
+               a >>= 8;
+               out[1] = (char)a;
+               a >>= 8;
+               out[2] = (char)a;
+#else
+               out[2] = (char)a;       // lsb
+               a >>= 8;
+               out[1] = (char)a;
+               a >>= 8;
+               out[0] = (char)a;
+#endif
+               out += 3;
+       }
+}
+
+void ASIOConvertSamples::int16to24inPlace(void* buffer, long frames)
+{
+       char* in = (char*)buffer;
+       char* out = (char*)buffer;
+       in += frames * 2;
+       out += frames * 3;
+       while(--frames >= 0)
+       {
+               out -= 3;
+               in -= 2;
+#if ASIO_LITTLE_ENDIAN
+               out[2] = in[1]; // msb
+               out[1] = in[0]; // lsb
+               out[0] = 0;
+#else
+               out[2] = 0;
+               out[1] = in[1]; // lsb
+               out[0] = in[0]; // msb
+#endif
+       }
+}
+
+void ASIOConvertSamples::int24to32inPlace(void* buffer, long frames)
+{
+       long a, b, c;
+       char* in = (char*)buffer;
+       long* out = (long*)buffer;
+       in += (frames * 3);
+       out += frames;
+       while(--frames >= 0)
+       {
+#if ASIO_LITTLE_ENDIAN
+               a = (long)in[-1];       // msb
+               b = (long)in[-2];
+               c = (long)in[-3];
+#else
+               a = (long)in[-3];       // msb
+               b = (long)in[-2];
+               c = (long)in[-1];
+#endif
+               a <<= 24;
+               b <<= 16;
+               b &= 0x00ff0000;
+               a |= b;
+               c <<= 8;
+               c &= 0x0000ff00;
+               a |= c;
+               *--out = a;
+               in -= 3;
+       }
+}
+
+void ASIOConvertSamples::int16to32inPlace(void* buffer, long frames)
+{
+       short* in = (short*)buffer;
+       long* out = (long*)buffer;
+       in += frames;
+       out += frames;
+       while(--frames >= 0)
+               *--out = ((long)(*--in)) << 16;
+}
+
+//------------------------------------------------------------------------------------------
+// float to int
+
+const double fScaler16 = (double)0x7fffL;
+const double fScaler24 = (double)0x7fffffL;
+const double fScaler32 = (double)0x7fffffffL;
+
+void ASIOConvertSamples::float32toInt16inPlace(float* buffer, long frames)
+{
+       double sc = fScaler16 + .49999;
+       short* b = (short*)buffer;
+       while(--frames >= 0)
+               *b++ = (short)((double)(*buffer++) * sc);
+}
+
+void ASIOConvertSamples::float32toInt24inPlace(float* buffer, long frames)
+{
+       double sc = fScaler24 + .49999;
+       long a;
+       char* b = (char*)buffer;
+       char* aa = (char*)&a;
+       
+       while(--frames >= 0)
+       {
+               a = (long)((double)(*buffer++) * sc);
+#if ASIO_LITTLE_ENDIAN
+               *b++ = aa[3];
+               *b++ = aa[2];
+               *b++ = aa[1];
+#else
+               *b++ = aa[1];
+               *b++ = aa[2];
+               *b++ = aa[3];
+#endif
+       }
+}
+
+void ASIOConvertSamples::float32toInt32inPlace(float* buffer, long frames)
+{
+       double sc = fScaler32 + .49999;
+       long* b = (long*)buffer;
+       while(--frames >= 0)
+               *b++ = (long)((double)(*buffer++) * sc);
+}
+
diff --git a/src/hostapi/asio/ASIOSDK/host/ASIOConvertSamples.h b/src/hostapi/asio/ASIOSDK/host/ASIOConvertSamples.h
new file mode 100644 (file)
index 0000000..d1918a2
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef __ASIOConvertSamples__
+#define __ASIOConvertSamples__
+
+class ASIOConvertSamples
+{
+public:
+       ASIOConvertSamples();
+       ~ASIOConvertSamples() {}
+
+       // format converters, input 32 bit integer
+       // mono
+       void convertMono8(long *source, char *dest, long frames);
+       void convertMono8Unsigned(long *source, char *dest, long frames);
+       void convertMono16(long *source, short *dest, long frames);
+       void convertMono16SmallEndian(long *source, short *dest, long frames);
+       void convertMono24(long *source, char *dest, long frames);
+       void convertMono24SmallEndian(long *source, char *dest, long frames);
+
+       // stereo interleaved
+       void convertStereo8Interleaved(long *left, long *right, char *dest, long frames);
+       void convertStereo8InterleavedUnsigned(long *left, long *right, char *dest, long frames);
+       void convertStereo16Interleaved(long *left, long *right, short *dest, long frames);
+       void convertStereo16InterleavedSmallEndian(long *left, long *right, short *dest, long frames);
+       void convertStereo24Interleaved(long *left, long *right, char *dest, long frames);
+       void convertStereo24InterleavedSmallEndian(long *left, long *right, char *dest, long frames);
+
+       // stereo split
+       void convertStereo8(long *left, long *right, char *dLeft, char *dRight, long frames);
+       void convertStereo8Unsigned(long *left, long *right, char *dLeft, char *dRight, long frames);
+       void convertStereo16(long *left, long *right, short *dLeft, short *dRight, long frames);
+       void convertStereo16SmallEndian(long *left, long *right, short *dLeft, short *dRight, long frames);
+       void convertStereo24(long *left, long *right, char *dLeft, char *dRight, long frames);
+       void convertStereo24SmallEndian(long *left, long *right, char *dLeft, char *dRight, long frames);
+
+       // integer in place conversions
+
+       void int32msb16to16inPlace(long *in, long frames);
+       void int32lsb16to16inPlace(long *in, long frames);
+       void int32msb16shiftedTo16inPlace(long *in1, long frames, long shift);
+       void int24msbto16inPlace(unsigned char *in, long frames);
+
+       // integer to integer
+
+       void shift32(void* buffer, long shiftAmount, long targetByteWidth,
+               bool reverseEndian,     long frames);
+       void reverseEndian(void* buffer, long byteWidth, long frames);
+
+       void int32to16inPlace(void* buffer, long frames);
+       void int24to16inPlace(void* buffer, long frames);
+       void int32to24inPlace(void* buffer, long frames);
+       void int16to24inPlace(void* buffer, long frames);
+       void int24to32inPlace(void* buffer, long frames);
+       void int16to32inPlace(void* buffer, long frames);
+
+       // float to integer
+       
+       void float32toInt16inPlace(float* buffer, long frames);
+       void float32toInt24inPlace(float* buffer, long frames);
+       void float32toInt32inPlace(float* buffer, long frames);
+};
+
+#endif
diff --git a/src/hostapi/asio/ASIOSDK/host/asiodrivers.cpp b/src/hostapi/asio/ASIOSDK/host/asiodrivers.cpp
new file mode 100644 (file)
index 0000000..4067bc0
--- /dev/null
@@ -0,0 +1,186 @@
+#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
diff --git a/src/hostapi/asio/ASIOSDK/host/asiodrivers.h b/src/hostapi/asio/ASIOSDK/host/asiodrivers.h
new file mode 100644 (file)
index 0000000..511f2ea
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef __AsioDrivers__
+#define __AsioDrivers__
+
+#include "ginclude.h"
+
+#if MAC
+#include "CodeFragments.hpp"
+
+class AsioDrivers : public CodeFragments
+
+#elif WINDOWS
+#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
diff --git a/src/hostapi/asio/ASIOSDK/host/ginclude.h b/src/hostapi/asio/ASIOSDK/host/ginclude.h
new file mode 100644 (file)
index 0000000..97cb7b7
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef __gInclude__
+#define __gInclude__
+
+#if SGI 
+       #undef BEOS 
+       #undef MAC 
+       #undef WINDOWS
+       //
+       #define ASIO_BIG_ENDIAN 1
+       #define ASIO_CPU_MIPS 1
+#elif defined(_WIN32) || 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__
diff --git a/src/hostapi/asio/ASIOSDK/host/mac/asioshlib.cpp b/src/hostapi/asio/ASIOSDK/host/mac/asioshlib.cpp
new file mode 100644 (file)
index 0000000..77163e5
--- /dev/null
@@ -0,0 +1,342 @@
+// asio code fragment 'linker'
+// mac specific
+// loads the symbols via the fragment manager, and
+// translates them into function pointers. this
+// means no asio lib must be linked, as the
+// 'real' asio functions are here
+
+#include "ginclude.h"
+#include <macheaders.c>
+#include <string.h>
+#include <CodeFragments.h>
+#include "asio.h"
+
+// Macro below has to 0 if external drivers will be used.
+// Can be set to 1 if a specific ASIO driver should be linked into the program
+#define ASIOINCLUDED 0
+
+
+
+// export
+bool resolveASIO(unsigned long aconnID);
+
+//------------------------------------------------------------------------------------------------------
+// private
+
+#if ASIOINCLUDED
+bool resolveASIO(unsigned long aconnID) {aconnID = aconnID; return true;}
+#else
+
+enum
+{
+       kASIOInit = 0,
+       kASIOExit,
+       kASIOStart,
+       kASIOStop,
+       kASIOGetChannels,
+       kASIOGetLatencies,
+       kASIOGetBufferSize,
+       kASIOCanSampleRate,
+       kASIOGetSampleRate,
+       kASIOSetSampleRate,
+       kASIOGetClockSources,
+       kASIOSetClockSource,
+       kASIOGetSamplePosition,
+       kASIOGetChannelInfo,
+       kASIOCreateBuffers,
+       kASIODisposeBuffers,
+       kASIOControlPanel,
+       kASIOFuture,
+
+       kASIOOutputReady,
+
+       kNumSymbols,
+       kRequiredSymbols = kNumSymbols - 1
+}; 
+
+static char *asioTable[kNumSymbols] = 
+{
+       "ASIOInit",
+       "ASIOExit",
+       "ASIOStart",
+       "ASIOStop",
+       "ASIOGetChannels",
+       "ASIOGetLatencies",
+       "ASIOGetBufferSize",
+       "ASIOCanSampleRate",
+       "ASIOGetSampleRate",
+       "ASIOSetSampleRate",
+       "ASIOGetClockSources",
+       "ASIOSetClockSource",
+       "ASIOGetSamplePosition",
+       "ASIOGetChannelInfo",
+       "ASIOCreateBuffers",
+       "ASIODisposeBuffers",
+       "ASIOControlPanel",
+       "ASIOFuture",
+       "ASIOOutputReady"
+};
+
+typedef ASIOError (*fasioInit) (ASIODriverInfo *info);
+typedef ASIOError (*fasioExit) (void);
+typedef ASIOError (*fasioStart) (void);
+typedef ASIOError (*fasioStop) (void);
+typedef ASIOError (*asioGetChannels) (long *numInputChannels, long *numOutputChannels);
+typedef ASIOError (*asioGetLatencies) (long *inputLatency, long *outputLatency);
+typedef ASIOError (*asioGetBufferSize) (long *minSize, long *maxSize, long *preferredSize, long *granularity);
+typedef ASIOError (*asioCanSampleRate) (ASIOSampleRate sampleRate);
+typedef ASIOError (*asioGetSampleRate) (ASIOSampleRate *currentRate);
+typedef ASIOError (*asioSetSampleRate) (ASIOSampleRate sampleRate);
+typedef ASIOError (*asioGetClockSources) (ASIOClockSource *clocks, long *numSources);
+typedef ASIOError (*asioSetClockSource) (long reference);
+typedef ASIOError (*asioGetSamplePosition) (ASIOSamples *sPos, ASIOTimeStamp *tStamp);
+typedef ASIOError (*asioGetChannelInfo) (ASIOChannelInfo *info);
+typedef ASIOError (*asioCreateBuffers) (ASIOBufferInfo *channelInfos, long numChannels,
+       long bufferSize, ASIOCallbacks *callbacks);
+typedef ASIOError (*asioDisposeBuffers) (void);
+typedef ASIOError (*asioControlPanel) (void);
+typedef ASIOError (*asioFuture)(long selector, void *opt);
+typedef ASIOError (*asioOutputReady) (void);
+
+static void *functionTable[kNumSymbols] = {0};
+static bool inited = false;
+
+//---------------------------------------------------------------------------------------------------------
+
+#include <CodeFragments.h>
+
+bool resolveASIO(unsigned long aconnID)
+{
+       OSErr err;
+       CFragConnectionID connID = (CFragConnectionID)aconnID;
+       CFragSymbolClass symClass;
+       Ptr symAddr = nil;
+       Str255 myName;
+       long myCount = 0;
+
+       err = CountSymbols(connID, &myCount);
+       if(err != noErr || myCount < (kRequiredSymbols + 1))    // there must be a main()
+               return false;
+
+       long n, c = 0;
+       for(n = kRequiredSymbols; n < kNumSymbols; n++)
+               functionTable[n] = 0;
+       for(n = 0; n < myCount; n++)
+       {
+               // we can't use FindSymbol(), as the compiler adds mangling
+               // (such as ASIOInit__Fv). also, the symbols don't appear
+               // in the order they are declared or implemented.
+               // so we use strncmp()
+               err = GetIndSymbol(connID, n, myName, &symAddr, &symClass);
+               if(err != noErr)
+                       break;
+               PtoCstr(myName);
+               if(!strncmp((char *)myName, "main", 4L))
+                       c++;
+               else
+               {
+                       for(long i = 0; i < kNumSymbols; i++)
+                       {
+                               long sc = strlen(asioTable[i]);
+                               if(!strncmp((char *)myName, asioTable[i], sc))
+                               {
+                                       functionTable[i] = symAddr;
+                                       if(i < kRequiredSymbols)
+                                               c++;
+                                       break;
+                               }
+                       }
+               }
+               // if(c >= kNumSymbols + 1)
+               //      break;
+       }
+       if(c >= kRequiredSymbols + 1)
+       {
+               inited = true;
+               return true;
+       }
+       return false;
+}
+
+//---------------------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------------------
+
+#pragma export on
+
+static short curRes = 0;
+#define saveRes() curRes = CurResFile()
+#define restRes() UseResFile(curRes);
+
+
+ASIOError ASIOInit(ASIODriverInfo *info)
+{
+       saveRes();
+       strcpy(info->errorMessage, "No ASIO Driver could be Loaded!");
+       if(!inited)
+               return ASE_NotPresent;
+       fasioInit f = (fasioInit)functionTable[kASIOInit];
+       ASIOError e = (*f)(info);
+       restRes();
+       return e;
+}
+
+ASIOError ASIOExit(void)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       saveRes();
+       fasioExit f = (fasioExit)functionTable[kASIOExit];
+       ASIOError e = (*f)();
+       restRes();
+       return e;
+}
+
+ASIOError ASIOStart(void)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       fasioStart f = (fasioStart)functionTable[kASIOStart];
+       return (*f)();
+}
+
+ASIOError ASIOStop(void)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       fasioStop f = (fasioStop)functionTable[kASIOStop];
+       return (*f)();
+}
+
+ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioGetChannels f = (asioGetChannels)functionTable[kASIOGetChannels];
+       return (*f)(numInputChannels, numOutputChannels);
+}
+
+ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioGetLatencies f = (asioGetLatencies)functionTable[kASIOGetLatencies];
+       return (*f)(inputLatency, outputLatency);
+}
+
+ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioGetBufferSize f = (asioGetBufferSize)functionTable[kASIOGetBufferSize];
+       return (*f)(minSize, maxSize, preferredSize, granularity);
+}
+
+ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioCanSampleRate f = (asioCanSampleRate)functionTable[kASIOCanSampleRate];
+       return (*f)(sampleRate);
+}
+
+ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioGetSampleRate f = (asioGetSampleRate)functionTable[kASIOGetSampleRate];
+       return (*f)(currentRate);
+}
+
+ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioSetSampleRate f = (asioSetSampleRate)functionTable[kASIOSetSampleRate];
+       return (*f)(sampleRate);
+}
+
+ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioGetClockSources f = (asioGetClockSources)functionTable[kASIOGetClockSources];
+       return (*f)(clocks, numSources);
+}
+
+ASIOError ASIOSetClockSource(long reference)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioSetClockSource f = (asioSetClockSource)functionTable[kASIOSetClockSource];
+       return (*f)(reference);
+}
+
+ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioGetSamplePosition f = (asioGetSamplePosition)functionTable[kASIOGetSamplePosition];
+       return (*f)(sPos, tStamp);
+}
+
+ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioGetChannelInfo f = (asioGetChannelInfo)functionTable[kASIOGetChannelInfo];
+       return (*f)(info);
+}
+
+ASIOError ASIOCreateBuffers(ASIOBufferInfo *channelInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       saveRes();
+       asioCreateBuffers f = (asioCreateBuffers)functionTable[kASIOCreateBuffers];
+       ASIOError e = (*f)(channelInfos, numChannels, bufferSize, callbacks);
+       restRes();
+       return e;
+}
+
+ASIOError ASIODisposeBuffers(void)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       asioDisposeBuffers f = (asioDisposeBuffers)functionTable[kASIODisposeBuffers];
+       return (*f)();
+}
+
+ASIOError ASIOControlPanel(void)
+{
+       if(!inited)
+               return ASE_NotPresent;
+       saveRes();
+       asioControlPanel f = (asioControlPanel)functionTable[kASIOControlPanel];
+       ASIOError e = (*f)();
+       restRes();
+       return e;
+}
+
+ASIOError ASIOFuture(long selector, void *opt)
+{
+       if(!inited)
+               return 0;
+       saveRes();
+       asioFuture f = (asioFuture)functionTable[kASIOFuture];
+       ASIOError e = (*f)(selector, opt);
+       restRes();
+       return e;
+}
+
+ASIOError ASIOOutputReady(void)
+{
+       asioOutputReady f = (asioControlPanel)functionTable[kASIOOutputReady];
+       if(!inited || !f)
+               return ASE_NotPresent;
+       return (*f)();
+}
+
+#pragma export off
+
+#endif // ASIOINCLUDED
+
diff --git a/src/hostapi/asio/ASIOSDK/host/mac/codefragments.cpp b/src/hostapi/asio/ASIOSDK/host/mac/codefragments.cpp
new file mode 100644 (file)
index 0000000..6b3cb07
--- /dev/null
@@ -0,0 +1,349 @@
+// very MAC specific; generic code fragment handler
+#include "ginclude.h"
+#include <macheaders.c>
+#include <string.h>
+#include <Files.h>
+#include <CodeFragments.h>
+#include "CodeFragments.hpp"
+
+enum
+{
+       kNewCFragCopy                           = kPrivateCFragCopy
+};
+
+class CodeFragmentInstance
+{
+private:
+friend class CodeFragment;
+       CodeFragmentInstance() {next = 0; handle = 0; connID = (void*)-1;}
+       ~CodeFragmentInstance() {CloseConnection((CFragConnectionID*)&connID); DisposeHandle(handle);}
+
+       CodeFragmentInstance *next;
+       Handle handle;
+       void* connID;
+};
+
+class CodeFragment
+{
+public:
+       CodeFragment();
+       ~CodeFragment();
+
+       bool newInstance(void** cID);
+       void removeInstance(void* id);
+       bool getName(char *name) {if(!resName[0]) return false; strcpy(name, resName); return true;}
+
+private:
+friend class CodeFragments;
+
+       CodeFragment *next;
+       CodeFragmentInstance *root;
+       Handle handle;
+       long numInstances;
+       long index;
+       char resName[64];
+};
+
+//------------------------------------------------------------------------------------------
+
+CodeFragment::CodeFragment()
+{
+       next = 0;
+       root = 0;
+       handle = 0;
+       numInstances = 0;
+       index = 0;
+       resName[0] = 0;
+}
+
+CodeFragment::~CodeFragment()
+{
+       // could delete all instances
+       // rather omit it...
+}
+
+bool CodeFragment::newInstance(void** cID)
+{
+       Ptr myMainAddr;
+       Str255 myErrName;
+       char pname[256];
+
+       *cID = (void*)-1;
+       if(!handle)
+               return false;
+       CodeFragmentInstance *c = new CodeFragmentInstance();
+       if(!c)
+               return false;
+       c->handle = this->handle;
+       OSErr err = HandToHand(&c->handle);
+       if(err == noErr)
+       {
+               // use fragment loader
+               myMainAddr = 0;
+               strcpy(pname, resName);
+               CtoPstr(pname);
+               err = GetMemFragment(*handle, GetHandleSize(handle),
+                       (unsigned char *)pname, kNewCFragCopy, (CFragConnectionID*)&c->connID,
+                       &myMainAddr, myErrName);
+               if(err == noErr && myMainAddr)
+               {
+                       if(!root)
+                               root = c;
+                       else
+                       {
+                               CodeFragmentInstance *cc = root;
+                               while(cc->next)
+                                       cc = cc->next;
+                               cc->next = c;
+                       }
+                       numInstances++;
+                       *cID = c->connID;
+                       return true;
+               }
+       }
+       return false;
+}
+
+void CodeFragment::removeInstance(void* id)
+{
+       CodeFragmentInstance *c = root, *last = root;
+       while(c)
+       {
+               if(c->connID == id)
+               {
+                       if(c == root)
+                               root = root->next;
+                       else
+                               last->next = c->next;
+                       delete c;
+                       numInstances--;
+                       return;
+               }
+               last = c;
+               c = c->next;
+       }               
+}
+
+//----------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------
+
+CodeFragments::CodeFragments(char *folderName, long fileType, long resType)
+{
+       root = 0;
+       numFragments = 0;
+       gARefNum = -1;
+       
+       if(setFolder(folderName))
+       {
+               loadFragments(gARefNum, fileType, resType);
+               SetVol(0L, defVol);
+       }
+}
+
+CodeFragments::~CodeFragments()
+{
+       while(root)
+       {
+               CodeFragment *c = root->next;
+               delete root;
+               root = c;
+       }
+}
+
+bool CodeFragments::newInstance(long index, unsigned long* cID)
+{
+       *cID = -1;
+       CodeFragment *c = root;
+       while(c)
+       {
+               if(c->index == index)
+                       return c->newInstance((void**)cID);
+               c = c->next;
+       }
+       return false;
+}
+
+void CodeFragments::removeInstance(long index, unsigned long cID)
+{
+       CodeFragment *c = root;
+       while(c)
+       {
+               if(c->index == index)
+               {
+                       c->removeInstance((void*)cID);
+                       break;
+               }
+               c = c->next;
+       }
+}
+
+bool CodeFragments::getName(long index, char *name)
+{
+       CodeFragment *c = root;
+       while(c)
+       {
+               if(c->index == index)
+               {
+                       strcpy(name, c->resName);
+                       return true;
+               }
+               c = c->next;
+       }
+       return false;
+}
+
+//------------------------------------------------------------------------------------
+// private
+
+void CodeFragments::loadFragments(short folderRef, long fileType, long resType)
+{
+       Str255 fileName;
+       HFileParam parmblock;
+       short resRef,index = 1,lindex;
+       short resID;
+       ResType resourceType;
+       Str255 resName;
+       Handle h;
+       short curResFile = CurResFile();
+
+       while(true)
+       {
+               // find any file in the folder
+               memset (&parmblock,0,(long)sizeof(HFileParam));
+               parmblock.ioNamePtr     = fileName;
+               parmblock.ioVRefNum     = folderRef;    
+               parmblock.ioFDirIndex   = index;
+               if(PBHGetFInfoSync ((HParmBlkPtr)&parmblock) != noErr)
+                       break;
+
+               // see if the file type matches
+               if(parmblock.ioFlFndrInfo.fdType == fileType)
+               {
+                       resRef = OpenResFile(fileName);
+                       if(ResError()==noErr)
+                       {
+                               UseResFile(resRef);
+                               lindex = 1;
+                               // search resources in the file found which match
+                               while(true)
+                               {
+                                       h = Get1IndResource(resType, lindex);
+                                       if(h)
+                                       {
+                                               CodeFragment *c = new CodeFragment;
+                                               if(!root)
+                                                       root = c;
+                                               else
+                                               {
+                                                       CodeFragment *cc = root;
+                                                       while(cc->next)
+                                                               cc = cc->next;
+                                                       cc->next = c;
+                                               }
+                                               GetResInfo(h, &resID, &resourceType, resName);
+                                               // PtoCstr(fileName);
+                                               // strcpy(c->fileName, (char *)fileName);
+                                               PtoCstr(resName);
+                                               strcpy(c->resName, (char*)resName);
+                                               DetachResource(h);
+                                               HLockHi(h);
+                                               c->handle = h;
+                                               c->index = numFragments;
+                                               numFragments++;
+                                       }
+                                       else
+                                               break;
+                                       lindex++;
+                               }
+                               CloseResFile(resRef);
+                       }
+               }
+               index++;
+       }
+       UseResFile(curResFile);
+}
+
+//-----------------------------------------------------------------------------------------
+
+bool CodeFragments::setFolder(char *folderName)
+{
+       FSSpec fss;
+
+       if(gARefNum == -1)
+       {
+               if(!getFrontProcessDirectory(&fss))
+                       return false;
+               if(!openFragmentFolder(&fss, folderName, &gARefNum))
+                       return false;
+       }
+       defVol = getDefVol();
+       SetVol(0L, gARefNum);
+       return true;
+}
+
+bool CodeFragments::getFrontProcessDirectory(void *specs)
+{
+       FSSpec *fss = (FSSpec *)specs;
+       ProcessInfoRec pif;
+       ProcessSerialNumber psn;
+
+       memset(&psn,0,(long)sizeof(ProcessSerialNumber));
+       if(GetFrontProcess(&psn) == noErr)
+       {
+               pif.processName = 0;    //(StringPtr)name;
+               pif.processAppSpec = fss;
+               pif.processInfoLength = sizeof(ProcessInfoRec);
+               if(GetProcessInformation(&psn, &pif) == noErr)
+                               return true;
+       }
+       return false;
+}
+
+bool CodeFragments::openFragmentFolder(void *specs, char *foldername, short *found_vref)
+{
+       FSSpec *fss     = (FSSpec *)specs;
+       WDPBRec         funcparms,homefolder;
+       HFileInfo       my_funcfolder;
+       char funcFolder_name[32];
+
+       *found_vref = -1;
+       strcpy(funcFolder_name,foldername);
+       CtoPstr(funcFolder_name);
+
+       memset (&homefolder,0,(long)sizeof(WDPBRec));
+       homefolder.ioVRefNum = fss->vRefNum;
+       homefolder.ioWDDirID = fss->parID;
+       if(PBOpenWDSync(&homefolder) != noErr)
+               return false;
+       memset(&my_funcfolder,0,(long)sizeof(CInfoPBRec));
+       my_funcfolder.ioNamePtr         = (StringPtr)funcFolder_name;
+       my_funcfolder.ioVRefNum         = homefolder.ioVRefNum;
+       if(PBGetCatInfoSync((CInfoPBPtr)&my_funcfolder) != noErr)
+       {
+               PBCloseWDSync(&homefolder);
+               return false;
+       }
+       memset (&funcparms,0,(long)sizeof(WDPBRec));
+       funcparms.ioWDProcID    = 'stCA';
+       funcparms.ioVRefNum = my_funcfolder.ioVRefNum;
+       funcparms.ioWDDirID = my_funcfolder.ioDirID;
+       if(PBOpenWDSync(&funcparms) != noErr)
+       {
+               PBCloseWDSync(&homefolder);
+               return false;
+       }
+       PBCloseWDSync(&homefolder);
+       *found_vref     = funcparms.ioVRefNum;
+       return true;
+}
+
+short CodeFragments::getDefVol()
+{
+       unsigned char text[32];
+       short vol_ref = 0;
+
+       *text=0;
+       if(GetVol(text, &vol_ref) == noErr)
+               return (vol_ref);
+       return 0;
+}
diff --git a/src/hostapi/asio/ASIOSDK/host/mac/codefragments.hpp b/src/hostapi/asio/ASIOSDK/host/mac/codefragments.hpp
new file mode 100644 (file)
index 0000000..2eb6ba2
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef __CodeFragments__
+#define __CodeFragments__
+
+class CodeFragment;
+
+class CodeFragments
+{
+public:
+       CodeFragments(char *folderName, long fileType, long resType);
+       ~CodeFragments();
+
+       long getNumFragments() {return numFragments;}
+       bool newInstance(long index, unsigned long *cID);
+       void removeInstance(long index, unsigned long cID);
+       bool getName(long index, char *name);
+
+protected:
+       void loadFragments(short folderRef, long fileType, long resType);
+       bool setFolder(char *folderName);
+       bool openFragmentFolder(void *specs, char *foldername, short *found_vref);
+       bool getFrontProcessDirectory(void *specs);
+       short getDefVol();
+
+       CodeFragment *root;
+       long numFragments;
+       short gARefNum;
+       short defVol;
+};
+
+#endif
diff --git a/src/hostapi/asio/ASIOSDK/host/pc/asiolist.cpp b/src/hostapi/asio/ASIOSDK/host/pc/asiolist.cpp
new file mode 100644 (file)
index 0000000..88b1632
--- /dev/null
@@ -0,0 +1,268 @@
+#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;
+
+       CharLowerBuff(clsidstr,strlen(clsidstr));
+       if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) {
+
+               index = 0;
+               while (cr == ERROR_SUCCESS && !found) {
+                       cr = RegEnumKey(hkEnum,index++,(LPTSTR)databuf,512);
+                       if (cr == ERROR_SUCCESS) {
+                               CharLowerBuff(databuf,strlen(databuf));
+                               if (!(strcmp(databuf,clsidstr))) {
+                                       if ((cr = RegOpenKeyEx(hkEnum,(LPCTSTR)databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
+                                               if ((cr = RegOpenKeyEx(hksub,(LPCTSTR)INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) {
+                                                       datatype = REG_SZ; datasize = (DWORD)dllpathsize;
+                                                       cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize);
+                                                       if (cr == ERROR_SUCCESS) {
+                                                               memset(&ofs,0,sizeof(OFSTRUCT));
+                                                               ofs.cBytes = sizeof(OFSTRUCT); 
+                                                               hfile = OpenFile(dllpath,&ofs,OF_EXIST);
+                                                               if (hfile) rc = 0; 
+                                                       }
+                                                       RegCloseKey(hkpath);
+                                               }
+                                               RegCloseKey(hksub);
+                                       }
+                                       found = TRUE;   // break out 
+                               }
+                       }
+               }                               
+               RegCloseKey(hkEnum);
+       }
+       return rc;
+}
+
+
+static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv)
+{
+       HKEY    hksub;
+       char    databuf[256];
+       char    dllpath[MAXPATHLEN];
+       WORD    wData[100];
+       CLSID   clsid;
+       DWORD   datatype,datasize;
+       LONG    cr,rc;
+
+       if (!lpdrv) {
+               if ((cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
+
+                       datatype = REG_SZ; datasize = 256;
+                       cr = RegQueryValueEx(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize);
+                       if (cr == ERROR_SUCCESS) {
+                               rc = findDrvPath (databuf,dllpath,MAXPATHLEN);
+                               if (rc == 0) {
+                                       lpdrv = new ASIODRVSTRUCT[1];
+                                       if (lpdrv) {
+                                               memset(lpdrv,0,sizeof(ASIODRVSTRUCT));
+                                               lpdrv->drvID = drvID;
+                                               MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100);
+                                               if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) {
+                                                       memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID));
+                                               }
+
+                                               datatype = REG_SZ; datasize = 256;
+                                               cr = RegQueryValueEx(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize);
+                                               if (cr == ERROR_SUCCESS) {
+                                                       strcpy(lpdrv->drvname,databuf);
+                                               }
+                                               else strcpy(lpdrv->drvname,keyname);
+                                       }
+                               }
+                       }
+                       RegCloseKey(hksub);
+               }
+       }       
+       else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next);
+
+       return lpdrv;
+}
+
+static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv)
+{
+       IASIO   *iasio;
+
+       if (lpdrv != 0) {
+               deleteDrvStruct(lpdrv->next);
+               if (lpdrv->asiodrv) {
+                       iasio = (IASIO *)lpdrv->asiodrv;
+                       iasio->Release();
+               }
+               delete lpdrv;
+       }
+}
+
+
+static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv)
+{
+       while (lpdrv) {
+               if (lpdrv->drvID == drvID) return lpdrv;
+               lpdrv = lpdrv->next;
+       }
+       return 0;
+}
+// ******************************************************************
+
+
+// ******************************************************************
+//     AsioDriverList
+// ******************************************************************
+AsioDriverList::AsioDriverList ()
+{
+       HKEY                    hkEnum = 0;
+       char                    keyname[MAXDRVNAMELEN];
+       LPASIODRVSTRUCT pdl;
+       LONG                    cr;
+       DWORD                   index = 0;
+       BOOL                    fin = FALSE;
+
+       numdrv          = 0;
+       lpdrvlist       = 0;
+
+       cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum);
+       while (cr == ERROR_SUCCESS) {
+               if ((cr = RegEnumKey(hkEnum,index++,(LPTSTR)keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) {
+                       lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist);
+               }
+               else fin = TRUE;
+       }
+       if (hkEnum) RegCloseKey(hkEnum);
+
+       pdl = lpdrvlist;
+       while (pdl) {
+               numdrv++;
+               pdl = pdl->next;
+       }
+
+       if (numdrv) CoInitialize(0);    // initialize COM
+}
+
+AsioDriverList::~AsioDriverList ()
+{
+       if (numdrv) {
+               deleteDrvStruct(lpdrvlist);
+               CoUninitialize();
+       }
+}
+
+
+LONG AsioDriverList::asioGetNumDev (VOID)
+{
+       return (LONG)numdrv;
+}
+
+
+LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv)
+{
+       LPASIODRVSTRUCT lpdrv = 0;
+       long                    rc;
+
+       if (!asiodrv) return DRVERR_INVALID_PARAM;
+
+       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
+               if (!lpdrv->asiodrv) {
+                       rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv);
+                       if (rc == S_OK) {
+                               lpdrv->asiodrv = *asiodrv;
+                               return 0;
+                       }
+                       // else if (rc == REGDB_E_CLASSNOTREG)
+                       //      strcpy (info->messageText, "Driver not registered in the Registration Database!");
+               }
+               else rc = DRVERR_DEVICE_ALREADY_OPEN;
+       }
+       else rc = DRVERR_DEVICE_NOT_FOUND;
+       
+       return rc;
+}
+
+
+LONG AsioDriverList::asioCloseDriver (int drvID)
+{
+       LPASIODRVSTRUCT lpdrv = 0;
+       IASIO                   *iasio;
+
+       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
+               if (lpdrv->asiodrv) {
+                       iasio = (IASIO *)lpdrv->asiodrv;
+                       iasio->Release();
+                       lpdrv->asiodrv = 0;
+               }
+       }
+
+       return 0;
+}
+
+LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize)
+{      
+       LPASIODRVSTRUCT                 lpdrv = 0;
+
+       if (!drvname) return DRVERR_INVALID_PARAM;
+
+       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
+               if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) {
+                       strcpy(drvname,lpdrv->drvname);
+               }
+               else {
+                       memcpy(drvname,lpdrv->drvname,drvnamesize-4);
+                       drvname[drvnamesize-4] = '.';
+                       drvname[drvnamesize-3] = '.';
+                       drvname[drvnamesize-2] = '.';
+                       drvname[drvnamesize-1] = 0;
+               }
+               return 0;
+       }
+       return DRVERR_DEVICE_NOT_FOUND;
+}
+
+LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize)
+{
+       LPASIODRVSTRUCT                 lpdrv = 0;
+
+       if (!dllpath) return DRVERR_INVALID_PARAM;
+
+       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
+               if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) {
+                       strcpy(dllpath,lpdrv->dllpath);
+                       return 0;
+               }
+               dllpath[0] = 0;
+               return DRVERR_INVALID_PARAM;
+       }
+       return DRVERR_DEVICE_NOT_FOUND;
+}
+
+LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid)
+{
+       LPASIODRVSTRUCT                 lpdrv = 0;
+
+       if (!clsid) return DRVERR_INVALID_PARAM;
+
+       if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
+               memcpy(clsid,&lpdrv->clsid,sizeof(CLSID));
+               return 0;
+       }
+       return DRVERR_DEVICE_NOT_FOUND;
+}
+
+
diff --git a/src/hostapi/asio/ASIOSDK/host/pc/asiolist.h b/src/hostapi/asio/ASIOSDK/host/pc/asiolist.h
new file mode 100644 (file)
index 0000000..1f504af
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __asiolist__
+#define __asiolist__
+
+#define DRVERR                 -5000
+#define DRVERR_INVALID_PARAM           DRVERR-1
+#define DRVERR_DEVICE_ALREADY_OPEN     DRVERR-2
+#define DRVERR_DEVICE_NOT_FOUND                DRVERR-3
+
+#define MAXPATHLEN                     512
+#define MAXDRVNAMELEN          128
+
+struct asiodrvstruct
+{
+       int                                             drvID;
+       CLSID                                   clsid;
+       char                                    dllpath[MAXPATHLEN];
+       char                                    drvname[MAXDRVNAMELEN];
+       LPVOID                                  asiodrv;
+       struct asiodrvstruct    *next;
+};
+
+typedef struct asiodrvstruct ASIODRVSTRUCT;
+typedef ASIODRVSTRUCT  *LPASIODRVSTRUCT;
+
+class AsioDriverList {
+public:
+       AsioDriverList();
+       ~AsioDriverList();
+       
+       LONG asioOpenDriver (int,VOID **);
+       LONG asioCloseDriver (int);
+
+       // nice to have
+       LONG asioGetNumDev (VOID);
+       LONG asioGetDriverName (int,char *,int);                
+       LONG asioGetDriverPath (int,char *,int);
+       LONG asioGetDriverCLSID (int,CLSID *);
+
+       // or use directly access
+       LPASIODRVSTRUCT lpdrvlist;
+       int                             numdrv;
+};
+
+typedef class AsioDriverList *LPASIODRIVERLIST;
+
+#endif
diff --git a/src/hostapi/asio/ASIOSDK/host/sample/hostsample.cpp b/src/hostapi/asio/ASIOSDK/host/sample/hostsample.cpp
new file mode 100644 (file)
index 0000000..16283bc
--- /dev/null
@@ -0,0 +1,526 @@
+// hostsample.cpp : a simple ASIO host example.
+// - instantiates the driver
+// - get the information from the driver
+// - built up some audio channels
+// - plays silence for 20 seconds
+// - destruct the driver
+// Note: This sample cannot work with the "ASIO DirectX Driver" as it does
+//       not have a valid Application Window handle, which is used as sysRef
+//       on the Windows platform.
+
+#include <stdio.h>
+#include <string.h>
+#include "asiosys.h"
+#include "asio.h"
+#include "asiodrivers.h"
+
+// name of the ASIO device to be used
+#if WINDOWS
+//     #define ASIO_DRIVER_NAME    "ASIO Multimedia Driver"
+       #define ASIO_DRIVER_NAME    "ASIO Sample"
+#elif MAC
+//     #define ASIO_DRIVER_NAME        "Apple Sound Manager"
+       #define ASIO_DRIVER_NAME        "ASIO Sample"
+#endif
+
+#define TEST_RUN_TIME  20.0            // run for 20 seconds
+
+
+enum {
+       // number of input and outputs supported by the host application
+       // you can change these to higher or lower values
+       kMaxInputChannels = 32,
+       kMaxOutputChannels = 32
+};
+
+
+// internal data storage
+typedef struct DriverInfo
+{
+       // ASIOInit()
+       ASIODriverInfo driverInfo;
+
+       // ASIOGetChannels()
+       long           inputChannels;
+       long           outputChannels;
+
+       // ASIOGetBufferSize()
+       long           minSize;
+       long           maxSize;
+       long           preferredSize;
+       long           granularity;
+
+       // ASIOGetSampleRate()
+       ASIOSampleRate sampleRate;
+
+       // ASIOOutputReady()
+       bool           postOutput;
+
+       // ASIOGetLatencies ()
+       long           inputLatency;
+       long           outputLatency;
+
+       // ASIOCreateBuffers ()
+       long inputBuffers;      // becomes number of actual created input buffers
+       long outputBuffers;     // becomes number of actual created output buffers
+       ASIOBufferInfo bufferInfos[kMaxInputChannels + kMaxOutputChannels]; // buffer info's
+
+       // ASIOGetChannelInfo()
+       ASIOChannelInfo channelInfos[kMaxInputChannels + kMaxOutputChannels]; // channel info's
+       // The above two arrays share the same indexing, as the data in them are linked together
+
+       // Information from ASIOGetSamplePosition()
+       // data is converted to double floats for easier use, however 64 bit integer can be used, too
+       double         nanoSeconds;
+       double         samples;
+       double         tcSamples;       // time code samples
+
+       // bufferSwitchTimeInfo()
+       ASIOTime       tInfo;                   // time info state
+       unsigned long  sysRefTime;      // system reference time, when bufferSwitch() was called
+
+       // Signal the end of processing in this example
+       bool           stopped;
+} DriverInfo;
+
+
+DriverInfo asioDriverInfo = {0};
+ASIOCallbacks asioCallbacks;
+
+//----------------------------------------------------------------------------------
+// some external references
+extern AsioDrivers* asioDrivers;
+bool loadAsioDriver(char *name);
+
+// internal prototypes (required for the Metrowerks CodeWarrior compiler)
+int main(int argc, char* argv[]);
+long init_asio_static_data (DriverInfo *asioDriverInfo);
+ASIOError create_asio_buffers (DriverInfo *asioDriverInfo);
+unsigned long get_sys_reference_time();
+
+
+// callback prototypes
+void bufferSwitch(long index, ASIOBool processNow);
+ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow);
+void sampleRateChanged(ASIOSampleRate sRate);
+long asioMessages(long selector, long value, void* message, double* opt);
+
+
+
+//----------------------------------------------------------------------------------
+long init_asio_static_data (DriverInfo *asioDriverInfo)
+{      // collect the informational data of the driver
+       // get the number of available channels
+       if(ASIOGetChannels(&asioDriverInfo->inputChannels, &asioDriverInfo->outputChannels) == ASE_OK)
+       {
+               printf ("ASIOGetChannels (inputs: %d, outputs: %d);\n", asioDriverInfo->inputChannels, asioDriverInfo->outputChannels);
+
+               // get the usable buffer sizes
+               if(ASIOGetBufferSize(&asioDriverInfo->minSize, &asioDriverInfo->maxSize, &asioDriverInfo->preferredSize, &asioDriverInfo->granularity) == ASE_OK)
+               {
+                       printf ("ASIOGetBufferSize (min: %d, max: %d, preferred: %d, granularity: %d);\n",
+                                        asioDriverInfo->minSize, asioDriverInfo->maxSize,
+                                        asioDriverInfo->preferredSize, asioDriverInfo->granularity);
+
+                       // get the currently selected sample rate
+                       if(ASIOGetSampleRate(&asioDriverInfo->sampleRate) == ASE_OK)
+                       {
+                               printf ("ASIOGetSampleRate (sampleRate: %f);\n", asioDriverInfo->sampleRate);
+                               if (asioDriverInfo->sampleRate <= 0.0 || asioDriverInfo->sampleRate > 96000.0)
+                               {
+                                       // Driver does not store it's internal sample rate, so set it to a know one.
+                                       // Usually you should check beforehand, that the selected sample rate is valid
+                                       // with ASIOCanSampleRate().
+                                       if(ASIOSetSampleRate(44100.0) == ASE_OK)
+                                       {
+                                               if(ASIOGetSampleRate(&asioDriverInfo->sampleRate) == ASE_OK)
+                                                       printf ("ASIOGetSampleRate (sampleRate: %f);\n", asioDriverInfo->sampleRate);
+                                               else
+                                                       return -6;
+                                       }
+                                       else
+                                               return -5;
+                               }
+
+                               // check wether the driver requires the ASIOOutputReady() optimization
+                               // (can be used by the driver to reduce output latency by one block)
+                               if(ASIOOutputReady() == ASE_OK)
+                                       asioDriverInfo->postOutput = true;
+                               else
+                                       asioDriverInfo->postOutput = false;
+                               printf ("ASIOOutputReady(); - %s\n", asioDriverInfo->postOutput ? "Supported" : "Not supported");
+
+                               return 0;
+                       }
+                       return -3;
+               }
+               return -2;
+       }
+       return -1;
+}
+
+
+//----------------------------------------------------------------------------------
+// conversion from 64 bit ASIOSample/ASIOTimeStamp to double float
+#if NATIVE_INT64
+       #define ASIO64toDouble(a)  (a)
+#else
+       const double twoRaisedTo32 = 4294967296.;
+       #define ASIO64toDouble(a)  ((a).lo + (a).hi * twoRaisedTo32)
+#endif
+
+ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow)
+{      // the actual processing callback.
+       // Beware that this is normally in a seperate thread, hence be sure that you take care
+       // about thread synchronization. This is omitted here for simplicity.
+       static long processedSamples = 0;
+
+       // store the timeInfo for later use
+       asioDriverInfo.tInfo = *timeInfo;
+
+       // get the time stamp of the buffer, not necessary if no
+       // synchronization to other media is required
+       if (timeInfo->timeInfo.flags & kSystemTimeValid)
+               asioDriverInfo.nanoSeconds = ASIO64toDouble(timeInfo->timeInfo.systemTime);
+       else
+               asioDriverInfo.nanoSeconds = 0;
+
+       if (timeInfo->timeInfo.flags & kSamplePositionValid)
+               asioDriverInfo.samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition);
+       else
+               asioDriverInfo.samples = 0;
+
+       if (timeInfo->timeCode.flags & kTcValid)
+               asioDriverInfo.tcSamples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples);
+       else
+               asioDriverInfo.tcSamples = 0;
+
+       // get the system reference time
+       asioDriverInfo.sysRefTime = get_sys_reference_time();
+
+#if WINDOWS && _DEBUG
+       // a few debug messages for the Windows device driver developer
+       // tells you the time when driver got its interrupt and the delay until the app receives
+       // the event notification.
+       static double last_samples = 0;
+       char tmp[128];
+       sprintf (tmp, "diff: %d / %d ms / %d ms / %d samples                 \n", asioDriverInfo.sysRefTime - (long)(asioDriverInfo.nanoSeconds / 1000000.0), asioDriverInfo.sysRefTime, (long)(asioDriverInfo.nanoSeconds / 1000000.0), (long)(asioDriverInfo.samples - last_samples));
+       OutputDebugString (tmp);
+       last_samples = asioDriverInfo.samples;
+#endif
+
+       // buffer size in samples
+       long buffSize = asioDriverInfo.preferredSize;
+
+       // perform the processing
+       for (int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++)
+       {
+               if (asioDriverInfo.bufferInfos[i].isInput == false)
+               {
+                       // OK do processing for the outputs only
+                       switch (asioDriverInfo.channelInfos[i].type)
+                       {
+                       case ASIOSTInt16LSB:
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2);
+                               break;
+                       case ASIOSTInt24LSB:            // used for 20 bits as well
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3);
+                               break;
+                       case ASIOSTInt32LSB:
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4);
+                               break;
+                       case ASIOSTFloat32LSB:          // IEEE 754 32 bit float, as found on Intel x86 architecture
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4);
+                               break;
+                       case ASIOSTFloat64LSB:          // IEEE 754 64 bit double float, as found on Intel x86 architecture
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 8);
+                               break;
+
+                               // 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
+                       case ASIOSTInt32LSB16:          // 32 bit data with 18 bit alignment
+                       case ASIOSTInt32LSB18:          // 32 bit data with 18 bit alignment
+                       case ASIOSTInt32LSB20:          // 32 bit data with 20 bit alignment
+                       case ASIOSTInt32LSB24:          // 32 bit data with 24 bit alignment
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4);
+                               break;
+
+                       case ASIOSTInt16MSB:
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2);
+                               break;
+                       case ASIOSTInt24MSB:            // used for 20 bits as well
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3);
+                               break;
+                       case ASIOSTInt32MSB:
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4);
+                               break;
+                       case ASIOSTFloat32MSB:          // IEEE 754 32 bit float, as found on Intel x86 architecture
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4);
+                               break;
+                       case ASIOSTFloat64MSB:          // IEEE 754 64 bit double float, as found on Intel x86 architecture
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 8);
+                               break;
+
+                               // 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
+                       case ASIOSTInt32MSB16:          // 32 bit data with 18 bit alignment
+                       case ASIOSTInt32MSB18:          // 32 bit data with 18 bit alignment
+                       case ASIOSTInt32MSB20:          // 32 bit data with 20 bit alignment
+                       case ASIOSTInt32MSB24:          // 32 bit data with 24 bit alignment
+                               memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 4);
+                               break;
+                       }
+               }
+       }
+
+       // finally if the driver supports the ASIOOutputReady() optimization, do it here, all data are in place
+       if (asioDriverInfo.postOutput)
+               ASIOOutputReady();
+
+       if (processedSamples >= asioDriverInfo.sampleRate * TEST_RUN_TIME)      // roughly measured
+               asioDriverInfo.stopped = true;
+       else
+               processedSamples += buffSize;
+
+       return 0L;
+}
+
+//----------------------------------------------------------------------------------
+void bufferSwitch(long index, ASIOBool processNow)
+{      // the actual processing callback.
+       // Beware that this is normally in a seperate thread, hence be sure that you take care
+       // about thread synchronization. This is omitted here for simplicity.
+
+       // as this is a "back door" into the bufferSwitchTimeInfo a timeInfo needs to be created
+       // though it will only set the timeInfo.samplePosition and timeInfo.systemTime fields and the according flags
+       ASIOTime  timeInfo;
+       memset (&timeInfo, 0, sizeof (timeInfo));
+
+       // get the time stamp of the buffer, not necessary if no
+       // synchronization to other media is required
+       if(ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime) == ASE_OK)
+               timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;
+
+       bufferSwitchTimeInfo (&timeInfo, index, processNow);
+}
+
+
+//----------------------------------------------------------------------------------
+void sampleRateChanged(ASIOSampleRate sRate)
+{
+       // do whatever you need to do if the sample rate changed
+       // usually this 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.
+       // You might have to update time/sample related conversion routines, etc.
+}
+
+//----------------------------------------------------------------------------------
+long asioMessages(long selector, long value, void* message, double* opt)
+{
+       // currently the parameters "value", "message" and "opt" are not used.
+       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.
+                       asioDriverInfo.stopped;  // In this sample the processing will just stop
+                       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 loose data because the Mutex was hold too long
+                       // by another thread.
+                       // However a driver can issue it in other situations, too.
+                       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.
+                       ret = 1L;
+                       break;
+               case kAsioEngineVersion:
+                       // return the supported ASIO version of the host application
+                       // If a host applications does not implement this selector, ASIO 1.0 is assumed
+                       // by the driver
+                       ret = 2L;
+                       break;
+               case kAsioSupportsTimeInfo:
+                       // informs the driver wether 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 = 1;
+                       break;
+               case kAsioSupportsTimeCode:
+                       // informs the driver wether 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;
+}
+
+
+//----------------------------------------------------------------------------------
+ASIOError create_asio_buffers (DriverInfo *asioDriverInfo)
+{      // create buffers for all inputs and outputs of the card with the 
+       // preferredSize from ASIOGetBufferSize() as buffer size
+       long i;
+       ASIOError result;
+
+       // fill the bufferInfos from the start without a gap
+       ASIOBufferInfo *info = asioDriverInfo->bufferInfos;
+
+       // prepare inputs (Though this is not necessaily required, no opened inputs will work, too
+       if (asioDriverInfo->inputChannels > kMaxInputChannels)
+               asioDriverInfo->inputBuffers = kMaxInputChannels;
+       else
+               asioDriverInfo->inputBuffers = asioDriverInfo->inputChannels;
+       for(i = 0; i < asioDriverInfo->inputBuffers; i++, info++)
+       {
+               info->isInput = ASIOTrue;
+               info->channelNum = i;
+               info->buffers[0] = info->buffers[1] = 0;
+       }
+
+       // prepare outputs
+       if (asioDriverInfo->outputChannels > kMaxOutputChannels)
+               asioDriverInfo->outputBuffers = kMaxOutputChannels;
+       else
+               asioDriverInfo->outputBuffers = asioDriverInfo->outputChannels;
+       for(i = 0; i < asioDriverInfo->outputBuffers; i++, info++)
+       {
+               info->isInput = ASIOFalse;
+               info->channelNum = i;
+               info->buffers[0] = info->buffers[1] = 0;
+       }
+
+       // create and activate buffers
+       result = ASIOCreateBuffers(asioDriverInfo->bufferInfos,
+               asioDriverInfo->inputBuffers + asioDriverInfo->outputBuffers,
+               asioDriverInfo->preferredSize, &asioCallbacks);
+       if (result == ASE_OK)
+       {
+               // now get all the buffer details, sample word length, name, word clock group and activation
+               for (i = 0; i < asioDriverInfo->inputBuffers + asioDriverInfo->outputBuffers; i++)
+               {
+                       asioDriverInfo->channelInfos[i].channel = asioDriverInfo->bufferInfos[i].channelNum;
+                       asioDriverInfo->channelInfos[i].isInput = asioDriverInfo->bufferInfos[i].isInput;
+                       result = ASIOGetChannelInfo(&asioDriverInfo->channelInfos[i]);
+                       if (result != ASE_OK)
+                               break;
+               }
+
+               if (result == ASE_OK)
+               {
+                       // get the input and output latencies
+                       // Latencies often are only valid after ASIOCreateBuffers()
+                       // (input latency is the age of the first sample in the currently returned audio block)
+                       // (output latency is the time the first sample in the currently returned audio block requires to get to the output)
+                       result = ASIOGetLatencies(&asioDriverInfo->inputLatency, &asioDriverInfo->outputLatency);
+                       if (result == ASE_OK)
+                               printf ("ASIOGetLatencies (input: %d, output: %d);\n", asioDriverInfo->inputLatency, asioDriverInfo->outputLatency);
+               }
+       }
+       return result;
+}
+
+int main(int argc, char* argv[])
+{
+       // load the driver, this will setup all the necessary internal data structures
+       if (loadAsioDriver (ASIO_DRIVER_NAME))
+       {
+               // initialize the driver
+               if (ASIOInit (&asioDriverInfo.driverInfo) == ASE_OK)
+               {
+                       printf ("asioVersion:   %d\n"
+                                       "driverVersion: %d\n"
+                                       "Name:          %s\n"
+                                       "ErrorMessage:  %s\n",
+                                       asioDriverInfo.driverInfo.asioVersion, asioDriverInfo.driverInfo.driverVersion,
+                                       asioDriverInfo.driverInfo.name, asioDriverInfo.driverInfo.errorMessage);
+                       if (init_asio_static_data (&asioDriverInfo) == 0)
+                       {
+                               // ASIOControlPanel(); you might want to check wether the ASIOControlPanel() can open
+
+                               // set up the asioCallback structure and create the ASIO data buffer
+                               asioCallbacks.bufferSwitch = &bufferSwitch;
+                               asioCallbacks.sampleRateDidChange = &sampleRateChanged;
+                               asioCallbacks.asioMessage = &asioMessages;
+                               asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo;
+                               if (create_asio_buffers (&asioDriverInfo) == ASE_OK)
+                               {
+                                       if (ASIOStart() == ASE_OK)
+                                       {
+                                               // Now all is up and running
+                                               fprintf (stdout, "\nASIO Driver started succefully.\n\n");
+                                               while (!asioDriverInfo.stopped)
+                                               {
+#if WINDOWS
+                                                       Sleep(100);     // goto sleep for 100 milliseconds
+#elif MAC
+                                                       unsigned long dummy;
+                                                       Delay (6, &dummy);
+#endif
+                                                       fprintf (stdout, "%d ms / %d ms / %d samples", asioDriverInfo.sysRefTime, (long)(asioDriverInfo.nanoSeconds / 1000000.0), (long)asioDriverInfo.samples);
+
+                                                       // create a more readable time code format (the quick and dirty way)
+                                                       double remainder = asioDriverInfo.tcSamples;
+                                                       long hours = (long)(remainder / (asioDriverInfo.sampleRate * 3600));
+                                                       remainder -= hours * asioDriverInfo.sampleRate * 3600;
+                                                       long minutes = (long)(remainder / (asioDriverInfo.sampleRate * 60));
+                                                       remainder -= minutes * asioDriverInfo.sampleRate * 60;
+                                                       long seconds = (long)(remainder / asioDriverInfo.sampleRate);
+                                                       remainder -= seconds * asioDriverInfo.sampleRate;
+                                                       fprintf (stdout, " / TC: %2.2d:%2.2d:%2.2d:%5.5d", (long)hours, (long)minutes, (long)seconds, (long)remainder);
+
+                                                       fprintf (stdout, "     \r");
+                                                       #if !MAC
+                                                       fflush (stdout);
+                                                       #endif
+                                               }
+                                               ASIOStop();
+                                       }
+                                       ASIODisposeBuffers();
+                               }
+                       }
+                       ASIOExit();
+               }
+               asioDrivers->removeCurrentDriver();
+       }
+       return 0;
+}
+
+
+unsigned long get_sys_reference_time()
+{      // get the system reference time
+#if WINDOWS
+       return timeGetTime();
+#elif MAC
+static const double twoRaisedTo32 = 4294967296.;
+       UnsignedWide ys;
+       Microseconds(&ys);
+       double r = ((double)ys.hi * twoRaisedTo32 + (double)ys.lo);
+       return (unsigned long)(r / 1000.);
+#endif
+}
diff --git a/src/hostapi/asio/ASIOSDK/host/sample/hostsample.dsp b/src/hostapi/asio/ASIOSDK/host/sample/hostsample.dsp
new file mode 100644 (file)
index 0000000..1c38f06
--- /dev/null
@@ -0,0 +1,134 @@
+# Microsoft Developer Studio Project File - Name="hostsample" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=hostsample - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "hostsample.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "hostsample.mak" CFG="hostsample - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "hostsample - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "hostsample - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "hostsample - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../../common" /I "../../host" /I "../../host/pc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  winmm.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "hostsample - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../common" /I "../../host" /I "../../host/pc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "hostsample - Win32 Release"
+# Name "hostsample - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\common\asio.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\asiodrivers.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\pc\asiolist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\hostsample.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\common\asio.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\asiodrivers.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\pc\asiolist.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\ginclude.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\ReadMe.txt
+# End Source File
+# End Target
+# End Project
diff --git a/src/hostapi/asio/ASIOSDK/host/sample/hostsample.vcproj b/src/hostapi/asio/ASIOSDK/host/sample/hostsample.vcproj
new file mode 100644 (file)
index 0000000..130fc5c
--- /dev/null
@@ -0,0 +1,571 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8.00"
+       Name="hostsample"
+       ProjectGUID="{1E10ECB0-0666-474F-A010-660E7CE9DC00}"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+               <Platform
+                       Name="x64"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="1"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       CharacterSet="2"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               TypeLibraryName=".\Release/hostsample.tlb"
+                               HeaderFileName=""
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               InlineFunctionExpansion="1"
+                               AdditionalIncludeDirectories="../../common,../../host,../../host/pc"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
+                               StringPooling="true"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               PrecompiledHeaderFile=".\Release/hostsample.pch"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="NDEBUG"
+                               Culture="2057"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
+                               OutputFile="$(PlatformName)\$(ConfigurationName)\hostsample.exe"
+                               LinkIncremental="1"
+                               SuppressStartupBanner="true"
+                               SubSystem="1"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCWebDeploymentTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|x64"
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="1"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       CharacterSet="2"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               TargetEnvironment="3"
+                               TypeLibraryName=".\Release/hostsample.tlb"
+                               HeaderFileName=""
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               InlineFunctionExpansion="1"
+                               AdditionalIncludeDirectories="../../common,../../host,../../host/pc"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
+                               StringPooling="true"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               PrecompiledHeaderFile=".\Release/hostsample.pch"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="NDEBUG"
+                               Culture="2057"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
+                               OutputFile="$(PlatformName)\$(ConfigurationName)\hostsample.exe"
+                               LinkIncremental="1"
+                               SuppressStartupBanner="true"
+                               SubSystem="1"
+                               TargetMachine="17"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCWebDeploymentTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="1"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       CharacterSet="2"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               TypeLibraryName=".\Debug/hostsample.tlb"
+                               HeaderFileName=""
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="../../common,../../host,../../host/pc"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="1"
+                               PrecompiledHeaderFile=".\Debug/hostsample.pch"
+                               BrowseInformation="1"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="_DEBUG"
+                               Culture="2057"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
+                               OutputFile="$(PlatformName)\$(ConfigurationName)\hostsample.exe"
+                               LinkIncremental="2"
+                               SuppressStartupBanner="true"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCWebDeploymentTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|x64"
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="1"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       CharacterSet="2"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               TargetEnvironment="3"
+                               TypeLibraryName=".\Debug/hostsample.tlb"
+                               HeaderFileName=""
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="../../common,../../host,../../host/pc"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="1"
+                               PrecompiledHeaderFile=".\Debug/hostsample.pch"
+                               BrowseInformation="1"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="_DEBUG"
+                               Culture="2057"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
+                               OutputFile="$(PlatformName)\$(ConfigurationName)\hostsample.exe"
+                               LinkIncremental="2"
+                               SuppressStartupBanner="true"
+                               GenerateDebugInformation="true"
+                               SubSystem="1"
+                               TargetMachine="17"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCWebDeploymentTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+                       >
+                       <File
+                               RelativePath="..\..\common\asio.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\asiodrivers.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="..\pc\asiolist.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath="hostsample.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl"
+                       >
+                       <File
+                               RelativePath="..\..\common\asio.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\asiodrivers.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\pc\asiolist.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\ginclude.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+                       >
+               </Filter>
+               <File
+                       RelativePath="ReadMe.txt"
+                       >
+               </File>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/src/hostapi/asio/ASIOSDK/readme.txt b/src/hostapi/asio/ASIOSDK/readme.txt
new file mode 100644 (file)
index 0000000..35f62e6
--- /dev/null
@@ -0,0 +1,55 @@
+ASIO 2.3 SDK Contents
+---------------------
+
+readme.txt                             - this file
+changes.txt                            - contains change information between
+                                         SDK releases
+ASIO SDK 2.3.pdf                       - ASIO SDK 2.3 specification
+Steinberg ASIO Licensing Agreement.pdf - Licencing Agreement
+
+common:
+asio.h                 - ASIO C definition
+iasiodrv.h             - interface definition for the ASIO driver class
+asio.cpp               - asio host interface (not used on Mac)
+asiodrvr.h
+asiodrvr.cpp           - ASIO driver class base definition
+combase.h
+combase.cpp            - COM base definitions (PC only)
+dllentry.cpp           - DLL functions (PC only)
+register.cpp           - driver self registration functionality
+wxdebug.h
+debugmessage.cpp       - some debugging help
+
+host:
+asiodrivers.h
+asiodrivers.cpp         - ASIO driver managment (enumeration and instantiation)
+ASIOConvertSamples.h
+ASIOConvertSamples.cpp  - sample data format conversion class
+ginclude.h              - platform specific definitions
+
+host/mac:
+asioshlib.cpp          - asio.cpp for the Mac, resolves the symbols
+codefragments.hpp
+codefragments.cpp      - code fragment loader
+
+host/pc:
+asiolist.h
+asiolist.cpp           - instantiates an ASIO driver via the COM model
+
+host/sample:
+hostsample.cpp         - a simple console app which shows ASIO hosting
+hostsample.dsp         - MSVC++ 5.0 project
+hostsample.vcproj      - Visual Studio 2005 project (32 and 64 bit targets)
+
+driver/asiosample:
+asiosmpl.h
+asiosmpl.cpp           - ASIO 2.0 sample driver
+wintimer.cpp           - bufferSwitch() wakeup thread (Windows)
+asiosample.def         - Windows DLL module export definition
+mactimer.cpp           - bufferSwitch() wakeup thread (Macintosh)
+macnanosecs.cpp        - Macintosh system reference time
+makesamp.cpp           - Macintosh driver object instantiation
+
+driver/asiosample/asiosample:
+asiosample.dsp         - MSVC++ 5.0 project
+asiosample.vcproj      - Visual Studio 2005 project (32 and 64 bit targets)
diff --git a/src/hostapi/asio/asiosdk2.3.zip b/src/hostapi/asio/asiosdk2.3.zip
new file mode 100644 (file)
index 0000000..fc513a0
Binary files /dev/null and b/src/hostapi/asio/asiosdk2.3.zip differ