Files
jens 562920dd85 Initial import
git-svn-id: http://moon:8086/svn/software/trunk/libsrc/asiosdk2@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
2014-07-19 07:44:42 +00:00

1 line
8.5 KiB
C++
Executable File

// 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