/[svn]/linuxsampler/trunk/src/drivers/audio/iasiothiscallresolver.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/drivers/audio/iasiothiscallresolver.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1808 - (show annotations) (download) (as text)
Sun Dec 14 15:43:18 2008 UTC (15 years, 4 months ago) by persson
File MIME type: text/x-c++hdr
File size: 9589 byte(s)
* fixes for building with newer MinGW versions
* fix for building with bison 2.4 (#111)
* fix for crash when running gigedit as a plugin

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

  ViewVC Help
Powered by ViewVC