Updated asio SDK files.

This commit is contained in:
Gary Scavone
2021-11-17 21:00:06 -05:00
parent dec667bab5
commit 6a6a9cdfbe
6 changed files with 347 additions and 293 deletions

View File

@@ -2,7 +2,7 @@ The Synthesis ToolKit in C++ (STK)
By Perry R. Cook and Gary P. Scavone, 1995--2021. By Perry R. Cook and Gary P. Scavone, 1995--2021.
v.4.6.2 (16 November 2021) v.4.6.2 (17 November 2021)
- see github site for complete details (github.com/thestk/stk) - see github site for complete details (github.com/thestk/stk)
- bug fixes in LentPitShift and Granulate classes - bug fixes in LentPitShift and Granulate classes
- Makefile fixes - Makefile fixes

View File

@@ -1,6 +1,6 @@
/*! \page download Download and Release Notes /*! \page download Download and Release Notes
\section down Download Version 4.6.2 (16 November 2021): \section down Download Version 4.6.2 (17 November 2021):
- <A HREF="http://ccrma.stanford.edu/software/stk/release/stk-4.6.2.tar.gz">Source distribution</A> - <A HREF="http://ccrma.stanford.edu/software/stk/release/stk-4.6.2.tar.gz">Source distribution</A>

View File

@@ -3,12 +3,14 @@
/* /*
Steinberg Audio Stream I/O API Steinberg Audio Stream I/O API
(c) 1997 - 2005, Steinberg Media Technologies GmbH (c) 1997 - 2013, Steinberg Media Technologies GmbH
ASIO Interface Specification v 2.1 ASIO Interface Specification v 2.3
2005 - Added support for DSD sample data (in cooperation with Sony) 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: basic concept is an i/o synchronous double-buffer scheme:
@@ -164,13 +166,13 @@ enum {
// DSD operation and buffer layout // DSD operation and buffer layout
// Definition by Steinberg/Sony Oxford. // Definition by Steinberg/Sony Oxford.
// //
// We have tried to treat DSD as PCM and so keep a consistant structure across // We have tried to treat DSD as PCM and so keep a consistent structure across
// the ASIO interface. // the ASIO interface.
// //
// DSD's sample rate is normally referenced as a multiple of 44.1Khz, so // 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 // the standard sample rate is referred to as 64Fs (or 2.8224Mhz). We looked
// at making a special case for DSD and adding a field to the ASIOFuture that // 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 // would allow the user to select the Over Sampleing Rate (OSR) as a separate
// entity but decided in the end just to treat it as a simple value of // 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. // 2.8224Mhz and use the standard interface to set it.
// //
@@ -489,7 +491,7 @@ ASIOError ASIOInit(ASIODriverInfo *info);
info: pointer to an ASIODriver structure: info: pointer to an ASIODriver structure:
- asioVersion: - asioVersion:
- on input, the host version. *** Note *** this is 0 for earlier asio - on input, the host version. *** Note *** this is 0 for earlier asio
implementations, and the asioMessage callback is implemeted implementations, and the asioMessage callback is implemented
only if asioVersion is 2 or greater. sorry but due to a design fault 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 :-( the driver doesn't have access to the host version in ASIOInit :-(
added selector for host (engine) version in the asioMessage callback added selector for host (engine) version in the asioMessage callback
@@ -502,7 +504,7 @@ ASIOError ASIOInit(ASIODriverInfo *info);
- version: on return, the driver version (format is driver specific) - version: on return, the driver version (format is driver specific)
- name: on return, a null-terminated string containing the driver's name - name: on return, a null-terminated string containing the driver's name
- error message: on return, should contain a user message describing - error message: on return, should contain a user message describing
the type of error that occured during ASIOInit(), if any. the type of error that occurred during ASIOInit(), if any.
- sysRef: platform specific - sysRef: platform specific
Returns: Returns:
If neither input nor output is present ASE_NotPresent If neither input nor output is present ASE_NotPresent
@@ -607,9 +609,9 @@ ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);
is most commonly done, but should be avoided), the output latency 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 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, 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 and to achieve less latency, it is highly recommended to try to avoid
copying (this is also why the driver is the owner of the buffers). To 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 summarize, the minimum i/o latency can be achieved if the input buffer
is processed by the host into the output buffer which will physically 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 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 the bufferSwitch() callback to be accessed for each time slice in order
@@ -624,7 +626,7 @@ ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, l
Returns min, max, and preferred buffer sizes for input/output Returns min, max, and preferred buffer sizes for input/output
Parameter: Parameter:
minSize will hold the minimum buffer size minSize will hold the minimum buffer size
maxSize will hold the maxium possible buffer size maxSize will hold the maximum possible buffer size
preferredSize will hold the preferred buffer size (a size which preferredSize will hold the preferred buffer size (a size which
best fits performance and hardware requirements) best fits performance and hardware requirements)
granularity will hold the granularity at which buffer sizes granularity will hold the granularity at which buffer sizes
@@ -694,11 +696,11 @@ ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);
- associatedInputChannel: the first channel of an associated - associatedInputChannel: the first channel of an associated
input group, if any. input group, if any.
- associatedGroup: the group index of that channel. - associatedGroup: the group index of that channel.
groups of channels are defined to seperate for groups of channels are defined to separate for
instance analog, S/PDIF, AES/EBU, ADAT connectors etc, instance analog, S/PDIF, AES/EBU, ADAT connectors etc,
when present simultaniously. Note that associated channel when present simultaneously. Note that associated channel
is enumerated according to numInputs/numOutputs, means it is enumerated according to numInputs/numOutputs, means it
is independant from a group (see also ASIOGetChannelInfo()) is independent from a group (see also ASIOGetChannelInfo())
inputs are associated to a clock if the physical connection inputs are associated to a clock if the physical connection
transfers both data and clock (like S/PDIF, AES/EBU, or transfers both data and clock (like S/PDIF, AES/EBU, or
ADAT inputs). if there is no input channel associated with ADAT inputs). if there is no input channel associated with
@@ -774,7 +776,7 @@ typedef struct ASIOChannelInfo
ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info); ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);
/* Purpose: /* Purpose:
retreive information about the nature of a channel retrieve information about the nature of a channel
Parameter: Parameter:
info: pointer to a ASIOChannelInfo structure with info: pointer to a ASIOChannelInfo structure with
- channel: on input, the channel index of the channel in question. - channel: on input, the channel index of the channel in question.
@@ -784,7 +786,7 @@ ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);
belongs to. For drivers which support different types of belongs to. For drivers which support different types of
channels, like analog, S/PDIF, AES/EBU, ADAT etc interfaces, channels, like analog, S/PDIF, AES/EBU, ADAT etc interfaces,
there should be a reasonable grouping of these types. Groups there should be a reasonable grouping of these types. Groups
are always independant form a channel index, that is, a channel are always independent form a channel index, that is, a channel
index always counts from 0 to numInputs/numOutputs regardless index always counts from 0 to numInputs/numOutputs regardless
of the group it may belong to. of the group it may belong to.
There will always be at least one group (group 0). Please There will always be at least one group (group 0). Please
@@ -888,9 +890,9 @@ ASIOError ASIOFuture(long selector, void *params);
selector: operation Code as to be defined. zero is reserved for selector: operation Code as to be defined. zero is reserved for
testing purposes. testing purposes.
params: depends on the selector; usually pointer to a structure params: depends on the selector; usually pointer to a structure
for passing and retreiving any type and amount of parameters. for passing and retrieving any type and amount of parameters.
Returns: Returns:
the return value is also selector dependant. if the selector the return value is also selector dependent. if the selector
is unknown, ASE_InvalidParameter should be returned to prevent is unknown, ASE_InvalidParameter should be returned to prevent
further calls with this selector. on success, ASE_SUCCESS further calls with this selector. on success, ASE_SUCCESS
must be returned (note: ASE_OK is *not* sufficient!) must be returned (note: ASE_OK is *not* sufficient!)
@@ -916,13 +918,19 @@ enum
kAsioCanInputMeter, kAsioCanInputMeter,
kAsioCanOutputGain, kAsioCanOutputGain,
kAsioCanOutputMeter, kAsioCanOutputMeter,
kAsioOptionalOne,
// DSD support // DSD support
// The following extensions are required to allow switching // The following extensions are required to allow switching
// and control of the DSD subsystem. // and control of the DSD subsystem.
kAsioSetIoFormat = 0x23111961, /* ASIOIoFormat * in params. */ kAsioSetIoFormat = 0x23111961, /* ASIOIoFormat * in params. */
kAsioGetIoFormat = 0x23111983, /* ASIOIoFormat * in params. */ kAsioGetIoFormat = 0x23111983, /* ASIOIoFormat * in params. */
kAsioCanDoIoFormat = 0x23112004, /* 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 typedef struct ASIOInputMonitor
@@ -1003,6 +1011,14 @@ typedef struct ASIOIoFormat_s
char future[512-sizeof(ASIOIoFormatType)]; char future[512-sizeof(ASIOIoFormatType)];
} ASIOIoFormat; } 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); ASIOError ASIOOutputReady(void);
/* Purpose: /* Purpose:
@@ -1027,14 +1043,14 @@ ASIOError ASIOOutputReady(void);
None None
Returns: Returns:
only if the above mentioned scenario is given, and a reduction only if the above mentioned scenario is given, and a reduction
of output latency can be acheived by this mechanism, should of output latency can be achieved by this mechanism, should
ASE_OK be returned. otherwise (and usually), ASE_NotPresent ASE_OK be returned. otherwise (and usually), ASE_NotPresent
should be returned in order to prevent further calls to this should be returned in order to prevent further calls to this
function. note that the host may want to determine if it is function. note that the host may want to determine if it is
to use this when the system is not yet fully initialized, so to use this when the system is not yet fully initialized, so
ASE_OK should always be returned if the mechanism makes sense. ASE_OK should always be returned if the mechanism makes sense.
Notes: Notes:
please remeber to adjust ASIOGetLatencies() according to please remember to adjust ASIOGetLatencies() according to
whether ASIOOutputReady() was ever called or not, if your whether ASIOOutputReady() was ever called or not, if your
driver supports this scenario. driver supports this scenario.
also note that the engine may fail to call ASIO_OutputReady() also note that the engine may fail to call ASIO_OutputReady()

View File

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

View File

@@ -1,7 +1,7 @@
#ifndef __asiosys__ #ifndef __asiosys__
#define __asiosys__ #define __asiosys__
#ifdef WIN32 #if defined(_WIN32) || defined(_WIN64)
#undef MAC #undef MAC
#define PPC 0 #define PPC 0
#define WINDOWS 1 #define WINDOWS 1

View File

@@ -356,7 +356,7 @@ extern IASIO* theAsioDriver;
IASIOThiscallResolver IASIOThiscallResolver::instance; IASIOThiscallResolver IASIOThiscallResolver::instance;
// Constructor called to initialize static Singleton instance above. Note that // Constructor called to initialize static Singleton instance above. Note that
// it is important not to clear that_ incase it has already been set by the call // it is important not to clear that_ in case it has already been set by the call
// to placement new in ASIOInit(). // to placement new in ASIOInit().
IASIOThiscallResolver::IASIOThiscallResolver() IASIOThiscallResolver::IASIOThiscallResolver()
{ {