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