To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at https://github.com/sonic-visualiser/sv-dependency-builds .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / src / portaudio_20161030_catalina_patch / src / hostapi / asio / iasiothiscallresolver.h @ 162:d43aab368df9

History | View | Annotate | Download (9.16 KB)

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

    
108
#ifndef included_iasiothiscallresolver_h
109
#define included_iasiothiscallresolver_h
110

    
111
// We only need IASIOThiscallResolver at all if we are on Win32. For other
112
// platforms we simply bypass the IASIOThiscallResolver definition to allow us
113
// to be safely #include'd whatever the platform to keep client code portable
114
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN64)
115

    
116

    
117
// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver
118
// is not used.
119
#if !defined(_MSC_VER)
120

    
121

    
122
// The following is in order to ensure that this header is only included after
123
// the other ASIO headers (except for the case of iasiothiscallresolver.cpp).
124
// We need to do this because IASIOThiscallResolver works by eclipsing the
125
// original definition of ASIOInit() with a macro (see below).
126
#if !defined(iasiothiscallresolver_sourcefile)
127
        #if !defined(__ASIO_H)
128
        #error iasiothiscallresolver.h must be included AFTER asio.h
129
        #endif
130
#endif
131

    
132
#include <windows.h>
133
#include <asiodrvr.h> /* From ASIO SDK */
134

    
135

    
136
class IASIOThiscallResolver : public IASIO {
137
private:
138
        IASIO* that_; // Points to the real IASIO
139

    
140
        static IASIOThiscallResolver instance; // Singleton instance
141

    
142
        // Constructors - declared private so construction is limited to
143
    // our Singleton instance
144
    IASIOThiscallResolver();
145
        IASIOThiscallResolver(IASIO* that);
146
public:
147

    
148
    // Methods from the IUnknown interface. We don't fully implement IUnknown
149
    // because the ASIO SDK never calls these methods through theAsioDriver ptr.
150
    // These methods are implemented as assert(false).
151
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv);
152
    virtual ULONG STDMETHODCALLTYPE AddRef();
153
    virtual ULONG STDMETHODCALLTYPE Release();
154

    
155
    // Methods from the IASIO interface, implemented as forwarning calls to that.
156
        virtual ASIOBool init(void *sysHandle);
157
        virtual void getDriverName(char *name);
158
        virtual long getDriverVersion();
159
        virtual void getErrorMessage(char *string);
160
        virtual ASIOError start();
161
        virtual ASIOError stop();
162
        virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);
163
        virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);
164
        virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);
165
        virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);
166
        virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);
167
        virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);
168
        virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);
169
        virtual ASIOError setClockSource(long reference);
170
        virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp);
171
        virtual ASIOError getChannelInfo(ASIOChannelInfo *info);
172
        virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks);
173
        virtual ASIOError disposeBuffers();
174
        virtual ASIOError controlPanel();
175
        virtual ASIOError future(long selector,void *opt);
176
        virtual ASIOError outputReady();
177

    
178
    // Class method, see ASIOInit() macro below.
179
    static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit
180
};
181

    
182

    
183
// Replace calls to ASIOInit with our interposing version.
184
// This macro enables us to perform thiscall resolution simply by #including
185
// <iasiothiscallresolver.h> after the asio #includes (this file _must_ be
186
// included _after_ the asio #includes)
187

    
188
#define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name))
189

    
190

    
191
#endif /* !defined(_MSC_VER) */
192

    
193
#endif /* Win32 */
194

    
195
#endif /* included_iasiothiscallresolver_h */
196

    
197