LMMS
Loading...
Searching...
No Matches
iasiothiscallresolver.h
Go to the documentation of this file.
1// ****************************************************************************
2//
3// Changed: I have modified this file slightly (includes) to work with
4// RtAudio. RtAudio.cpp must include this file after asio.h.
5//
6// File: IASIOThiscallResolver.h
7// Description: The IASIOThiscallResolver class implements the IASIO
8// interface and acts as a proxy to the real IASIO interface by
9// calling through its vptr table using the thiscall calling
10// convention. To put it another way, we interpose
11// IASIOThiscallResolver between ASIO SDK code and the driver.
12// This is necessary because most non-Microsoft compilers don't
13// implement the thiscall calling convention used by IASIO.
14//
15// iasiothiscallresolver.cpp contains the background of this
16// problem plus a technical description of the vptr
17// manipulations.
18//
19// In order to use this mechanism one simply has to add
20// iasiothiscallresolver.cpp to the list of files to compile
21// and #include <iasiothiscallresolver.h>
22//
23// Note that this #include must come after the other ASIO SDK
24// #includes, for example:
25//
26// #include <windows.h>
27// #include <asiosys.h>
28// #include <asio.h>
29// #include <asiodrivers.h>
30// #include <iasiothiscallresolver.h>
31//
32// Actually the important thing is to #include
33// <iasiothiscallresolver.h> after <asio.h>. We have
34// incorporated a test to enforce this ordering.
35//
36// The code transparently takes care of the interposition by
37// using macro substitution to intercept calls to ASIOInit()
38// and ASIOExit(). We save the original ASIO global
39// "theAsioDriver" in our "that" variable, and then set
40// "theAsioDriver" to equal our IASIOThiscallResolver instance.
41//
42// Whilst this method of resolving the thiscall problem requires
43// the addition of #include <iasiothiscallresolver.h> to client
44// code it has the advantage that it does not break the terms
45// of the ASIO licence by publishing it. We are NOT modifying
46// any Steinberg code here, we are merely implementing the IASIO
47// interface in the same way that we would need to do if we
48// wished to provide an open source ASIO driver.
49//
50// For compilation with MinGW -lole32 needs to be added to the
51// linker options. For BORLAND, linking with Import32.lib is
52// sufficient.
53//
54// The dependencies are with: CoInitialize, CoUninitialize,
55// CoCreateInstance, CLSIDFromString - used by asiolist.cpp
56// and are required on Windows whether ThiscallResolver is used
57// or not.
58//
59// Searching for the above strings in the root library path
60// of your compiler should enable the correct libraries to be
61// identified if they aren't immediately obvious.
62//
63// Note that the current implementation of IASIOThiscallResolver
64// is not COM compliant - it does not correctly implement the
65// IUnknown interface. Implementing it is not necessary because
66// it is not called by parts of the ASIO SDK which call through
67// theAsioDriver ptr. The IUnknown methods are implemented as
68// assert(false) to ensure that the code fails if they are
69// ever called.
70// Restrictions: None. Public Domain & Open Source distribute freely
71// You may use IASIOThiscallResolver commercially as well as
72// privately.
73// You the user assume the responsibility for the use of the
74// files, binary or text, and there is no guarantee or warranty,
75// expressed or implied, including but not limited to the
76// implied warranties of merchantability and fitness for a
77// particular purpose. You assume all responsibility and agree
78// to hold no entity, copyright holder or distributors liable
79// for any loss of data or inaccurate representations of data
80// as a result of using IASIOThiscallResolver.
81// Version: 1.4 Added separate macro CALL_THISCALL_1_DOUBLE from
82// Andrew Baldwin, and volatile for whole gcc asm blocks,
83// both for compatibility with newer gcc versions. Cleaned up
84// Borland asm to use one less register.
85// 1.3 Switched to including assert.h for better compatibility.
86// Wrapped entire .h and .cpp contents with a check for
87// _MSC_VER to provide better compatibility with MS compilers.
88// Changed Singleton implementation to use static instance
89// instead of freestore allocated instance. Removed ASIOExit
90// macro as it is no longer needed.
91// 1.2 Removed semicolons from ASIOInit and ASIOExit macros to
92// allow them to be embedded in expressions (if statements).
93// Cleaned up some comments. Removed combase.c dependency (it
94// doesn't compile with BCB anyway) by stubbing IUnknown.
95// 1.1 Incorporated comments from Ross Bencina including things
96// such as changing name from ThiscallResolver to
97// IASIOThiscallResolver, tidying up the constructor, fixing
98// a bug in IASIOThiscallResolver::ASIOExit() and improving
99// portability through the use of conditional compilation
100// 1.0 Initial working version.
101// Created: 6/09/2003
102// Authors: Fraser Adams
103// Ross Bencina
104// Rene G. Ceballos
105// Martin Fay
106// Antti Silvast
107// Andrew Baldwin
108//
109// ****************************************************************************
110
111
112#ifndef included_iasiothiscallresolver_h
113#define included_iasiothiscallresolver_h
114
115// We only need IASIOThiscallResolver at all if we are on Win32. For other
116// platforms we simply bypass the IASIOThiscallResolver definition to allow us
117// to be safely #include'd whatever the platform to keep client code portable
118//#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
119#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN64)
120
121
122// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver
123// is not used.
124#if !defined(_MSC_VER)
125
126
127// The following is in order to ensure that this header is only included after
128// the other ASIO headers (except for the case of iasiothiscallresolver.cpp).
129// We need to do this because IASIOThiscallResolver works by eclipsing the
130// original definition of ASIOInit() with a macro (see below).
131#if !defined(iasiothiscallresolver_sourcefile)
132 #if !defined(__ASIO_H)
133 #error iasiothiscallresolver.h must be included AFTER asio.h
134 #endif
135#endif
136
137#include <windows.h>
138#include "iasiodrv.h" /* From ASIO SDK */
139
140
141class IASIOThiscallResolver : public IASIO {
142private:
143 IASIO* that_; // Points to the real IASIO
144
145 static IASIOThiscallResolver instance; // Singleton instance
146
147 // Constructors - declared private so construction is limited to
148 // our Singleton instance
149 IASIOThiscallResolver();
150 IASIOThiscallResolver(IASIO* that);
151public:
152
153 // Methods from the IUnknown interface. We don't fully implement IUnknown
154 // because the ASIO SDK never calls these methods through theAsioDriver ptr.
155 // These methods are implemented as assert(false).
156 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv);
157 virtual ULONG STDMETHODCALLTYPE AddRef();
158 virtual ULONG STDMETHODCALLTYPE Release();
159
160 // Methods from the IASIO interface, implemented as forwarning calls to that.
161 virtual ASIOBool init(void *sysHandle);
162 virtual void getDriverName(char *name);
163 virtual long getDriverVersion();
164 virtual void getErrorMessage(char *string);
165 virtual ASIOError start();
166 virtual ASIOError stop();
167 virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);
168 virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);
169 virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);
170 virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);
171 virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);
172 virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);
173 virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);
174 virtual ASIOError setClockSource(long reference);
177 virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks);
178 virtual ASIOError disposeBuffers();
179 virtual ASIOError controlPanel();
180 virtual ASIOError future(long selector,void *opt);
181 virtual ASIOError outputReady();
182
183 // Class method, see ASIOInit() macro below.
184 static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit
185};
186
187
188// Replace calls to ASIOInit with our interposing version.
189// This macro enables us to perform thiscall resolution simply by #including
190// <iasiothiscallresolver.h> after the asio #includes (this file _must_ be
191// included _after_ the asio #includes)
192
193#define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name))
194
195
196#endif /* !defined(_MSC_VER) */
197
198#endif /* Win32 */
199
200#endif /* included_iasiothiscallresolver_h */
201
202
uint getBufferSize()
Definition DistrhoUtils.cpp:153
ASIOError ASIOInit(ASIODriverInfo *info)
Definition asio.cpp:45
struct ASIOChannelInfo ASIOChannelInfo
struct ASIOCallbacks ASIOCallbacks
struct ASIOClockSource ASIOClockSource
struct ASIOSampleRate ASIOSampleRate
struct ASIOBufferInfo ASIOBufferInfo
struct ASIODriverInfo ASIODriverInfo
struct ASIOSamples ASIOSamples
struct ASIOTimeStamp ASIOTimeStamp
long ASIOBool
Definition asio.h:121
long ASIOError
Definition asio.h:208
static const char * name
Definition pugl.h:1582
virtual void getDriverName(char *name)=0
virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)=0
virtual long getDriverVersion()=0
virtual ASIOError controlPanel()=0
virtual ASIOError outputReady()=0
virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources)=0
virtual ASIOError future(long selector, void *opt)=0
virtual ASIOError disposeBuffers()=0
virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks)=0
virtual ASIOError getChannelInfo(ASIOChannelInfo *info)=0
virtual void getErrorMessage(char *string)=0
virtual ASIOError stop()=0
virtual ASIOError canSampleRate(ASIOSampleRate sampleRate)=0
virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels)=0
interface IASIO IASIO
Definition iasiodrv.h:9
virtual ASIOError getLatencies(long *inputLatency, long *outputLatency)=0
virtual ASIOError start()=0
virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate)=0
virtual ASIOError setSampleRate(ASIOSampleRate sampleRate)=0
virtual ASIOError setClockSource(long reference)=0
struct backing_store_struct * info
Definition jmemsys.h:183
signed int HRESULT
Definition swell-types.h:181
unsigned int ULONG
Definition swell-types.h:183
ZCONST uch * init
Definition extract.c:2392