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