├── .gitignore ├── ASIOSDK2.3 ├── ASIO SDK 2.3.pdf ├── Steinberg ASIO Licensing Agreement.pdf ├── asio │ ├── asio.dsw │ └── asio.opt ├── changes.txt ├── common │ ├── asio.cpp │ ├── asio.h │ ├── asiodrvr.cpp │ ├── asiodrvr.h │ ├── asiosys.h │ ├── combase.cpp │ ├── combase.h │ ├── debugmessage.cpp │ ├── dllentry.cpp │ ├── iasiodrv.h │ ├── register.cpp │ └── wxdebug.h ├── driver │ └── asiosample │ │ ├── asiosample.def │ │ ├── asiosample.txt │ │ ├── asiosample │ │ ├── asiosample.dsp │ │ └── asiosample.vcproj │ │ ├── asiosmpl.cpp │ │ ├── asiosmpl.h │ │ ├── macnanosecs.cpp │ │ ├── mactimer.cpp │ │ ├── makesamp.cpp │ │ └── wintimer.cpp ├── host │ ├── ASIOConvertSamples.cpp │ ├── ASIOConvertSamples.h │ ├── asiodrivers.cpp │ ├── asiodrivers.h │ ├── ginclude.h │ ├── mac │ │ ├── asioshlib.cpp │ │ ├── codefragments.cpp │ │ └── codefragments.hpp │ ├── pc │ │ ├── asiolist.cpp │ │ └── asiolist.h │ └── sample │ │ ├── hostsample.cpp │ │ ├── hostsample.dsp │ │ └── hostsample.vcproj └── readme.txt ├── Feature-Extractor.jucer ├── README.md └── Source ├── AnalyserTrack.h ├── AnalyserTrackController.h ├── AudioAnalysis.h ├── AudioDataCollector.h ├── AudioFeatures.h ├── AudioFeaturesListComponent.h ├── AudioFilePlayer.h ├── AudioFileTransportComponent.h ├── AudioSourceSelectorComboBox.h ├── CustomAudioSettingsComponent.cpp ├── CustomAudioSettingsComponent.h ├── CustomChannelSelectorController.h ├── CustomChannelSelectorPanel.h ├── FeatureExtractorLookAndFeel.h ├── HarmonicCharacteristics.h ├── LiveScrollingAudioDisplay.h ├── Main.cpp ├── MainComponent.cpp ├── MainView.h ├── OSCFeatureAnalysisOutput.h ├── OSCSettings.h ├── PitchAnalyser.h ├── PitchEstimationVisualiser.h ├── RealTimeAnalyser.h ├── RealTimeAudioAnalysis.h ├── SpectralCharacteristics.h └── include.h /.gitignore: -------------------------------------------------------------------------------- 1 | Builds 2 | JuceLibraryCode 3 | .DS_Store 4 | core 5 | *.swp 6 | *.swo 7 | *.log 8 | *~ 9 | 10 | -------------------------------------------------------------------------------- /ASIOSDK2.3/ASIO SDK 2.3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeanSoraghan/Feature-Extractor/84db22e758671a9d91c9b72f99689b11c2cb863c/ASIOSDK2.3/ASIO SDK 2.3.pdf -------------------------------------------------------------------------------- /ASIOSDK2.3/Steinberg ASIO Licensing Agreement.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeanSoraghan/Feature-Extractor/84db22e758671a9d91c9b72f99689b11c2cb863c/ASIOSDK2.3/Steinberg ASIO Licensing Agreement.pdf -------------------------------------------------------------------------------- /ASIOSDK2.3/asio/asio.dsw: -------------------------------------------------------------------------------- 1 | Microsoft Developer Studio Workspace File, Format Version 6.00 2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! 3 | 4 | ############################################################################### 5 | 6 | Project: "asiosample"="..\driver\asiosample\asiosample\asiosample.dsp" - Package Owner=<4> 7 | 8 | Package=<5> 9 | {{{ 10 | }}} 11 | 12 | Package=<4> 13 | {{{ 14 | }}} 15 | 16 | ############################################################################### 17 | 18 | Project: "hostsample"="..\host\sample\hostsample.dsp" - Package Owner=<4> 19 | 20 | Package=<5> 21 | {{{ 22 | }}} 23 | 24 | Package=<4> 25 | {{{ 26 | }}} 27 | 28 | ############################################################################### 29 | 30 | Global: 31 | 32 | Package=<5> 33 | {{{ 34 | }}} 35 | 36 | Package=<3> 37 | {{{ 38 | }}} 39 | 40 | ############################################################################### 41 | 42 | -------------------------------------------------------------------------------- /ASIOSDK2.3/asio/asio.opt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeanSoraghan/Feature-Extractor/84db22e758671a9d91c9b72f99689b11c2cb863c/ASIOSDK2.3/asio/asio.opt -------------------------------------------------------------------------------- /ASIOSDK2.3/changes.txt: -------------------------------------------------------------------------------- 1 | Changes in ASIO 2.3 since ASIO 2.2 2 | - added host queries to detect the driver's buffering and drop-out detection capabilities 3 | - some additional documentation on MMCSS; see page 46 of 'ASIO SDK 2.3.pdf' 4 | - dropped support for Mac OS 8 and 9 5 | 6 | Changes in ASIO 2.2 since ASIO 2.1 7 | - added support for Windows 64 bit 8 | 9 | Changes in ASIO 2.1 since ASIO 2.0 10 | - Sony DSD support added 11 | - fixed Windows registry sample to HKEY_LOCAL_MACHINE 12 | - fixed a definition problem for input monitoring 13 | -------------------------------------------------------------------------------- /ASIOSDK2.3/common/asio.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Steinberg Audio Stream I/O API 3 | (c) 1996, Steinberg Soft- und Hardware GmbH 4 | 5 | asio.cpp 6 | 7 | asio functions entries which translate the 8 | asio interface to the asiodrvr class methods 9 | */ 10 | 11 | #include 12 | #include "asiosys.h" // platform definition 13 | #include "asio.h" 14 | 15 | #if MAC 16 | #include "asiodrvr.h" 17 | 18 | #pragma export on 19 | 20 | AsioDriver *theAsioDriver = 0; 21 | 22 | extern "C" 23 | { 24 | 25 | long main() 26 | { 27 | return 'ASIO'; 28 | } 29 | 30 | #elif WINDOWS 31 | 32 | #include "windows.h" 33 | #include "iasiodrv.h" 34 | #include "asiodrivers.h" 35 | 36 | IASIO *theAsioDriver = 0; 37 | extern AsioDrivers *asioDrivers; 38 | 39 | #elif SGI || SUN || BEOS || LINUX 40 | #include "asiodrvr.h" 41 | static AsioDriver *theAsioDriver = 0; 42 | #endif 43 | 44 | //----------------------------------------------------------------------------------------------------- 45 | ASIOError ASIOInit(ASIODriverInfo *info) 46 | { 47 | #if MAC || SGI || SUN || BEOS || LINUX 48 | if(theAsioDriver) 49 | { 50 | delete theAsioDriver; 51 | theAsioDriver = 0; 52 | } 53 | info->driverVersion = 0; 54 | strcpy(info->name, "No ASIO Driver"); 55 | theAsioDriver = getDriver(); 56 | if(!theAsioDriver) 57 | { 58 | strcpy(info->errorMessage, "Not enough memory for the ASIO driver!"); 59 | return ASE_NotPresent; 60 | } 61 | if(!theAsioDriver->init(info->sysRef)) 62 | { 63 | theAsioDriver->getErrorMessage(info->errorMessage); 64 | delete theAsioDriver; 65 | theAsioDriver = 0; 66 | return ASE_NotPresent; 67 | } 68 | strcpy(info->errorMessage, "No ASIO Driver Error"); 69 | theAsioDriver->getDriverName(info->name); 70 | info->driverVersion = theAsioDriver->getDriverVersion(); 71 | return ASE_OK; 72 | 73 | #else 74 | 75 | info->driverVersion = 0; 76 | strcpy(info->name, "No ASIO Driver"); 77 | if(theAsioDriver) // must be loaded! 78 | { 79 | if(!theAsioDriver->init(info->sysRef)) 80 | { 81 | theAsioDriver->getErrorMessage(info->errorMessage); 82 | theAsioDriver = 0; 83 | return ASE_NotPresent; 84 | } 85 | 86 | strcpy(info->errorMessage, "No ASIO Driver Error"); 87 | theAsioDriver->getDriverName(info->name); 88 | info->driverVersion = theAsioDriver->getDriverVersion(); 89 | return ASE_OK; 90 | } 91 | return ASE_NotPresent; 92 | 93 | #endif // !MAC 94 | } 95 | 96 | ASIOError ASIOExit(void) 97 | { 98 | if(theAsioDriver) 99 | { 100 | #if WINDOWS 101 | asioDrivers->removeCurrentDriver(); 102 | #else 103 | delete theAsioDriver; 104 | #endif 105 | } 106 | theAsioDriver = 0; 107 | return ASE_OK; 108 | } 109 | 110 | ASIOError ASIOStart(void) 111 | { 112 | if(!theAsioDriver) 113 | return ASE_NotPresent; 114 | return theAsioDriver->start(); 115 | } 116 | 117 | ASIOError ASIOStop(void) 118 | { 119 | if(!theAsioDriver) 120 | return ASE_NotPresent; 121 | return theAsioDriver->stop(); 122 | } 123 | 124 | ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels) 125 | { 126 | if(!theAsioDriver) 127 | { 128 | *numInputChannels = *numOutputChannels = 0; 129 | return ASE_NotPresent; 130 | } 131 | return theAsioDriver->getChannels(numInputChannels, numOutputChannels); 132 | } 133 | 134 | ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency) 135 | { 136 | if(!theAsioDriver) 137 | { 138 | *inputLatency = *outputLatency = 0; 139 | return ASE_NotPresent; 140 | } 141 | return theAsioDriver->getLatencies(inputLatency, outputLatency); 142 | } 143 | 144 | ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity) 145 | { 146 | if(!theAsioDriver) 147 | { 148 | *minSize = *maxSize = *preferredSize = *granularity = 0; 149 | return ASE_NotPresent; 150 | } 151 | return theAsioDriver->getBufferSize(minSize, maxSize, preferredSize, granularity); 152 | } 153 | 154 | ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate) 155 | { 156 | if(!theAsioDriver) 157 | return ASE_NotPresent; 158 | return theAsioDriver->canSampleRate(sampleRate); 159 | } 160 | 161 | ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate) 162 | { 163 | if(!theAsioDriver) 164 | return ASE_NotPresent; 165 | return theAsioDriver->getSampleRate(currentRate); 166 | } 167 | 168 | ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate) 169 | { 170 | if(!theAsioDriver) 171 | return ASE_NotPresent; 172 | return theAsioDriver->setSampleRate(sampleRate); 173 | } 174 | 175 | ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources) 176 | { 177 | if(!theAsioDriver) 178 | { 179 | *numSources = 0; 180 | return ASE_NotPresent; 181 | } 182 | return theAsioDriver->getClockSources(clocks, numSources); 183 | } 184 | 185 | ASIOError ASIOSetClockSource(long reference) 186 | { 187 | if(!theAsioDriver) 188 | return ASE_NotPresent; 189 | return theAsioDriver->setClockSource(reference); 190 | } 191 | 192 | ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) 193 | { 194 | if(!theAsioDriver) 195 | return ASE_NotPresent; 196 | return theAsioDriver->getSamplePosition(sPos, tStamp); 197 | } 198 | 199 | ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info) 200 | { 201 | if(!theAsioDriver) 202 | { 203 | info->channelGroup = -1; 204 | info->type = ASIOSTInt16MSB; 205 | strcpy(info->name, "None"); 206 | return ASE_NotPresent; 207 | } 208 | return theAsioDriver->getChannelInfo(info); 209 | } 210 | 211 | ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels, 212 | long bufferSize, ASIOCallbacks *callbacks) 213 | { 214 | if(!theAsioDriver) 215 | { 216 | ASIOBufferInfo *info = bufferInfos; 217 | for(long i = 0; i < numChannels; i++, info++) 218 | info->buffers[0] = info->buffers[1] = 0; 219 | return ASE_NotPresent; 220 | } 221 | return theAsioDriver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks); 222 | } 223 | 224 | ASIOError ASIODisposeBuffers(void) 225 | { 226 | if(!theAsioDriver) 227 | return ASE_NotPresent; 228 | return theAsioDriver->disposeBuffers(); 229 | } 230 | 231 | ASIOError ASIOControlPanel(void) 232 | { 233 | if(!theAsioDriver) 234 | return ASE_NotPresent; 235 | return theAsioDriver->controlPanel(); 236 | } 237 | 238 | ASIOError ASIOFuture(long selector, void *opt) 239 | { 240 | if(!theAsioDriver) 241 | return ASE_NotPresent; 242 | return theAsioDriver->future(selector, opt); 243 | } 244 | 245 | ASIOError ASIOOutputReady(void) 246 | { 247 | if(!theAsioDriver) 248 | return ASE_NotPresent; 249 | return theAsioDriver->outputReady(); 250 | } 251 | 252 | #if MAC 253 | } // extern "C" 254 | #pragma export off 255 | #endif 256 | 257 | 258 | -------------------------------------------------------------------------------- /ASIOSDK2.3/common/asiodrvr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Steinberg Audio Stream I/O API 3 | (c) 1996, Steinberg Soft- und Hardware GmbH 4 | charlie (May 1996) 5 | 6 | asiodrvr.cpp 7 | c++ superclass to implement asio functionality. from this, 8 | you can derive whatever required 9 | */ 10 | 11 | #include 12 | #include "asiosys.h" 13 | #include "asiodrvr.h" 14 | 15 | #if WINDOWS 16 | #error do not use this 17 | AsioDriver::AsioDriver (LPUNKNOWN pUnk, HRESULT *phr) : CUnknown("My AsioDriver", pUnk, phr) 18 | { 19 | } 20 | 21 | #else 22 | 23 | AsioDriver::AsioDriver() 24 | { 25 | } 26 | 27 | #endif 28 | 29 | AsioDriver::~AsioDriver() 30 | { 31 | } 32 | 33 | ASIOBool AsioDriver::init(void *sysRef) 34 | { 35 | return ASE_NotPresent; 36 | } 37 | 38 | void AsioDriver::getDriverName(char *name) 39 | { 40 | strcpy(name, "No Driver"); 41 | } 42 | 43 | long AsioDriver::getDriverVersion() 44 | { 45 | return 0; 46 | } 47 | 48 | void AsioDriver::getErrorMessage(char *string) 49 | { 50 | strcpy(string, "ASIO Driver Implementation Error!"); 51 | } 52 | 53 | ASIOError AsioDriver::start() 54 | { 55 | return ASE_NotPresent; 56 | } 57 | 58 | ASIOError AsioDriver::stop() 59 | { 60 | return ASE_NotPresent; 61 | } 62 | 63 | ASIOError AsioDriver::getChannels(long *numInputChannels, long *numOutputChannels) 64 | { 65 | return ASE_NotPresent; 66 | } 67 | 68 | ASIOError AsioDriver::getLatencies(long *inputLatency, long *outputLatency) 69 | { 70 | return ASE_NotPresent; 71 | } 72 | 73 | ASIOError AsioDriver::getBufferSize(long *minSize, long *maxSize, 74 | long *preferredSize, long *granularity) 75 | { 76 | return ASE_NotPresent; 77 | } 78 | 79 | ASIOError AsioDriver::canSampleRate(ASIOSampleRate sampleRate) 80 | { 81 | return ASE_NotPresent; 82 | } 83 | 84 | ASIOError AsioDriver::getSampleRate(ASIOSampleRate *sampleRate) 85 | { 86 | return ASE_NotPresent; 87 | } 88 | 89 | ASIOError AsioDriver::setSampleRate(ASIOSampleRate sampleRate) 90 | { 91 | return ASE_NotPresent; 92 | } 93 | 94 | ASIOError AsioDriver::getClockSources(ASIOClockSource *clocks, long *numSources) 95 | { 96 | *numSources = 0; 97 | return ASE_NotPresent; 98 | } 99 | 100 | ASIOError AsioDriver::setClockSource(long reference) 101 | { 102 | return ASE_NotPresent; 103 | } 104 | 105 | ASIOError AsioDriver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) 106 | { 107 | return ASE_NotPresent; 108 | } 109 | 110 | ASIOError AsioDriver::getChannelInfo(ASIOChannelInfo *info) 111 | { 112 | return ASE_NotPresent; 113 | } 114 | 115 | ASIOError AsioDriver::createBuffers(ASIOBufferInfo *channelInfos, long numChannels, 116 | long bufferSize, ASIOCallbacks *callbacks) 117 | { 118 | return ASE_NotPresent; 119 | } 120 | 121 | ASIOError AsioDriver::disposeBuffers() 122 | { 123 | return ASE_NotPresent; 124 | } 125 | 126 | ASIOError AsioDriver::controlPanel() 127 | { 128 | return ASE_NotPresent; 129 | } 130 | 131 | ASIOError AsioDriver::future(long selector, void *opt) 132 | { 133 | return ASE_NotPresent; 134 | } 135 | 136 | ASIOError AsioDriver::outputReady() 137 | { 138 | return ASE_NotPresent; 139 | } -------------------------------------------------------------------------------- /ASIOSDK2.3/common/asiodrvr.h: -------------------------------------------------------------------------------- 1 | /* 2 | Steinberg Audio Stream I/O API 3 | (c) 1996, Steinberg Soft- und Hardware GmbH 4 | charlie (May 1996) 5 | 6 | asiodrvr.h 7 | c++ superclass to implement asio functionality. from this, 8 | you can derive whatever required 9 | */ 10 | 11 | #ifndef _asiodrvr_ 12 | #define _asiodrvr_ 13 | 14 | // cpu and os system we are running on 15 | #include "asiosys.h" 16 | // basic "C" interface 17 | #include "asio.h" 18 | 19 | class AsioDriver; 20 | extern AsioDriver *getDriver(); // for generic constructor 21 | 22 | #if WINDOWS 23 | #include 24 | #include "combase.h" 25 | #include "iasiodrv.h" 26 | class AsioDriver : public IASIO ,public CUnknown 27 | { 28 | public: 29 | AsioDriver(LPUNKNOWN pUnk, HRESULT *phr); 30 | 31 | DECLARE_IUNKNOWN 32 | // Factory method 33 | static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); 34 | // IUnknown 35 | virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject); 36 | 37 | #else 38 | 39 | class AsioDriver 40 | { 41 | public: 42 | AsioDriver(); 43 | #endif 44 | virtual ~AsioDriver(); 45 | 46 | virtual ASIOBool init(void* sysRef); 47 | virtual void getDriverName(char *name); // max 32 bytes incl. terminating zero 48 | virtual long getDriverVersion(); 49 | virtual void getErrorMessage(char *string); // max 124 bytes incl. 50 | 51 | virtual ASIOError start(); 52 | virtual ASIOError stop(); 53 | 54 | virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels); 55 | virtual ASIOError getLatencies(long *inputLatency, long *outputLatency); 56 | virtual ASIOError getBufferSize(long *minSize, long *maxSize, 57 | long *preferredSize, long *granularity); 58 | 59 | virtual ASIOError canSampleRate(ASIOSampleRate sampleRate); 60 | virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate); 61 | virtual ASIOError setSampleRate(ASIOSampleRate sampleRate); 62 | virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); 63 | virtual ASIOError setClockSource(long reference); 64 | 65 | virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); 66 | virtual ASIOError getChannelInfo(ASIOChannelInfo *info); 67 | 68 | virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, 69 | long bufferSize, ASIOCallbacks *callbacks); 70 | virtual ASIOError disposeBuffers(); 71 | 72 | virtual ASIOError controlPanel(); 73 | virtual ASIOError future(long selector, void *opt); 74 | virtual ASIOError outputReady(); 75 | }; 76 | #endif 77 | -------------------------------------------------------------------------------- /ASIOSDK2.3/common/asiosys.h: -------------------------------------------------------------------------------- 1 | #ifndef __asiosys__ 2 | #define __asiosys__ 3 | 4 | #if defined(_WIN32) || defined(_WIN64) 5 | #undef MAC 6 | #define PPC 0 7 | #define WINDOWS 1 8 | #define SGI 0 9 | #define SUN 0 10 | #define LINUX 0 11 | #define BEOS 0 12 | 13 | #define NATIVE_INT64 0 14 | #define IEEE754_64FLOAT 1 15 | 16 | #elif BEOS 17 | #define MAC 0 18 | #define PPC 0 19 | #define WINDOWS 0 20 | #define PC 0 21 | #define SGI 0 22 | #define SUN 0 23 | #define LINUX 0 24 | 25 | #define NATIVE_INT64 0 26 | #define IEEE754_64FLOAT 1 27 | 28 | #ifndef DEBUG 29 | #define DEBUG 0 30 | #if DEBUG 31 | void DEBUGGERMESSAGE(char *string); 32 | #else 33 | #define DEBUGGERMESSAGE(a) 34 | #endif 35 | #endif 36 | 37 | #elif SGI 38 | #define MAC 0 39 | #define PPC 0 40 | #define WINDOWS 0 41 | #define PC 0 42 | #define SUN 0 43 | #define LINUX 0 44 | #define BEOS 0 45 | 46 | #define NATIVE_INT64 0 47 | #define IEEE754_64FLOAT 1 48 | 49 | #ifndef DEBUG 50 | #define DEBUG 0 51 | #if DEBUG 52 | void DEBUGGERMESSAGE(char *string); 53 | #else 54 | #define DEBUGGERMESSAGE(a) 55 | #endif 56 | #endif 57 | 58 | #else // MAC 59 | 60 | #define MAC 1 61 | #define PPC 1 62 | #define WINDOWS 0 63 | #define PC 0 64 | #define SGI 0 65 | #define SUN 0 66 | #define LINUX 0 67 | #define BEOS 0 68 | 69 | #define NATIVE_INT64 0 70 | #define IEEE754_64FLOAT 1 71 | 72 | #ifndef DEBUG 73 | #define DEBUG 0 74 | #if DEBUG 75 | void DEBUGGERMESSAGE(char *string); 76 | #else 77 | #define DEBUGGERMESSAGE(a) 78 | #endif 79 | #endif 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /ASIOSDK2.3/common/combase.cpp: -------------------------------------------------------------------------------- 1 | //==========================================================================; 2 | // 3 | // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 4 | // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 5 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR 6 | // PURPOSE. 7 | // 8 | // Copyright (c) 1992 - 1996 Microsoft Corporation. All Rights Reserved. 9 | // 10 | //--------------------------------------------------------------------------; 11 | 12 | // Base class hierachy for creating COM objects, December 1994 13 | 14 | #include 15 | #include "wxdebug.h" 16 | #include "combase.h" 17 | #pragma warning( disable : 4514 ) // Disable warnings re unused inline functions 18 | 19 | 20 | /* Define the static member variable */ 21 | 22 | LONG CBaseObject::m_cObjects = 0; 23 | 24 | 25 | /* Constructor */ 26 | 27 | CBaseObject::CBaseObject(TCHAR *pName) 28 | { 29 | /* Increment the number of active objects */ 30 | InterlockedIncrement(&m_cObjects); 31 | 32 | #ifdef DEBUG 33 | m_dwCookie = DbgRegisterObjectCreation(pName); 34 | #endif 35 | } 36 | 37 | 38 | /* Destructor */ 39 | 40 | CBaseObject::~CBaseObject() 41 | { 42 | /* Decrement the number of objects active */ 43 | InterlockedDecrement(&m_cObjects); 44 | 45 | #ifdef DEBUG 46 | DbgRegisterObjectDestruction(m_dwCookie); 47 | #endif 48 | } 49 | 50 | 51 | /* Constructor */ 52 | 53 | // We know we use "this" in the initialization list, we also know we don't modify *phr. 54 | #pragma warning( disable : 4355 4100 ) 55 | CUnknown::CUnknown(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr) 56 | : CBaseObject(pName) 57 | /* Start the object with a reference count of zero - when the */ 58 | /* object is queried for it's first interface this may be */ 59 | /* incremented depending on whether or not this object is */ 60 | /* currently being aggregated upon */ 61 | , m_cRef(0) 62 | /* Set our pointer to our IUnknown interface. */ 63 | /* If we have an outer, use its, otherwise use ours. */ 64 | /* This pointer effectivly points to the owner of */ 65 | /* this object and can be accessed by the GetOwner() method. */ 66 | , m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast( static_cast(this) ) ) 67 | /* Why the double cast? Well, the inner cast is a type-safe cast */ 68 | /* to pointer to a type from which we inherit. The second is */ 69 | /* type-unsafe but works because INonDelegatingUnknown "behaves */ 70 | /* like" IUnknown. (Only the names on the methods change.) */ 71 | { 72 | // Everything we need to do has been done in the initializer list 73 | } 74 | #pragma warning( default : 4355 4100 ) 75 | 76 | /* QueryInterface */ 77 | 78 | STDMETHODIMP CUnknown::NonDelegatingQueryInterface(REFIID riid, void ** ppv) 79 | { 80 | CheckPointer(ppv,E_POINTER); 81 | ValidateReadWritePtr(ppv,sizeof(PVOID)); 82 | 83 | /* We know only about IUnknown */ 84 | 85 | if (riid == IID_IUnknown) { 86 | GetInterface((LPUNKNOWN) (PNDUNKNOWN) this, ppv); 87 | return NOERROR; 88 | } else { 89 | *ppv = NULL; 90 | return E_NOINTERFACE; 91 | } 92 | } 93 | 94 | /* We have to ensure that we DON'T use a max macro, since these will typically */ 95 | /* lead to one of the parameters being evaluated twice. Since we are worried */ 96 | /* about concurrency, we can't afford to access the m_cRef twice since we can't */ 97 | /* afford to run the risk that its value having changed between accesses. */ 98 | #ifdef max 99 | #undef max 100 | #endif 101 | 102 | template inline static T max( const T & a, const T & b ) 103 | { 104 | return a > b ? a : b; 105 | } 106 | 107 | /* AddRef */ 108 | 109 | STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef() 110 | { 111 | LONG lRef = InterlockedIncrement( &m_cRef ); 112 | ASSERT(lRef > 0); 113 | DbgLog((LOG_MEMORY,3,TEXT(" Obj %d ref++ = %d"), 114 | m_dwCookie, m_cRef)); 115 | return max(ULONG(m_cRef), 1ul); 116 | } 117 | 118 | 119 | 120 | /* Release */ 121 | 122 | STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease() 123 | { 124 | /* If the reference count drops to zero delete ourselves */ 125 | 126 | LONG lRef = InterlockedDecrement( &m_cRef ); 127 | ASSERT(lRef >= 0); 128 | 129 | DbgLog((LOG_MEMORY,3,TEXT(" Object %d ref-- = %d"), 130 | m_dwCookie, m_cRef)); 131 | if (lRef == 0) { 132 | 133 | // COM rules say we must protect against re-entrancy. 134 | // If we are an aggregator and we hold our own interfaces 135 | // on the aggregatee, the QI for these interfaces will 136 | // addref ourselves. So after doing the QI we must release 137 | // a ref count on ourselves. Then, before releasing the 138 | // private interface, we must addref ourselves. When we do 139 | // this from the destructor here it will result in the ref 140 | // count going to 1 and then back to 0 causing us to 141 | // re-enter the destructor. Hence we add an extra refcount here 142 | // once we know we will delete the object. 143 | // for an example aggregator see filgraph\distrib.cpp. 144 | 145 | m_cRef++; 146 | 147 | delete this; 148 | return ULONG(0); 149 | } else { 150 | return max(ULONG(m_cRef), 1ul); 151 | } 152 | } 153 | 154 | 155 | /* Return an interface pointer to a requesting client 156 | performing a thread safe AddRef as necessary */ 157 | 158 | HRESULT CUnknown::GetInterface(LPUNKNOWN pUnk, void **ppv) 159 | { 160 | CheckPointer(ppv, E_POINTER); 161 | *ppv = pUnk; 162 | pUnk->AddRef(); 163 | return NOERROR; 164 | } 165 | 166 | 167 | /* Compares two interfaces and returns TRUE if they are on the same object */ 168 | 169 | BOOL IsEqualObject(IUnknown *pFirst, IUnknown *pSecond) 170 | { 171 | /* Different objects can't have the same interface pointer for 172 | any interface 173 | */ 174 | if (pFirst == pSecond) { 175 | return TRUE; 176 | } 177 | /* OK - do it the hard way - check if they have the same 178 | IUnknown pointers - a single object can only have one of these 179 | */ 180 | LPUNKNOWN pUnknown1; // Retrieve the IUnknown interface 181 | LPUNKNOWN pUnknown2; // Retrieve the other IUnknown interface 182 | HRESULT hr; // General OLE return code 183 | 184 | ASSERT(pFirst); 185 | ASSERT(pSecond); 186 | 187 | /* See if the IUnknown pointers match */ 188 | 189 | hr = pFirst->QueryInterface(IID_IUnknown,(void **) &pUnknown1); 190 | ASSERT(SUCCEEDED(hr)); 191 | ASSERT(pUnknown1); 192 | 193 | hr = pSecond->QueryInterface(IID_IUnknown,(void **) &pUnknown2); 194 | ASSERT(SUCCEEDED(hr)); 195 | ASSERT(pUnknown2); 196 | 197 | /* Release the extra interfaces we hold */ 198 | 199 | pUnknown1->Release(); 200 | pUnknown2->Release(); 201 | return (pUnknown1 == pUnknown2); 202 | } 203 | -------------------------------------------------------------------------------- /ASIOSDK2.3/common/debugmessage.cpp: -------------------------------------------------------------------------------- 1 | #include "asiosys.h" 2 | 3 | #if DEBUG 4 | #if MAC 5 | #include 6 | void DEBUGGERMESSAGE(char *string) 7 | { 8 | c2pstr(string); 9 | DebugStr((unsigned char *)string); 10 | } 11 | #else 12 | #error debugmessage 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /ASIOSDK2.3/common/dllentry.cpp: -------------------------------------------------------------------------------- 1 | //==========================================================================; 2 | // 3 | // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 4 | // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 5 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR 6 | // PURPOSE. 7 | // 8 | // Copyright (c) 1992 - 1996 Microsoft Corporation. All Rights Reserved. 9 | // 10 | //--------------------------------------------------------------------------; 11 | 12 | // 13 | // classes used to support dll entrypoints for COM objects. 14 | // 15 | // #include "switches.h" 16 | 17 | #include 18 | #include "wxdebug.h" 19 | #include "combase.h" 20 | #ifdef DEBUG 21 | #include 22 | #endif 23 | 24 | #include 25 | 26 | extern CFactoryTemplate g_Templates[]; 27 | extern int g_cTemplates; 28 | 29 | HINSTANCE hinstance = 0; 30 | DWORD g_amPlatform; // VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx) 31 | OSVERSIONINFO g_osInfo; 32 | 33 | // 34 | // an instance of this is created by the DLLGetClassObject entrypoint 35 | // it uses the CFactoryTemplate object it is given to support the 36 | // IClassFactory interface 37 | 38 | class CClassFactory : public IClassFactory 39 | { 40 | 41 | private: 42 | const CFactoryTemplate * m_pTemplate; 43 | 44 | ULONG m_cRef; 45 | 46 | static int m_cLocked; 47 | public: 48 | CClassFactory(const CFactoryTemplate *); 49 | 50 | // IUnknown 51 | STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); 52 | STDMETHODIMP_(ULONG)AddRef(); 53 | STDMETHODIMP_(ULONG)Release(); 54 | 55 | // IClassFactory 56 | STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **pv); 57 | STDMETHODIMP LockServer(BOOL fLock); 58 | 59 | // allow DLLGetClassObject to know about global server lock status 60 | static BOOL IsLocked() { 61 | return (m_cLocked > 0); 62 | }; 63 | }; 64 | 65 | // process-wide dll locked state 66 | int CClassFactory::m_cLocked = 0; 67 | 68 | CClassFactory::CClassFactory(const CFactoryTemplate *pTemplate) 69 | { 70 | m_cRef = 0; 71 | m_pTemplate = pTemplate; 72 | } 73 | 74 | 75 | STDMETHODIMP CClassFactory::QueryInterface(REFIID riid,void **ppv) 76 | { 77 | CheckPointer(ppv,E_POINTER) 78 | ValidateReadWritePtr(ppv,sizeof(PVOID)); 79 | *ppv = NULL; 80 | 81 | // any interface on this object is the object pointer. 82 | if ((riid == IID_IUnknown) || (riid == IID_IClassFactory)) { 83 | *ppv = (LPVOID) this; 84 | // AddRef returned interface pointer 85 | ((LPUNKNOWN) *ppv)->AddRef(); 86 | return NOERROR; 87 | } 88 | 89 | return ResultFromScode(E_NOINTERFACE); 90 | } 91 | 92 | 93 | STDMETHODIMP_(ULONG) CClassFactory::AddRef() 94 | { 95 | return ++m_cRef; 96 | } 97 | 98 | STDMETHODIMP_(ULONG) CClassFactory::Release() 99 | { 100 | LONG rc; 101 | 102 | if (--m_cRef == 0) { 103 | delete this; 104 | rc = 0; 105 | } else rc = m_cRef; 106 | 107 | return rc; 108 | } 109 | 110 | STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,REFIID riid,void **pv) 111 | { 112 | CheckPointer(pv,E_POINTER) 113 | ValidateReadWritePtr(pv,sizeof(void *)); 114 | 115 | /* Enforce the normal OLE rules regarding interfaces and delegation */ 116 | 117 | if (pUnkOuter != NULL) { 118 | if (IsEqualIID(riid,IID_IUnknown) == FALSE) { 119 | return ResultFromScode(E_NOINTERFACE); 120 | } 121 | } 122 | 123 | /* Create the new object through the derived class's create function */ 124 | 125 | HRESULT hr = NOERROR; 126 | CUnknown *pObj = m_pTemplate->CreateInstance(pUnkOuter, &hr); 127 | 128 | if (pObj == NULL) { 129 | return E_OUTOFMEMORY; 130 | } 131 | 132 | /* Delete the object if we got a construction error */ 133 | 134 | if (FAILED(hr)) { 135 | delete pObj; 136 | return hr; 137 | } 138 | 139 | /* Get a reference counted interface on the object */ 140 | 141 | /* We wrap the non-delegating QI with NDAddRef & NDRelease. */ 142 | /* This protects any outer object from being prematurely */ 143 | /* released by an inner object that may have to be created */ 144 | /* in order to supply the requested interface. */ 145 | pObj->NonDelegatingAddRef(); 146 | hr = pObj->NonDelegatingQueryInterface(riid, pv); 147 | pObj->NonDelegatingRelease(); 148 | /* Note that if NonDelegatingQueryInterface fails, it will */ 149 | /* not increment the ref count, so the NonDelegatingRelease */ 150 | /* will drop the ref back to zero and the object will "self-*/ 151 | /* destruct". Hence we don't need additional tidy-up code */ 152 | /* to cope with NonDelegatingQueryInterface failing. */ 153 | 154 | if (SUCCEEDED(hr)) { 155 | ASSERT(*pv); 156 | } 157 | 158 | return hr; 159 | } 160 | 161 | STDMETHODIMP CClassFactory::LockServer(BOOL fLock) 162 | { 163 | if (fLock) { 164 | m_cLocked++; 165 | } else { 166 | m_cLocked--; 167 | } 168 | return NOERROR; 169 | } 170 | 171 | 172 | // --- COM entrypoints ----------------------------------------- 173 | // DllRegisterServer 174 | 175 | //called by COM to get the class factory object for a given class 176 | STDAPI DllGetClassObject(REFCLSID rClsID,REFIID riid,void **pv) 177 | { 178 | // DebugBreak(); 179 | 180 | if (!(riid == IID_IUnknown) && !(riid == IID_IClassFactory)) { 181 | return E_NOINTERFACE; 182 | } 183 | 184 | // traverse the array of templates looking for one with this 185 | // class id 186 | for (int i = 0; i < g_cTemplates; i++) { 187 | const CFactoryTemplate * pT = &g_Templates[i]; 188 | if (pT->IsClassID(rClsID)) { 189 | 190 | // found a template - make a class factory based on this 191 | // template 192 | 193 | *pv = (LPVOID) (LPUNKNOWN) new CClassFactory(pT); 194 | if (*pv == NULL) { 195 | return E_OUTOFMEMORY; 196 | } 197 | ((LPUNKNOWN)*pv)->AddRef(); 198 | return NOERROR; 199 | } 200 | } 201 | return CLASS_E_CLASSNOTAVAILABLE; 202 | } 203 | 204 | // 205 | // Call any initialization routines 206 | // 207 | void DllInitClasses(BOOL bLoading) 208 | { 209 | int i; 210 | 211 | // DebugBreak(); 212 | 213 | // traverse the array of templates calling the init routine 214 | // if they have one 215 | for (i = 0; i < g_cTemplates; i++) { 216 | const CFactoryTemplate * pT = &g_Templates[i]; 217 | if (pT->m_lpfnInit != NULL) { 218 | (*pT->m_lpfnInit)(bLoading, pT->m_ClsID); 219 | } 220 | } 221 | 222 | } 223 | 224 | // called by COM to determine if this dll can be unloaded 225 | // return ok unless there are outstanding objects or a lock requested 226 | // by IClassFactory::LockServer 227 | // 228 | // CClassFactory has a static function that can tell us about the locks, 229 | // and CCOMObject has a static function that can tell us about the active 230 | // object count 231 | STDAPI DllCanUnloadNow() 232 | { 233 | // DebugBreak(); 234 | 235 | DbgLog((LOG_MEMORY,2,TEXT("DLLCanUnloadNow called - IsLocked = %d, Active objects = %d"), 236 | CClassFactory::IsLocked(), 237 | CBaseObject::ObjectsActive())); 238 | 239 | if (CClassFactory::IsLocked() || CBaseObject::ObjectsActive()) { 240 | 241 | return S_FALSE; 242 | } 243 | else { 244 | return S_OK; 245 | } 246 | } 247 | 248 | 249 | // --- standard WIN32 entrypoints -------------------------------------- 250 | 251 | 252 | //extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID); 253 | //BOOL WINAPI DllEntryPoint(HINSTANCE hInstance,ULONG ulReason,LPVOID pv) 254 | //BOOL WINAPI DllMain (HINSTANCE hInstance,ULONG ulReason,LPVOID pv) 255 | BOOL WINAPI DllEntryPoint (HINSTANCE hInstance,ULONG ulReason,LPVOID pv) 256 | { 257 | 258 | // DebugBreak(); 259 | 260 | switch (ulReason) { 261 | 262 | case DLL_PROCESS_ATTACH: 263 | DisableThreadLibraryCalls(hInstance); 264 | DbgInitialise(hInstance); 265 | { 266 | // The platform identifier is used to work out whether 267 | // full unicode support is available or not. Hence the 268 | // default will be the lowest common denominator - i.e. N/A 269 | g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails 270 | 271 | g_osInfo.dwOSVersionInfoSize = sizeof(g_osInfo); 272 | if (GetVersionEx(&g_osInfo)) { 273 | g_amPlatform = g_osInfo.dwPlatformId; 274 | } 275 | else { 276 | DbgLog((LOG_ERROR, 1, "Failed to get the OS platform, assuming Win95")); 277 | } 278 | } 279 | hinstance = hInstance; 280 | DllInitClasses(TRUE); 281 | 282 | break; 283 | 284 | case DLL_PROCESS_DETACH: 285 | DllInitClasses(FALSE); 286 | 287 | #ifdef DEBUG 288 | if (CBaseObject::ObjectsActive()) { 289 | DbgSetModuleLevel(LOG_MEMORY, 2); 290 | TCHAR szInfo[512]; 291 | extern TCHAR m_ModuleName[]; // Cut down module name 292 | 293 | TCHAR FullName[_MAX_PATH]; // Load the full path and module name 294 | TCHAR *pName; // Searches from the end for a backslash 295 | 296 | GetModuleFileName(NULL,FullName,_MAX_PATH); 297 | pName = _tcsrchr(FullName,'\\'); 298 | if (pName == NULL) { 299 | pName = FullName; 300 | } 301 | else { 302 | pName++; 303 | } 304 | 305 | DWORD cch = wsprintf(szInfo, TEXT("Executable: %s Pid %x Tid %x. "), 306 | pName, GetCurrentProcessId(), GetCurrentThreadId()); 307 | 308 | wsprintf(szInfo+cch, TEXT("Module %s, %d objects left active!"), 309 | m_ModuleName, CBaseObject::ObjectsActive()); 310 | DbgAssert(szInfo, TEXT(__FILE__),__LINE__); 311 | 312 | // If running remotely wait for the Assert to be acknowledged 313 | // before dumping out the object register 314 | DbgDumpObjectRegister(); 315 | } 316 | DbgTerminate(); 317 | #endif 318 | break; 319 | } 320 | return TRUE; 321 | } 322 | 323 | 324 | -------------------------------------------------------------------------------- /ASIOSDK2.3/common/iasiodrv.h: -------------------------------------------------------------------------------- 1 | #include "asiosys.h" 2 | #include "asio.h" 3 | 4 | /* Forward Declarations */ 5 | 6 | #ifndef __ASIODRIVER_FWD_DEFINED__ 7 | #define __ASIODRIVER_FWD_DEFINED__ 8 | typedef interface IASIO IASIO; 9 | #endif /* __ASIODRIVER_FWD_DEFINED__ */ 10 | 11 | interface IASIO : public IUnknown 12 | { 13 | 14 | virtual ASIOBool init(void *sysHandle) = 0; 15 | virtual void getDriverName(char *name) = 0; 16 | virtual long getDriverVersion() = 0; 17 | virtual void getErrorMessage(char *string) = 0; 18 | virtual ASIOError start() = 0; 19 | virtual ASIOError stop() = 0; 20 | virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0; 21 | virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0; 22 | virtual ASIOError getBufferSize(long *minSize, long *maxSize, 23 | long *preferredSize, long *granularity) = 0; 24 | virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0; 25 | virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0; 26 | virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0; 27 | virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0; 28 | virtual ASIOError setClockSource(long reference) = 0; 29 | virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0; 30 | virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0; 31 | virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, 32 | long bufferSize, ASIOCallbacks *callbacks) = 0; 33 | virtual ASIOError disposeBuffers() = 0; 34 | virtual ASIOError controlPanel() = 0; 35 | virtual ASIOError future(long selector,void *opt) = 0; 36 | virtual ASIOError outputReady() = 0; 37 | }; 38 | -------------------------------------------------------------------------------- /ASIOSDK2.3/common/register.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct keylist 5 | { 6 | HKEY mainKey; 7 | HKEY subKey; 8 | char *keyname; 9 | struct keylist *next; 10 | } KEYLIST, *LPKEYLIST; 11 | 12 | #define CLSID_STRING_LEN 100 13 | #define MAX_PATH_LEN 360 14 | 15 | #define DEV_ERR_SELFREG -100 16 | #define ERRSREG_MODULE_NOT_FOUND DEV_ERR_SELFREG-1 17 | #define ERRSREG_MODPATH_NOT_FOUND DEV_ERR_SELFREG-2 18 | #define ERRSREG_STRING_FROM_CLSID DEV_ERR_SELFREG-3 19 | #define ERRSREG_CHAR_TO_MULTIBYTE DEV_ERR_SELFREG-4 20 | 21 | #define SZREGSTR_DESCRIPTION "Description" 22 | #define SZREGSTR_CLSID "CLSID" 23 | #define SZREGSTR_INPROCSERVER32 "InprocServer32" 24 | #define SZREGSTR_THREADINGMODEL "ThreadingModel" 25 | #define SZREGSTR_SOFTWARE "SOFTWARE" 26 | #define SZREGSTR_ASIO "ASIO" 27 | 28 | LONG RegisterAsioDriver (CLSID,char *,char *,char *,char *); 29 | LONG UnregisterAsioDriver (CLSID,char *,char *); 30 | 31 | static LONG findRegPath (HKEY,char *); 32 | static LONG createRegPath (HKEY,char *,char *); 33 | static LONG createRegStringValue (HKEY,char *,char *,char *); 34 | static LONG getRegString (HKEY,char *,char *,LPVOID,DWORD); 35 | static LPKEYLIST findAllSubKeys (HKEY,HKEY,DWORD,char *,LPKEYLIST); 36 | static LONG deleteRegPath (HKEY,char *,char *); 37 | 38 | static char subkeybuf[MAX_PATH_LEN]; 39 | 40 | 41 | // ------------------------------------------ 42 | // Global Functions 43 | // ------------------------------------------ 44 | LONG RegisterAsioDriver (CLSID clsid,char *szdllname,char *szregname,char *szasiodesc,char *szthreadmodel) 45 | { 46 | HMODULE hMod; 47 | char szDLLPath[MAX_PATH_LEN]; 48 | char szModuleName[MAX_PATH_LEN]; 49 | char szregpath[MAX_PATH_LEN]; 50 | char szclsid[CLSID_STRING_LEN]; 51 | LPOLESTR wszCLSID = NULL; 52 | BOOL newregentry = FALSE; 53 | LONG rc; 54 | 55 | hMod = GetModuleHandle(szdllname); 56 | if (!hMod) return ERRSREG_MODULE_NOT_FOUND; 57 | szModuleName[0] = 0; 58 | GetModuleFileName(hMod,szModuleName,MAX_PATH_LEN); 59 | if (!szModuleName[0]) return ERRSREG_MODPATH_NOT_FOUND; 60 | CharLower((LPTSTR)szModuleName); 61 | 62 | rc = (LONG)StringFromCLSID(clsid,&wszCLSID); 63 | if (rc != S_OK) return ERRSREG_STRING_FROM_CLSID; 64 | rc = (LONG)WideCharToMultiByte(CP_ACP,0,(LPWSTR)wszCLSID,-1,szclsid,CLSID_STRING_LEN,0,0); 65 | if (!rc) return ERRSREG_CHAR_TO_MULTIBYTE; 66 | 67 | sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid); 68 | rc = findRegPath(HKEY_CLASSES_ROOT,szregpath); 69 | if (rc) { 70 | sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_CLSID,szclsid,SZREGSTR_INPROCSERVER32); 71 | getRegString (HKEY_CLASSES_ROOT,szregpath,0,(LPVOID)szDLLPath,MAX_PATH_LEN); 72 | CharLower((LPTSTR)szDLLPath); 73 | rc = (LONG)strcmp(szDLLPath,szModuleName); 74 | if (rc) { 75 | // delete old regentry 76 | sprintf(szregpath,"%s",SZREGSTR_CLSID); 77 | deleteRegPath(HKEY_CLASSES_ROOT,szregpath,szclsid); 78 | newregentry = TRUE; 79 | } 80 | } 81 | else newregentry = TRUE; 82 | 83 | if (newregentry) { 84 | // HKEY_CLASSES_ROOT\CLSID\{...} 85 | sprintf(szregpath,"%s",SZREGSTR_CLSID); 86 | createRegPath (HKEY_CLASSES_ROOT,szregpath,szclsid); 87 | // HKEY_CLASSES_ROOT\CLSID\{...} -> Description 88 | sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid); 89 | createRegStringValue(HKEY_CLASSES_ROOT,szregpath,0,szasiodesc); 90 | // HKEY_CLASSES_ROOT\CLSID\InProcServer32 91 | sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid); 92 | createRegPath (HKEY_CLASSES_ROOT,szregpath,SZREGSTR_INPROCSERVER32); 93 | // HKEY_CLASSES_ROOT\CLSID\InProcServer32 -> DLL path 94 | sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_CLSID,szclsid,SZREGSTR_INPROCSERVER32); 95 | createRegStringValue(HKEY_CLASSES_ROOT,szregpath,0,szModuleName); 96 | // HKEY_CLASSES_ROOT\CLSID\InProcServer32 -> ThreadingModel 97 | createRegStringValue(HKEY_CLASSES_ROOT,szregpath,SZREGSTR_THREADINGMODEL,szthreadmodel); 98 | } 99 | 100 | // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO 101 | sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO); 102 | rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath); 103 | if (rc) { 104 | sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO,szregname); 105 | rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath); 106 | if (rc) { 107 | sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO); 108 | deleteRegPath(HKEY_LOCAL_MACHINE,szregpath,szregname); 109 | } 110 | } 111 | else { 112 | // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO 113 | sprintf(szregpath,"%s",SZREGSTR_SOFTWARE); 114 | createRegPath (HKEY_LOCAL_MACHINE,szregpath,SZREGSTR_ASIO); 115 | } 116 | 117 | // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\ 118 | sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO); 119 | createRegPath (HKEY_LOCAL_MACHINE,szregpath,szregname); 120 | 121 | // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\ -> CLSID 122 | // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\ -> Description 123 | sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO,szregname); 124 | createRegStringValue(HKEY_LOCAL_MACHINE,szregpath,SZREGSTR_CLSID,szclsid); 125 | createRegStringValue(HKEY_LOCAL_MACHINE,szregpath,SZREGSTR_DESCRIPTION,szasiodesc); 126 | 127 | return 0; 128 | } 129 | 130 | 131 | LONG UnregisterAsioDriver (CLSID clsid,char *szdllname,char *szregname) 132 | { 133 | LONG rc; 134 | HMODULE hMod; 135 | char szregpath[MAX_PATH_LEN]; 136 | char szModuleName[MAX_PATH_LEN]; 137 | char szclsid[CLSID_STRING_LEN]; 138 | LPOLESTR wszCLSID = NULL; 139 | 140 | 141 | hMod = GetModuleHandle(szdllname); 142 | if (!hMod) return ERRSREG_MODULE_NOT_FOUND; 143 | szModuleName[0] = 0; 144 | GetModuleFileName(hMod,szModuleName,MAX_PATH_LEN); 145 | if (!szModuleName[0]) return ERRSREG_MODPATH_NOT_FOUND; 146 | CharLower((LPTSTR)szModuleName); 147 | 148 | rc = (LONG)StringFromCLSID(clsid,&wszCLSID) ; 149 | if (rc != S_OK) return ERRSREG_STRING_FROM_CLSID; 150 | rc = (LONG)WideCharToMultiByte(CP_ACP,0,(LPWSTR)wszCLSID,-1,szclsid,CLSID_STRING_LEN,0,0); 151 | if (!rc) return ERRSREG_CHAR_TO_MULTIBYTE; 152 | 153 | 154 | sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid); 155 | rc = findRegPath(HKEY_CLASSES_ROOT,szregpath); 156 | if (rc) { 157 | // delete old regentry 158 | sprintf(szregpath,"%s",SZREGSTR_CLSID); 159 | deleteRegPath(HKEY_CLASSES_ROOT,szregpath,szclsid); 160 | } 161 | 162 | 163 | // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO 164 | sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO); 165 | rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath); 166 | if (rc) { 167 | sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO,szregname); 168 | rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath); 169 | if (rc) { 170 | sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO); 171 | deleteRegPath(HKEY_LOCAL_MACHINE,szregpath,szregname); 172 | } 173 | } 174 | 175 | return 0; 176 | } 177 | 178 | 179 | // ------------------------------------------ 180 | // Local Functions 181 | // ------------------------------------------ 182 | static LONG findRegPath (HKEY mainkey,char *szregpath) 183 | { 184 | HKEY hkey; 185 | LONG cr,rc = -1; 186 | 187 | if (szregpath) { 188 | if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) { 189 | RegCloseKey(hkey); 190 | rc = 1; 191 | } 192 | else rc = 0; 193 | } 194 | 195 | return rc; 196 | } 197 | 198 | static LONG createRegPath (HKEY mainkey,char *szregpath,char *sznewpath) 199 | { 200 | HKEY hkey,hksub; 201 | LONG cr,rc = -1; 202 | char newregpath[MAX_PATH_LEN]; 203 | 204 | sprintf(newregpath,"%s\\%s",szregpath,sznewpath); 205 | if (!(cr = findRegPath(mainkey,newregpath))) { 206 | if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) { 207 | if ((cr = RegCreateKey(hkey,sznewpath,&hksub)) == ERROR_SUCCESS) { 208 | RegCloseKey(hksub); 209 | rc = 0; 210 | } 211 | RegCloseKey(hkey); 212 | } 213 | } 214 | else if (cr > 0) rc = 0; 215 | 216 | return rc; 217 | } 218 | 219 | static LONG createRegStringValue (HKEY mainkey,char *szregpath,char *valname,char *szvalstr) 220 | { 221 | LONG cr,rc = -1; 222 | HKEY hkey; 223 | 224 | if (szregpath) { 225 | if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) { 226 | cr = RegSetValueEx(hkey,(LPCTSTR)valname,0,REG_SZ,(const BYTE *)szvalstr,(DWORD)strlen(szvalstr)); 227 | RegCloseKey(hkey); 228 | if (cr == ERROR_SUCCESS) rc = 0; 229 | } 230 | } 231 | 232 | return rc; 233 | } 234 | 235 | 236 | static LONG getRegString (HKEY mainkey,char *szregpath,char *valname,LPVOID pval,DWORD vsize) 237 | { 238 | HKEY hkey; 239 | LONG cr,rc = -1; 240 | DWORD hsize,htype; 241 | 242 | if (szregpath) { 243 | if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) { 244 | cr = RegQueryValueEx(hkey,valname,0,&htype,0,&hsize); 245 | if (cr == ERROR_SUCCESS) { 246 | if (hsize <= vsize) { 247 | cr = RegQueryValueEx(hkey,valname,0,&htype,(LPBYTE)pval,&hsize); 248 | rc = 0; 249 | } 250 | } 251 | RegCloseKey(hkey); 252 | } 253 | } 254 | return rc; 255 | } 256 | 257 | static LPKEYLIST findAllSubKeys (HKEY hkey,HKEY hksub,DWORD index,char *keyname,LPKEYLIST kl) 258 | { 259 | HKEY hknew = 0; 260 | char *newkey; 261 | LONG cr; 262 | 263 | if (!hksub) { 264 | cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_ALL_ACCESS,&hknew); 265 | if (cr != ERROR_SUCCESS) return kl; 266 | } 267 | else hknew = hksub; 268 | 269 | cr = RegEnumKey(hknew,index,(LPTSTR)subkeybuf,MAX_PATH_LEN); 270 | if (cr == ERROR_SUCCESS) { 271 | newkey = new char[strlen(subkeybuf)+1]; 272 | strcpy(newkey,subkeybuf); 273 | 274 | kl = findAllSubKeys(hknew,0,0,newkey,kl); 275 | kl = findAllSubKeys(hkey,hknew,index+1,keyname,kl); 276 | 277 | return kl; 278 | 279 | } 280 | 281 | if (!kl->next) { 282 | kl->next = new KEYLIST[1]; 283 | kl = kl->next; 284 | kl->mainKey = hkey; 285 | kl->subKey = hknew; 286 | kl->keyname = keyname; 287 | kl->next = 0; 288 | } 289 | 290 | return kl; 291 | } 292 | 293 | static LONG deleteRegPath (HKEY mainkey,char *szregpath,char *szdelpath) 294 | { 295 | HKEY hkey; 296 | LONG cr,rc = -1; 297 | KEYLIST klist; 298 | LPKEYLIST pkl,k; 299 | char *keyname = 0; 300 | 301 | if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) { 302 | 303 | keyname = new char[strlen(szdelpath)+1]; 304 | if (!keyname) { 305 | RegCloseKey(hkey); 306 | return rc; 307 | } 308 | strcpy(keyname,szdelpath); 309 | klist.next = 0; 310 | 311 | findAllSubKeys(hkey,0,0,keyname,&klist); 312 | 313 | if (klist.next) { 314 | pkl = klist.next; 315 | 316 | while (pkl) { 317 | RegCloseKey(pkl->subKey); 318 | cr = RegDeleteKey(pkl->mainKey,pkl->keyname); 319 | delete pkl->keyname; 320 | k = pkl; 321 | pkl = pkl->next; 322 | delete k; 323 | } 324 | rc = 0; 325 | } 326 | 327 | RegCloseKey(hkey); 328 | } 329 | 330 | return rc; 331 | } 332 | 333 | -------------------------------------------------------------------------------- /ASIOSDK2.3/driver/asiosample/asiosample.def: -------------------------------------------------------------------------------- 1 | LIBRARY ASIOSample 2 | DESCRIPTION 'ASIO Sample Driver' 3 | PROTMODE 4 | EXPORTS 5 | DllMain 6 | DllGetClassObject 7 | DllCanUnloadNow 8 | DllRegisterServer 9 | DllUnregisterServer 10 | -------------------------------------------------------------------------------- /ASIOSDK2.3/driver/asiosample/asiosample.txt: -------------------------------------------------------------------------------- 1 | Asiosample 2 | 3 | This sample driver illustrates the implementation of an ASIO driver. 4 | 5 | 6 | 7 | Windows notes: 8 | 9 | For Windows a COM implementation is provided. The final driver can be 10 | installed in the system by dragging the asiosample.dll onto the 11 | regsvr32.exe in the windows\system directory. 12 | 13 | It is normal that the LNK4104 warning is issued for the following 4 14 | exported symbols: 15 | 16 | DllGetClassObject 17 | DllCanUnloadNow 18 | DllRegisterServer 19 | DllUnregisterServer 20 | 21 | 22 | Macintosh notes: 23 | The supplied project is created with CodeWarrior Pro 5. 24 | -------------------------------------------------------------------------------- /ASIOSDK2.3/driver/asiosample/asiosample/asiosample.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="asiosample" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 6 | 7 | CFG=asiosample - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "asiosample.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "asiosample.mak" CFG="asiosample - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "asiosample - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") 21 | !MESSAGE "asiosample - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | MTL=midl.exe 30 | RSC=rc.exe 31 | 32 | !IF "$(CFG)" == "asiosample - Win32 Release" 33 | 34 | # PROP BASE Use_MFC 0 35 | # PROP BASE Use_Debug_Libraries 0 36 | # PROP BASE Output_Dir "Release" 37 | # PROP BASE Intermediate_Dir "Release" 38 | # PROP BASE Target_Dir "" 39 | # PROP Use_MFC 0 40 | # PROP Use_Debug_Libraries 0 41 | # PROP Output_Dir "Release" 42 | # PROP Intermediate_Dir "Release" 43 | # PROP Ignore_Export_Lib 0 44 | # PROP Target_Dir "" 45 | # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c 46 | # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\Common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c 47 | # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 48 | # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 49 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 50 | # ADD RSC /l 0x409 /d "NDEBUG" 51 | BSC32=bscmake.exe 52 | # ADD BASE BSC32 /nologo 53 | # ADD BSC32 /nologo 54 | LINK32=link.exe 55 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 56 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /dll /machine:I386 57 | 58 | !ELSEIF "$(CFG)" == "asiosample - Win32 Debug" 59 | 60 | # PROP BASE Use_MFC 0 61 | # PROP BASE Use_Debug_Libraries 1 62 | # PROP BASE Output_Dir "Debug" 63 | # PROP BASE Intermediate_Dir "Debug" 64 | # PROP BASE Target_Dir "" 65 | # PROP Use_MFC 0 66 | # PROP Use_Debug_Libraries 1 67 | # PROP Output_Dir "Debug" 68 | # PROP Intermediate_Dir "Debug" 69 | # PROP Ignore_Export_Lib 0 70 | # PROP Target_Dir "" 71 | # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c 72 | # ADD CPP /nologo /G5 /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\Common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c 73 | # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 74 | # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 75 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 76 | # ADD RSC /l 0x409 /d "_DEBUG" 77 | BSC32=bscmake.exe 78 | # ADD BASE BSC32 /nologo 79 | # ADD BSC32 /nologo 80 | LINK32=link.exe 81 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept 82 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept 83 | 84 | !ENDIF 85 | 86 | # Begin Target 87 | 88 | # Name "asiosample - Win32 Release" 89 | # Name "asiosample - Win32 Debug" 90 | # Begin Group "Source Files" 91 | 92 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 93 | # Begin Source File 94 | 95 | SOURCE=..\asiosample.def 96 | # End Source File 97 | # Begin Source File 98 | 99 | SOURCE=..\asiosmpl.cpp 100 | # End Source File 101 | # Begin Source File 102 | 103 | SOURCE=..\..\..\common\combase.cpp 104 | # End Source File 105 | # Begin Source File 106 | 107 | SOURCE=..\..\..\common\dllentry.cpp 108 | # End Source File 109 | # Begin Source File 110 | 111 | SOURCE=..\..\..\common\register.cpp 112 | # End Source File 113 | # Begin Source File 114 | 115 | SOURCE=..\wintimer.cpp 116 | # End Source File 117 | # End Group 118 | # Begin Group "Header Files" 119 | 120 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 121 | # Begin Source File 122 | 123 | SOURCE=..\..\..\common\asio.h 124 | # End Source File 125 | # Begin Source File 126 | 127 | SOURCE=..\..\Common\Asiodrvr.h 128 | # End Source File 129 | # Begin Source File 130 | 131 | SOURCE=..\asiosmpl.h 132 | # End Source File 133 | # Begin Source File 134 | 135 | SOURCE=..\..\..\common\asiosys.h 136 | # End Source File 137 | # Begin Source File 138 | 139 | SOURCE=..\..\..\common\combase.h 140 | # End Source File 141 | # Begin Source File 142 | 143 | SOURCE=..\..\..\common\iasiodrv.h 144 | # End Source File 145 | # End Group 146 | # Begin Group "Resource Files" 147 | 148 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 149 | # End Group 150 | # End Target 151 | # End Project 152 | -------------------------------------------------------------------------------- /ASIOSDK2.3/driver/asiosample/asiosmpl.h: -------------------------------------------------------------------------------- 1 | /* 2 | Steinberg Audio Stream I/O API 3 | (c) 1999, Steinberg Soft- und Hardware GmbH 4 | 5 | asiosmpl.h 6 | 7 | test implementation of asio 8 | */ 9 | 10 | #ifndef _asiosmpl_ 11 | #define _asiosmpl_ 12 | 13 | #include "asiosys.h" 14 | 15 | #define TESTWAVES 1 16 | // when true, will feed the left input (to host) with 17 | // a sine wave, and the right one with a sawtooth 18 | 19 | enum 20 | { 21 | kBlockFrames = 256, 22 | kNumInputs = 16, 23 | kNumOutputs = 16 24 | }; 25 | 26 | #if WINDOWS 27 | 28 | #include "rpc.h" 29 | #include "rpcndr.h" 30 | #ifndef COM_NO_WINDOWS_H 31 | #include 32 | #include "ole2.h" 33 | #endif 34 | 35 | #include "combase.h" 36 | #include "iasiodrv.h" 37 | 38 | class AsioSample : public IASIO, public CUnknown 39 | { 40 | public: 41 | AsioSample(LPUNKNOWN pUnk, HRESULT *phr); 42 | ~AsioSample(); 43 | 44 | DECLARE_IUNKNOWN 45 | //STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \ 46 | // return GetOwner()->QueryInterface(riid,ppv); \ 47 | //}; \ 48 | //STDMETHODIMP_(ULONG) AddRef() { \ 49 | // return GetOwner()->AddRef(); \ 50 | //}; \ 51 | //STDMETHODIMP_(ULONG) Release() { \ 52 | // return GetOwner()->Release(); \ 53 | //}; 54 | 55 | // Factory method 56 | static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); 57 | // IUnknown 58 | virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject); 59 | #else 60 | 61 | #include "asiodrvr.h" 62 | 63 | //--------------------------------------------------------------------------------------------- 64 | class AsioSample : public AsioDriver 65 | { 66 | public: 67 | AsioSample (); 68 | ~AsioSample (); 69 | #endif 70 | 71 | ASIOBool init (void* sysRef); 72 | void getDriverName (char *name); // max 32 bytes incl. terminating zero 73 | long getDriverVersion (); 74 | void getErrorMessage (char *string); // max 128 bytes incl. 75 | 76 | ASIOError start (); 77 | ASIOError stop (); 78 | 79 | ASIOError getChannels (long *numInputChannels, long *numOutputChannels); 80 | ASIOError getLatencies (long *inputLatency, long *outputLatency); 81 | ASIOError getBufferSize (long *minSize, long *maxSize, 82 | long *preferredSize, long *granularity); 83 | 84 | ASIOError canSampleRate (ASIOSampleRate sampleRate); 85 | ASIOError getSampleRate (ASIOSampleRate *sampleRate); 86 | ASIOError setSampleRate (ASIOSampleRate sampleRate); 87 | ASIOError getClockSources (ASIOClockSource *clocks, long *numSources); 88 | ASIOError setClockSource (long index); 89 | 90 | ASIOError getSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp); 91 | ASIOError getChannelInfo (ASIOChannelInfo *info); 92 | 93 | ASIOError createBuffers (ASIOBufferInfo *bufferInfos, long numChannels, 94 | long bufferSize, ASIOCallbacks *callbacks); 95 | ASIOError disposeBuffers (); 96 | 97 | ASIOError controlPanel (); 98 | ASIOError future (long selector, void *opt); 99 | ASIOError outputReady (); 100 | 101 | void bufferSwitch (); 102 | long getMilliSeconds () {return milliSeconds;} 103 | 104 | private: 105 | friend void myTimer(); 106 | 107 | bool inputOpen (); 108 | #if TESTWAVES 109 | void makeSine (short *wave); 110 | void makeSaw (short *wave); 111 | #endif 112 | void inputClose (); 113 | void input (); 114 | 115 | bool outputOpen (); 116 | void outputClose (); 117 | void output (); 118 | 119 | void timerOn (); 120 | void timerOff (); 121 | void bufferSwitchX (); 122 | 123 | double samplePosition; 124 | double sampleRate; 125 | ASIOCallbacks *callbacks; 126 | ASIOTime asioTime; 127 | ASIOTimeStamp theSystemTime; 128 | short *inputBuffers[kNumInputs * 2]; 129 | short *outputBuffers[kNumOutputs * 2]; 130 | #if TESTWAVES 131 | short *sineWave, *sawTooth; 132 | #endif 133 | long inMap[kNumInputs]; 134 | long outMap[kNumOutputs]; 135 | long blockFrames; 136 | long inputLatency; 137 | long outputLatency; 138 | long activeInputs; 139 | long activeOutputs; 140 | long toggle; 141 | long milliSeconds; 142 | bool active, started; 143 | bool timeInfoMode, tcRead; 144 | char errorMessage[128]; 145 | }; 146 | 147 | #endif 148 | 149 | -------------------------------------------------------------------------------- /ASIOSDK2.3/driver/asiosample/macnanosecs.cpp: -------------------------------------------------------------------------------- 1 | #include "asio.h" 2 | #include 3 | 4 | void getNanoSeconds(ASIOTimeStamp *time); 5 | 6 | static const double twoRaisedTo32 = 4294967296.; 7 | 8 | void getNanoSeconds(ASIOTimeStamp *time) 9 | { 10 | UnsignedWide ys; 11 | Microseconds(&ys); 12 | double r = 1000. * ((double)ys.hi * twoRaisedTo32 + (double)ys.lo); 13 | time->hi = (unsigned long)(r / twoRaisedTo32); 14 | time->lo = (unsigned long)(r - (double)time->hi * twoRaisedTo32); 15 | } 16 | -------------------------------------------------------------------------------- /ASIOSDK2.3/driver/asiosample/mactimer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Steinberg Audio Stream I/O API 3 | (c) 1996, Steinberg Soft- und Hardware GmbH 4 | charlie (May 1996) 5 | 6 | asiosmpl.cpp 7 | 8 | sample implementation of asio. 9 | time manager irq 10 | **** mac os specific **** 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include "asiosmpl.h" 17 | 18 | static TMTask myTmTask; 19 | static bool tmTaskOn = false; 20 | static AsioSample *theSound = 0; 21 | 22 | void myTimer(); 23 | void myTimer() 24 | { 25 | if(theSound) 26 | theSound->bufferSwitch(); 27 | PrimeTime((QElemPtr)&myTmTask, theSound->milliSeconds); 28 | } 29 | 30 | void AsioSample::timerOn() 31 | { 32 | theSound = this; // for irq 33 | if(!tmTaskOn) 34 | { 35 | memset(&myTmTask, 0, sizeof(TMTask)); 36 | myTmTask.tmAddr = NewTimerProc(myTimer); 37 | myTmTask.tmWakeUp = 0; 38 | tmTaskOn = true; 39 | InsXTime((QElemPtr)&myTmTask); 40 | PrimeTime((QElemPtr)&myTmTask, theSound->milliSeconds); 41 | } 42 | } 43 | 44 | void AsioSample::timerOff() 45 | { 46 | if(tmTaskOn) 47 | { 48 | RmvTime((QElemPtr)&myTmTask); 49 | tmTaskOn = false; 50 | } 51 | theSound = 0; 52 | } 53 | -------------------------------------------------------------------------------- /ASIOSDK2.3/driver/asiosample/makesamp.cpp: -------------------------------------------------------------------------------- 1 | #include "asiosmpl.h" 2 | 3 | AsioDriver *getDriver() 4 | { 5 | return new AsioSample(); 6 | } 7 | -------------------------------------------------------------------------------- /ASIOSDK2.3/driver/asiosample/wintimer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "asiosmpl.h" 3 | 4 | static DWORD __stdcall ASIOThread (void *param); 5 | static HANDLE ASIOThreadHandle = 0; 6 | static bool done = false; 7 | const double twoRaisedTo32 = 4294967296.; 8 | 9 | AsioSample* theDriver = 0; 10 | 11 | //------------------------------------------------------------------------------------------ 12 | void getNanoSeconds (ASIOTimeStamp* ts) 13 | { 14 | double nanoSeconds = (double)((unsigned long)timeGetTime ()) * 1000000.; 15 | ts->hi = (unsigned long)(nanoSeconds / twoRaisedTo32); 16 | ts->lo = (unsigned long)(nanoSeconds - (ts->hi * twoRaisedTo32)); 17 | } 18 | 19 | //------------------------------------------------------------------------------------------ 20 | void AsioSample::timerOn () 21 | { 22 | theDriver = this; 23 | DWORD asioId; 24 | done = false; 25 | ASIOThreadHandle = CreateThread (0, 0, &ASIOThread, 0, 0, &asioId); 26 | } 27 | 28 | //------------------------------------------------------------------------------------------ 29 | void AsioSample::timerOff () 30 | { 31 | done = true; 32 | if (ASIOThreadHandle) 33 | WaitForSingleObject(ASIOThreadHandle, 1000); 34 | ASIOThreadHandle = 0; 35 | } 36 | 37 | //------------------------------------------------------------------------------------------ 38 | static DWORD __stdcall ASIOThread (void *param) 39 | { 40 | do 41 | { 42 | if (theDriver) 43 | { 44 | theDriver->bufferSwitch (); 45 | Sleep (theDriver->getMilliSeconds ()); 46 | } 47 | else 48 | { 49 | double a = 1000. / 44100.; 50 | Sleep ((long)(a * (double)kBlockFrames)); 51 | 52 | } 53 | } while (!done); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /ASIOSDK2.3/host/ASIOConvertSamples.h: -------------------------------------------------------------------------------- 1 | #ifndef __ASIOConvertSamples__ 2 | #define __ASIOConvertSamples__ 3 | 4 | class ASIOConvertSamples 5 | { 6 | public: 7 | ASIOConvertSamples(); 8 | ~ASIOConvertSamples() {} 9 | 10 | // format converters, input 32 bit integer 11 | // mono 12 | void convertMono8(long *source, char *dest, long frames); 13 | void convertMono8Unsigned(long *source, char *dest, long frames); 14 | void convertMono16(long *source, short *dest, long frames); 15 | void convertMono16SmallEndian(long *source, short *dest, long frames); 16 | void convertMono24(long *source, char *dest, long frames); 17 | void convertMono24SmallEndian(long *source, char *dest, long frames); 18 | 19 | // stereo interleaved 20 | void convertStereo8Interleaved(long *left, long *right, char *dest, long frames); 21 | void convertStereo8InterleavedUnsigned(long *left, long *right, char *dest, long frames); 22 | void convertStereo16Interleaved(long *left, long *right, short *dest, long frames); 23 | void convertStereo16InterleavedSmallEndian(long *left, long *right, short *dest, long frames); 24 | void convertStereo24Interleaved(long *left, long *right, char *dest, long frames); 25 | void convertStereo24InterleavedSmallEndian(long *left, long *right, char *dest, long frames); 26 | 27 | // stereo split 28 | void convertStereo8(long *left, long *right, char *dLeft, char *dRight, long frames); 29 | void convertStereo8Unsigned(long *left, long *right, char *dLeft, char *dRight, long frames); 30 | void convertStereo16(long *left, long *right, short *dLeft, short *dRight, long frames); 31 | void convertStereo16SmallEndian(long *left, long *right, short *dLeft, short *dRight, long frames); 32 | void convertStereo24(long *left, long *right, char *dLeft, char *dRight, long frames); 33 | void convertStereo24SmallEndian(long *left, long *right, char *dLeft, char *dRight, long frames); 34 | 35 | // integer in place conversions 36 | 37 | void int32msb16to16inPlace(long *in, long frames); 38 | void int32lsb16to16inPlace(long *in, long frames); 39 | void int32msb16shiftedTo16inPlace(long *in1, long frames, long shift); 40 | void int24msbto16inPlace(unsigned char *in, long frames); 41 | 42 | // integer to integer 43 | 44 | void shift32(void* buffer, long shiftAmount, long targetByteWidth, 45 | bool reverseEndian, long frames); 46 | void reverseEndian(void* buffer, long byteWidth, long frames); 47 | 48 | void int32to16inPlace(void* buffer, long frames); 49 | void int24to16inPlace(void* buffer, long frames); 50 | void int32to24inPlace(void* buffer, long frames); 51 | void int16to24inPlace(void* buffer, long frames); 52 | void int24to32inPlace(void* buffer, long frames); 53 | void int16to32inPlace(void* buffer, long frames); 54 | 55 | // float to integer 56 | 57 | void float32toInt16inPlace(float* buffer, long frames); 58 | void float32toInt24inPlace(float* buffer, long frames); 59 | void float32toInt32inPlace(float* buffer, long frames); 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /ASIOSDK2.3/host/asiodrivers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "asiodrivers.h" 3 | 4 | AsioDrivers* asioDrivers = 0; 5 | 6 | bool loadAsioDriver(char *name); 7 | 8 | bool loadAsioDriver(char *name) 9 | { 10 | if(!asioDrivers) 11 | asioDrivers = new AsioDrivers(); 12 | if(asioDrivers) 13 | return asioDrivers->loadDriver(name); 14 | return false; 15 | } 16 | 17 | //------------------------------------------------------------------------------------ 18 | 19 | #if MAC 20 | 21 | bool resolveASIO(unsigned long aconnID); 22 | 23 | AsioDrivers::AsioDrivers() : CodeFragments("ASIO Drivers", 'AsDr', 'Asio') 24 | { 25 | connID = -1; 26 | curIndex = -1; 27 | } 28 | 29 | AsioDrivers::~AsioDrivers() 30 | { 31 | removeCurrentDriver(); 32 | } 33 | 34 | bool AsioDrivers::getCurrentDriverName(char *name) 35 | { 36 | if(curIndex >= 0) 37 | return getName(curIndex, name); 38 | return false; 39 | } 40 | 41 | long AsioDrivers::getDriverNames(char **names, long maxDrivers) 42 | { 43 | for(long i = 0; i < getNumFragments() && i < maxDrivers; i++) 44 | getName(i, names[i]); 45 | return getNumFragments() < maxDrivers ? getNumFragments() : maxDrivers; 46 | } 47 | 48 | bool AsioDrivers::loadDriver(char *name) 49 | { 50 | char dname[64]; 51 | unsigned long newID; 52 | 53 | for(long i = 0; i < getNumFragments(); i++) 54 | { 55 | if(getName(i, dname) && !strcmp(name, dname)) 56 | { 57 | if(newInstance(i, &newID)) 58 | { 59 | if(resolveASIO(newID)) 60 | { 61 | if(connID != -1) 62 | removeInstance(curIndex, connID); 63 | curIndex = i; 64 | connID = newID; 65 | return true; 66 | } 67 | } 68 | break; 69 | } 70 | } 71 | return false; 72 | } 73 | 74 | void AsioDrivers::removeCurrentDriver() 75 | { 76 | if(connID != -1) 77 | removeInstance(curIndex, connID); 78 | connID = -1; 79 | curIndex = -1; 80 | } 81 | 82 | //------------------------------------------------------------------------------------ 83 | 84 | #elif WINDOWS 85 | 86 | #include "iasiodrv.h" 87 | 88 | extern IASIO* theAsioDriver; 89 | 90 | AsioDrivers::AsioDrivers() : AsioDriverList() 91 | { 92 | curIndex = -1; 93 | } 94 | 95 | AsioDrivers::~AsioDrivers() 96 | { 97 | } 98 | 99 | bool AsioDrivers::getCurrentDriverName(char *name) 100 | { 101 | if(curIndex >= 0) 102 | return asioGetDriverName(curIndex, name, 32) == 0 ? true : false; 103 | name[0] = 0; 104 | return false; 105 | } 106 | 107 | long AsioDrivers::getDriverNames(char **names, long maxDrivers) 108 | { 109 | for(long i = 0; i < asioGetNumDev() && i < maxDrivers; i++) 110 | asioGetDriverName(i, names[i], 32); 111 | return asioGetNumDev() < maxDrivers ? asioGetNumDev() : maxDrivers; 112 | } 113 | 114 | bool AsioDrivers::loadDriver(char *name) 115 | { 116 | char dname[64]; 117 | char curName[64]; 118 | 119 | for(long i = 0; i < asioGetNumDev(); i++) 120 | { 121 | if(!asioGetDriverName(i, dname, 32) && !strcmp(name, dname)) 122 | { 123 | curName[0] = 0; 124 | getCurrentDriverName(curName); // in case we fail... 125 | removeCurrentDriver(); 126 | 127 | if(!asioOpenDriver(i, (void **)&theAsioDriver)) 128 | { 129 | curIndex = i; 130 | return true; 131 | } 132 | else 133 | { 134 | theAsioDriver = 0; 135 | if(curName[0] && strcmp(dname, curName)) 136 | loadDriver(curName); // try restore 137 | } 138 | break; 139 | } 140 | } 141 | return false; 142 | } 143 | 144 | void AsioDrivers::removeCurrentDriver() 145 | { 146 | if(curIndex != -1) 147 | asioCloseDriver(curIndex); 148 | curIndex = -1; 149 | } 150 | 151 | #elif SGI || BEOS 152 | 153 | #include "asiolist.h" 154 | 155 | AsioDrivers::AsioDrivers() 156 | : AsioDriverList() 157 | { 158 | curIndex = -1; 159 | } 160 | 161 | AsioDrivers::~AsioDrivers() 162 | { 163 | } 164 | 165 | bool AsioDrivers::getCurrentDriverName(char *name) 166 | { 167 | return false; 168 | } 169 | 170 | long AsioDrivers::getDriverNames(char **names, long maxDrivers) 171 | { 172 | return 0; 173 | } 174 | 175 | bool AsioDrivers::loadDriver(char *name) 176 | { 177 | return false; 178 | } 179 | 180 | void AsioDrivers::removeCurrentDriver() 181 | { 182 | } 183 | 184 | #else 185 | #error implement me 186 | #endif 187 | -------------------------------------------------------------------------------- /ASIOSDK2.3/host/asiodrivers.h: -------------------------------------------------------------------------------- 1 | #ifndef __AsioDrivers__ 2 | #define __AsioDrivers__ 3 | 4 | #include "ginclude.h" 5 | 6 | #if MAC 7 | #include "CodeFragments.hpp" 8 | 9 | class AsioDrivers : public CodeFragments 10 | 11 | #elif WINDOWS 12 | #include 13 | #include "asiolist.h" 14 | 15 | class AsioDrivers : public AsioDriverList 16 | 17 | #elif SGI || BEOS 18 | #include "asiolist.h" 19 | 20 | class AsioDrivers : public AsioDriverList 21 | 22 | #else 23 | #error implement me 24 | #endif 25 | 26 | { 27 | public: 28 | AsioDrivers(); 29 | ~AsioDrivers(); 30 | 31 | bool getCurrentDriverName(char *name); 32 | long getDriverNames(char **names, long maxDrivers); 33 | bool loadDriver(char *name); 34 | void removeCurrentDriver(); 35 | long getCurrentDriverIndex() {return curIndex;} 36 | protected: 37 | unsigned long connID; 38 | long curIndex; 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /ASIOSDK2.3/host/ginclude.h: -------------------------------------------------------------------------------- 1 | #ifndef __gInclude__ 2 | #define __gInclude__ 3 | 4 | #if SGI 5 | #undef BEOS 6 | #undef MAC 7 | #undef WINDOWS 8 | // 9 | #define ASIO_BIG_ENDIAN 1 10 | #define ASIO_CPU_MIPS 1 11 | #elif defined(_WIN32) || defined(_WIN64) 12 | #undef BEOS 13 | #undef MAC 14 | #undef SGI 15 | #define WINDOWS 1 16 | #define ASIO_LITTLE_ENDIAN 1 17 | #define ASIO_CPU_X86 1 18 | #elif BEOS 19 | #undef MAC 20 | #undef SGI 21 | #undef WINDOWS 22 | #define ASIO_LITTLE_ENDIAN 1 23 | #define ASIO_CPU_X86 1 24 | // 25 | #else 26 | #define MAC 1 27 | #undef BEOS 28 | #undef WINDOWS 29 | #undef SGI 30 | #define ASIO_BIG_ENDIAN 1 31 | #define ASIO_CPU_PPC 1 32 | #endif 33 | 34 | // always 35 | #define NATIVE_INT64 0 36 | #define IEEE754_64FLOAT 1 37 | 38 | #endif // __gInclude__ 39 | -------------------------------------------------------------------------------- /ASIOSDK2.3/host/mac/asioshlib.cpp: -------------------------------------------------------------------------------- 1 | // asio code fragment 'linker' 2 | // mac specific 3 | // loads the symbols via the fragment manager, and 4 | // translates them into function pointers. this 5 | // means no asio lib must be linked, as the 6 | // 'real' asio functions are here 7 | 8 | #include "ginclude.h" 9 | #include 10 | #include 11 | #include 12 | #include "asio.h" 13 | 14 | // Macro below has to 0 if external drivers will be used. 15 | // Can be set to 1 if a specific ASIO driver should be linked into the program 16 | #define ASIOINCLUDED 0 17 | 18 | 19 | 20 | // export 21 | bool resolveASIO(unsigned long aconnID); 22 | 23 | //------------------------------------------------------------------------------------------------------ 24 | // private 25 | 26 | #if ASIOINCLUDED 27 | bool resolveASIO(unsigned long aconnID) {aconnID = aconnID; return true;} 28 | #else 29 | 30 | enum 31 | { 32 | kASIOInit = 0, 33 | kASIOExit, 34 | kASIOStart, 35 | kASIOStop, 36 | kASIOGetChannels, 37 | kASIOGetLatencies, 38 | kASIOGetBufferSize, 39 | kASIOCanSampleRate, 40 | kASIOGetSampleRate, 41 | kASIOSetSampleRate, 42 | kASIOGetClockSources, 43 | kASIOSetClockSource, 44 | kASIOGetSamplePosition, 45 | kASIOGetChannelInfo, 46 | kASIOCreateBuffers, 47 | kASIODisposeBuffers, 48 | kASIOControlPanel, 49 | kASIOFuture, 50 | 51 | kASIOOutputReady, 52 | 53 | kNumSymbols, 54 | kRequiredSymbols = kNumSymbols - 1 55 | }; 56 | 57 | static char *asioTable[kNumSymbols] = 58 | { 59 | "ASIOInit", 60 | "ASIOExit", 61 | "ASIOStart", 62 | "ASIOStop", 63 | "ASIOGetChannels", 64 | "ASIOGetLatencies", 65 | "ASIOGetBufferSize", 66 | "ASIOCanSampleRate", 67 | "ASIOGetSampleRate", 68 | "ASIOSetSampleRate", 69 | "ASIOGetClockSources", 70 | "ASIOSetClockSource", 71 | "ASIOGetSamplePosition", 72 | "ASIOGetChannelInfo", 73 | "ASIOCreateBuffers", 74 | "ASIODisposeBuffers", 75 | "ASIOControlPanel", 76 | "ASIOFuture", 77 | "ASIOOutputReady" 78 | }; 79 | 80 | typedef ASIOError (*fasioInit) (ASIODriverInfo *info); 81 | typedef ASIOError (*fasioExit) (void); 82 | typedef ASIOError (*fasioStart) (void); 83 | typedef ASIOError (*fasioStop) (void); 84 | typedef ASIOError (*asioGetChannels) (long *numInputChannels, long *numOutputChannels); 85 | typedef ASIOError (*asioGetLatencies) (long *inputLatency, long *outputLatency); 86 | typedef ASIOError (*asioGetBufferSize) (long *minSize, long *maxSize, long *preferredSize, long *granularity); 87 | typedef ASIOError (*asioCanSampleRate) (ASIOSampleRate sampleRate); 88 | typedef ASIOError (*asioGetSampleRate) (ASIOSampleRate *currentRate); 89 | typedef ASIOError (*asioSetSampleRate) (ASIOSampleRate sampleRate); 90 | typedef ASIOError (*asioGetClockSources) (ASIOClockSource *clocks, long *numSources); 91 | typedef ASIOError (*asioSetClockSource) (long reference); 92 | typedef ASIOError (*asioGetSamplePosition) (ASIOSamples *sPos, ASIOTimeStamp *tStamp); 93 | typedef ASIOError (*asioGetChannelInfo) (ASIOChannelInfo *info); 94 | typedef ASIOError (*asioCreateBuffers) (ASIOBufferInfo *channelInfos, long numChannels, 95 | long bufferSize, ASIOCallbacks *callbacks); 96 | typedef ASIOError (*asioDisposeBuffers) (void); 97 | typedef ASIOError (*asioControlPanel) (void); 98 | typedef ASIOError (*asioFuture)(long selector, void *opt); 99 | typedef ASIOError (*asioOutputReady) (void); 100 | 101 | static void *functionTable[kNumSymbols] = {0}; 102 | static bool inited = false; 103 | 104 | //--------------------------------------------------------------------------------------------------------- 105 | 106 | #include 107 | 108 | bool resolveASIO(unsigned long aconnID) 109 | { 110 | OSErr err; 111 | CFragConnectionID connID = (CFragConnectionID)aconnID; 112 | CFragSymbolClass symClass; 113 | Ptr symAddr = nil; 114 | Str255 myName; 115 | long myCount = 0; 116 | 117 | err = CountSymbols(connID, &myCount); 118 | if(err != noErr || myCount < (kRequiredSymbols + 1)) // there must be a main() 119 | return false; 120 | 121 | long n, c = 0; 122 | for(n = kRequiredSymbols; n < kNumSymbols; n++) 123 | functionTable[n] = 0; 124 | for(n = 0; n < myCount; n++) 125 | { 126 | // we can't use FindSymbol(), as the compiler adds mangling 127 | // (such as ASIOInit__Fv). also, the symbols don't appear 128 | // in the order they are declared or implemented. 129 | // so we use strncmp() 130 | err = GetIndSymbol(connID, n, myName, &symAddr, &symClass); 131 | if(err != noErr) 132 | break; 133 | PtoCstr(myName); 134 | if(!strncmp((char *)myName, "main", 4L)) 135 | c++; 136 | else 137 | { 138 | for(long i = 0; i < kNumSymbols; i++) 139 | { 140 | long sc = strlen(asioTable[i]); 141 | if(!strncmp((char *)myName, asioTable[i], sc)) 142 | { 143 | functionTable[i] = symAddr; 144 | if(i < kRequiredSymbols) 145 | c++; 146 | break; 147 | } 148 | } 149 | } 150 | // if(c >= kNumSymbols + 1) 151 | // break; 152 | } 153 | if(c >= kRequiredSymbols + 1) 154 | { 155 | inited = true; 156 | return true; 157 | } 158 | return false; 159 | } 160 | 161 | //--------------------------------------------------------------------------------------------------- 162 | //--------------------------------------------------------------------------------------------------- 163 | 164 | #pragma export on 165 | 166 | static short curRes = 0; 167 | #define saveRes() curRes = CurResFile() 168 | #define restRes() UseResFile(curRes); 169 | 170 | 171 | ASIOError ASIOInit(ASIODriverInfo *info) 172 | { 173 | saveRes(); 174 | strcpy(info->errorMessage, "No ASIO Driver could be Loaded!"); 175 | if(!inited) 176 | return ASE_NotPresent; 177 | fasioInit f = (fasioInit)functionTable[kASIOInit]; 178 | ASIOError e = (*f)(info); 179 | restRes(); 180 | return e; 181 | } 182 | 183 | ASIOError ASIOExit(void) 184 | { 185 | if(!inited) 186 | return ASE_NotPresent; 187 | saveRes(); 188 | fasioExit f = (fasioExit)functionTable[kASIOExit]; 189 | ASIOError e = (*f)(); 190 | restRes(); 191 | return e; 192 | } 193 | 194 | ASIOError ASIOStart(void) 195 | { 196 | if(!inited) 197 | return ASE_NotPresent; 198 | fasioStart f = (fasioStart)functionTable[kASIOStart]; 199 | return (*f)(); 200 | } 201 | 202 | ASIOError ASIOStop(void) 203 | { 204 | if(!inited) 205 | return ASE_NotPresent; 206 | fasioStop f = (fasioStop)functionTable[kASIOStop]; 207 | return (*f)(); 208 | } 209 | 210 | ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels) 211 | { 212 | if(!inited) 213 | return ASE_NotPresent; 214 | asioGetChannels f = (asioGetChannels)functionTable[kASIOGetChannels]; 215 | return (*f)(numInputChannels, numOutputChannels); 216 | } 217 | 218 | ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency) 219 | { 220 | if(!inited) 221 | return ASE_NotPresent; 222 | asioGetLatencies f = (asioGetLatencies)functionTable[kASIOGetLatencies]; 223 | return (*f)(inputLatency, outputLatency); 224 | } 225 | 226 | ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity) 227 | { 228 | if(!inited) 229 | return ASE_NotPresent; 230 | asioGetBufferSize f = (asioGetBufferSize)functionTable[kASIOGetBufferSize]; 231 | return (*f)(minSize, maxSize, preferredSize, granularity); 232 | } 233 | 234 | ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate) 235 | { 236 | if(!inited) 237 | return ASE_NotPresent; 238 | asioCanSampleRate f = (asioCanSampleRate)functionTable[kASIOCanSampleRate]; 239 | return (*f)(sampleRate); 240 | } 241 | 242 | ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate) 243 | { 244 | if(!inited) 245 | return ASE_NotPresent; 246 | asioGetSampleRate f = (asioGetSampleRate)functionTable[kASIOGetSampleRate]; 247 | return (*f)(currentRate); 248 | } 249 | 250 | ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate) 251 | { 252 | if(!inited) 253 | return ASE_NotPresent; 254 | asioSetSampleRate f = (asioSetSampleRate)functionTable[kASIOSetSampleRate]; 255 | return (*f)(sampleRate); 256 | } 257 | 258 | ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources) 259 | { 260 | if(!inited) 261 | return ASE_NotPresent; 262 | asioGetClockSources f = (asioGetClockSources)functionTable[kASIOGetClockSources]; 263 | return (*f)(clocks, numSources); 264 | } 265 | 266 | ASIOError ASIOSetClockSource(long reference) 267 | { 268 | if(!inited) 269 | return ASE_NotPresent; 270 | asioSetClockSource f = (asioSetClockSource)functionTable[kASIOSetClockSource]; 271 | return (*f)(reference); 272 | } 273 | 274 | ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) 275 | { 276 | if(!inited) 277 | return ASE_NotPresent; 278 | asioGetSamplePosition f = (asioGetSamplePosition)functionTable[kASIOGetSamplePosition]; 279 | return (*f)(sPos, tStamp); 280 | } 281 | 282 | ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info) 283 | { 284 | if(!inited) 285 | return ASE_NotPresent; 286 | asioGetChannelInfo f = (asioGetChannelInfo)functionTable[kASIOGetChannelInfo]; 287 | return (*f)(info); 288 | } 289 | 290 | ASIOError ASIOCreateBuffers(ASIOBufferInfo *channelInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks) 291 | { 292 | if(!inited) 293 | return ASE_NotPresent; 294 | saveRes(); 295 | asioCreateBuffers f = (asioCreateBuffers)functionTable[kASIOCreateBuffers]; 296 | ASIOError e = (*f)(channelInfos, numChannels, bufferSize, callbacks); 297 | restRes(); 298 | return e; 299 | } 300 | 301 | ASIOError ASIODisposeBuffers(void) 302 | { 303 | if(!inited) 304 | return ASE_NotPresent; 305 | asioDisposeBuffers f = (asioDisposeBuffers)functionTable[kASIODisposeBuffers]; 306 | return (*f)(); 307 | } 308 | 309 | ASIOError ASIOControlPanel(void) 310 | { 311 | if(!inited) 312 | return ASE_NotPresent; 313 | saveRes(); 314 | asioControlPanel f = (asioControlPanel)functionTable[kASIOControlPanel]; 315 | ASIOError e = (*f)(); 316 | restRes(); 317 | return e; 318 | } 319 | 320 | ASIOError ASIOFuture(long selector, void *opt) 321 | { 322 | if(!inited) 323 | return 0; 324 | saveRes(); 325 | asioFuture f = (asioFuture)functionTable[kASIOFuture]; 326 | ASIOError e = (*f)(selector, opt); 327 | restRes(); 328 | return e; 329 | } 330 | 331 | ASIOError ASIOOutputReady(void) 332 | { 333 | asioOutputReady f = (asioControlPanel)functionTable[kASIOOutputReady]; 334 | if(!inited || !f) 335 | return ASE_NotPresent; 336 | return (*f)(); 337 | } 338 | 339 | #pragma export off 340 | 341 | #endif // ASIOINCLUDED 342 | 343 | -------------------------------------------------------------------------------- /ASIOSDK2.3/host/mac/codefragments.cpp: -------------------------------------------------------------------------------- 1 | // very MAC specific; generic code fragment handler 2 | #include "ginclude.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "CodeFragments.hpp" 8 | 9 | enum 10 | { 11 | kNewCFragCopy = kPrivateCFragCopy 12 | }; 13 | 14 | class CodeFragmentInstance 15 | { 16 | private: 17 | friend class CodeFragment; 18 | CodeFragmentInstance() {next = 0; handle = 0; connID = (void*)-1;} 19 | ~CodeFragmentInstance() {CloseConnection((CFragConnectionID*)&connID); DisposeHandle(handle);} 20 | 21 | CodeFragmentInstance *next; 22 | Handle handle; 23 | void* connID; 24 | }; 25 | 26 | class CodeFragment 27 | { 28 | public: 29 | CodeFragment(); 30 | ~CodeFragment(); 31 | 32 | bool newInstance(void** cID); 33 | void removeInstance(void* id); 34 | bool getName(char *name) {if(!resName[0]) return false; strcpy(name, resName); return true;} 35 | 36 | private: 37 | friend class CodeFragments; 38 | 39 | CodeFragment *next; 40 | CodeFragmentInstance *root; 41 | Handle handle; 42 | long numInstances; 43 | long index; 44 | char resName[64]; 45 | }; 46 | 47 | //------------------------------------------------------------------------------------------ 48 | 49 | CodeFragment::CodeFragment() 50 | { 51 | next = 0; 52 | root = 0; 53 | handle = 0; 54 | numInstances = 0; 55 | index = 0; 56 | resName[0] = 0; 57 | } 58 | 59 | CodeFragment::~CodeFragment() 60 | { 61 | // could delete all instances 62 | // rather omit it... 63 | } 64 | 65 | bool CodeFragment::newInstance(void** cID) 66 | { 67 | Ptr myMainAddr; 68 | Str255 myErrName; 69 | char pname[256]; 70 | 71 | *cID = (void*)-1; 72 | if(!handle) 73 | return false; 74 | CodeFragmentInstance *c = new CodeFragmentInstance(); 75 | if(!c) 76 | return false; 77 | c->handle = this->handle; 78 | OSErr err = HandToHand(&c->handle); 79 | if(err == noErr) 80 | { 81 | // use fragment loader 82 | myMainAddr = 0; 83 | strcpy(pname, resName); 84 | CtoPstr(pname); 85 | err = GetMemFragment(*handle, GetHandleSize(handle), 86 | (unsigned char *)pname, kNewCFragCopy, (CFragConnectionID*)&c->connID, 87 | &myMainAddr, myErrName); 88 | if(err == noErr && myMainAddr) 89 | { 90 | if(!root) 91 | root = c; 92 | else 93 | { 94 | CodeFragmentInstance *cc = root; 95 | while(cc->next) 96 | cc = cc->next; 97 | cc->next = c; 98 | } 99 | numInstances++; 100 | *cID = c->connID; 101 | return true; 102 | } 103 | } 104 | return false; 105 | } 106 | 107 | void CodeFragment::removeInstance(void* id) 108 | { 109 | CodeFragmentInstance *c = root, *last = root; 110 | while(c) 111 | { 112 | if(c->connID == id) 113 | { 114 | if(c == root) 115 | root = root->next; 116 | else 117 | last->next = c->next; 118 | delete c; 119 | numInstances--; 120 | return; 121 | } 122 | last = c; 123 | c = c->next; 124 | } 125 | } 126 | 127 | //---------------------------------------------------------------------------------------- 128 | //---------------------------------------------------------------------------------------- 129 | 130 | CodeFragments::CodeFragments(char *folderName, long fileType, long resType) 131 | { 132 | root = 0; 133 | numFragments = 0; 134 | gARefNum = -1; 135 | 136 | if(setFolder(folderName)) 137 | { 138 | loadFragments(gARefNum, fileType, resType); 139 | SetVol(0L, defVol); 140 | } 141 | } 142 | 143 | CodeFragments::~CodeFragments() 144 | { 145 | while(root) 146 | { 147 | CodeFragment *c = root->next; 148 | delete root; 149 | root = c; 150 | } 151 | } 152 | 153 | bool CodeFragments::newInstance(long index, unsigned long* cID) 154 | { 155 | *cID = -1; 156 | CodeFragment *c = root; 157 | while(c) 158 | { 159 | if(c->index == index) 160 | return c->newInstance((void**)cID); 161 | c = c->next; 162 | } 163 | return false; 164 | } 165 | 166 | void CodeFragments::removeInstance(long index, unsigned long cID) 167 | { 168 | CodeFragment *c = root; 169 | while(c) 170 | { 171 | if(c->index == index) 172 | { 173 | c->removeInstance((void*)cID); 174 | break; 175 | } 176 | c = c->next; 177 | } 178 | } 179 | 180 | bool CodeFragments::getName(long index, char *name) 181 | { 182 | CodeFragment *c = root; 183 | while(c) 184 | { 185 | if(c->index == index) 186 | { 187 | strcpy(name, c->resName); 188 | return true; 189 | } 190 | c = c->next; 191 | } 192 | return false; 193 | } 194 | 195 | //------------------------------------------------------------------------------------ 196 | // private 197 | 198 | void CodeFragments::loadFragments(short folderRef, long fileType, long resType) 199 | { 200 | Str255 fileName; 201 | HFileParam parmblock; 202 | short resRef,index = 1,lindex; 203 | short resID; 204 | ResType resourceType; 205 | Str255 resName; 206 | Handle h; 207 | short curResFile = CurResFile(); 208 | 209 | while(true) 210 | { 211 | // find any file in the folder 212 | memset (&parmblock,0,(long)sizeof(HFileParam)); 213 | parmblock.ioNamePtr = fileName; 214 | parmblock.ioVRefNum = folderRef; 215 | parmblock.ioFDirIndex = index; 216 | if(PBHGetFInfoSync ((HParmBlkPtr)&parmblock) != noErr) 217 | break; 218 | 219 | // see if the file type matches 220 | if(parmblock.ioFlFndrInfo.fdType == fileType) 221 | { 222 | resRef = OpenResFile(fileName); 223 | if(ResError()==noErr) 224 | { 225 | UseResFile(resRef); 226 | lindex = 1; 227 | // search resources in the file found which match 228 | while(true) 229 | { 230 | h = Get1IndResource(resType, lindex); 231 | if(h) 232 | { 233 | CodeFragment *c = new CodeFragment; 234 | if(!root) 235 | root = c; 236 | else 237 | { 238 | CodeFragment *cc = root; 239 | while(cc->next) 240 | cc = cc->next; 241 | cc->next = c; 242 | } 243 | GetResInfo(h, &resID, &resourceType, resName); 244 | // PtoCstr(fileName); 245 | // strcpy(c->fileName, (char *)fileName); 246 | PtoCstr(resName); 247 | strcpy(c->resName, (char*)resName); 248 | DetachResource(h); 249 | HLockHi(h); 250 | c->handle = h; 251 | c->index = numFragments; 252 | numFragments++; 253 | } 254 | else 255 | break; 256 | lindex++; 257 | } 258 | CloseResFile(resRef); 259 | } 260 | } 261 | index++; 262 | } 263 | UseResFile(curResFile); 264 | } 265 | 266 | //----------------------------------------------------------------------------------------- 267 | 268 | bool CodeFragments::setFolder(char *folderName) 269 | { 270 | FSSpec fss; 271 | 272 | if(gARefNum == -1) 273 | { 274 | if(!getFrontProcessDirectory(&fss)) 275 | return false; 276 | if(!openFragmentFolder(&fss, folderName, &gARefNum)) 277 | return false; 278 | } 279 | defVol = getDefVol(); 280 | SetVol(0L, gARefNum); 281 | return true; 282 | } 283 | 284 | bool CodeFragments::getFrontProcessDirectory(void *specs) 285 | { 286 | FSSpec *fss = (FSSpec *)specs; 287 | ProcessInfoRec pif; 288 | ProcessSerialNumber psn; 289 | 290 | memset(&psn,0,(long)sizeof(ProcessSerialNumber)); 291 | if(GetFrontProcess(&psn) == noErr) 292 | { 293 | pif.processName = 0; //(StringPtr)name; 294 | pif.processAppSpec = fss; 295 | pif.processInfoLength = sizeof(ProcessInfoRec); 296 | if(GetProcessInformation(&psn, &pif) == noErr) 297 | return true; 298 | } 299 | return false; 300 | } 301 | 302 | bool CodeFragments::openFragmentFolder(void *specs, char *foldername, short *found_vref) 303 | { 304 | FSSpec *fss = (FSSpec *)specs; 305 | WDPBRec funcparms,homefolder; 306 | HFileInfo my_funcfolder; 307 | char funcFolder_name[32]; 308 | 309 | *found_vref = -1; 310 | strcpy(funcFolder_name,foldername); 311 | CtoPstr(funcFolder_name); 312 | 313 | memset (&homefolder,0,(long)sizeof(WDPBRec)); 314 | homefolder.ioVRefNum = fss->vRefNum; 315 | homefolder.ioWDDirID = fss->parID; 316 | if(PBOpenWDSync(&homefolder) != noErr) 317 | return false; 318 | memset(&my_funcfolder,0,(long)sizeof(CInfoPBRec)); 319 | my_funcfolder.ioNamePtr = (StringPtr)funcFolder_name; 320 | my_funcfolder.ioVRefNum = homefolder.ioVRefNum; 321 | if(PBGetCatInfoSync((CInfoPBPtr)&my_funcfolder) != noErr) 322 | { 323 | PBCloseWDSync(&homefolder); 324 | return false; 325 | } 326 | memset (&funcparms,0,(long)sizeof(WDPBRec)); 327 | funcparms.ioWDProcID = 'stCA'; 328 | funcparms.ioVRefNum = my_funcfolder.ioVRefNum; 329 | funcparms.ioWDDirID = my_funcfolder.ioDirID; 330 | if(PBOpenWDSync(&funcparms) != noErr) 331 | { 332 | PBCloseWDSync(&homefolder); 333 | return false; 334 | } 335 | PBCloseWDSync(&homefolder); 336 | *found_vref = funcparms.ioVRefNum; 337 | return true; 338 | } 339 | 340 | short CodeFragments::getDefVol() 341 | { 342 | unsigned char text[32]; 343 | short vol_ref = 0; 344 | 345 | *text=0; 346 | if(GetVol(text, &vol_ref) == noErr) 347 | return (vol_ref); 348 | return 0; 349 | } 350 | -------------------------------------------------------------------------------- /ASIOSDK2.3/host/mac/codefragments.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __CodeFragments__ 2 | #define __CodeFragments__ 3 | 4 | class CodeFragment; 5 | 6 | class CodeFragments 7 | { 8 | public: 9 | CodeFragments(char *folderName, long fileType, long resType); 10 | ~CodeFragments(); 11 | 12 | long getNumFragments() {return numFragments;} 13 | bool newInstance(long index, unsigned long *cID); 14 | void removeInstance(long index, unsigned long cID); 15 | bool getName(long index, char *name); 16 | 17 | protected: 18 | void loadFragments(short folderRef, long fileType, long resType); 19 | bool setFolder(char *folderName); 20 | bool openFragmentFolder(void *specs, char *foldername, short *found_vref); 21 | bool getFrontProcessDirectory(void *specs); 22 | short getDefVol(); 23 | 24 | CodeFragment *root; 25 | long numFragments; 26 | short gARefNum; 27 | short defVol; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /ASIOSDK2.3/host/pc/asiolist.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "iasiodrv.h" 3 | #include "asiolist.h" 4 | 5 | #define ASIODRV_DESC "description" 6 | #define INPROC_SERVER "InprocServer32" 7 | #define ASIO_PATH "software\\asio" 8 | #define COM_CLSID "clsid" 9 | 10 | // ****************************************************************** 11 | // Local Functions 12 | // ****************************************************************** 13 | static LONG findDrvPath (char *clsidstr,char *dllpath,int dllpathsize) 14 | { 15 | HKEY hkEnum,hksub,hkpath; 16 | char databuf[512]; 17 | LONG cr,rc = -1; 18 | DWORD datatype,datasize; 19 | DWORD index; 20 | OFSTRUCT ofs; 21 | HFILE hfile; 22 | BOOL found = FALSE; 23 | 24 | CharLowerBuff(clsidstr,strlen(clsidstr)); 25 | if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) { 26 | 27 | index = 0; 28 | while (cr == ERROR_SUCCESS && !found) { 29 | cr = RegEnumKey(hkEnum,index++,(LPTSTR)databuf,512); 30 | if (cr == ERROR_SUCCESS) { 31 | CharLowerBuff(databuf,strlen(databuf)); 32 | if (!(strcmp(databuf,clsidstr))) { 33 | if ((cr = RegOpenKeyEx(hkEnum,(LPCTSTR)databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) { 34 | if ((cr = RegOpenKeyEx(hksub,(LPCTSTR)INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) { 35 | datatype = REG_SZ; datasize = (DWORD)dllpathsize; 36 | cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize); 37 | if (cr == ERROR_SUCCESS) { 38 | memset(&ofs,0,sizeof(OFSTRUCT)); 39 | ofs.cBytes = sizeof(OFSTRUCT); 40 | hfile = OpenFile(dllpath,&ofs,OF_EXIST); 41 | if (hfile) rc = 0; 42 | } 43 | RegCloseKey(hkpath); 44 | } 45 | RegCloseKey(hksub); 46 | } 47 | found = TRUE; // break out 48 | } 49 | } 50 | } 51 | RegCloseKey(hkEnum); 52 | } 53 | return rc; 54 | } 55 | 56 | 57 | static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv) 58 | { 59 | HKEY hksub; 60 | char databuf[256]; 61 | char dllpath[MAXPATHLEN]; 62 | WORD wData[100]; 63 | CLSID clsid; 64 | DWORD datatype,datasize; 65 | LONG cr,rc; 66 | 67 | if (!lpdrv) { 68 | if ((cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) { 69 | 70 | datatype = REG_SZ; datasize = 256; 71 | cr = RegQueryValueEx(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize); 72 | if (cr == ERROR_SUCCESS) { 73 | rc = findDrvPath (databuf,dllpath,MAXPATHLEN); 74 | if (rc == 0) { 75 | lpdrv = new ASIODRVSTRUCT[1]; 76 | if (lpdrv) { 77 | memset(lpdrv,0,sizeof(ASIODRVSTRUCT)); 78 | lpdrv->drvID = drvID; 79 | MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100); 80 | if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) { 81 | memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID)); 82 | } 83 | 84 | datatype = REG_SZ; datasize = 256; 85 | cr = RegQueryValueEx(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize); 86 | if (cr == ERROR_SUCCESS) { 87 | strcpy(lpdrv->drvname,databuf); 88 | } 89 | else strcpy(lpdrv->drvname,keyname); 90 | } 91 | } 92 | } 93 | RegCloseKey(hksub); 94 | } 95 | } 96 | else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next); 97 | 98 | return lpdrv; 99 | } 100 | 101 | static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv) 102 | { 103 | IASIO *iasio; 104 | 105 | if (lpdrv != 0) { 106 | deleteDrvStruct(lpdrv->next); 107 | if (lpdrv->asiodrv) { 108 | iasio = (IASIO *)lpdrv->asiodrv; 109 | iasio->Release(); 110 | } 111 | delete lpdrv; 112 | } 113 | } 114 | 115 | 116 | static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv) 117 | { 118 | while (lpdrv) { 119 | if (lpdrv->drvID == drvID) return lpdrv; 120 | lpdrv = lpdrv->next; 121 | } 122 | return 0; 123 | } 124 | // ****************************************************************** 125 | 126 | 127 | // ****************************************************************** 128 | // AsioDriverList 129 | // ****************************************************************** 130 | AsioDriverList::AsioDriverList () 131 | { 132 | HKEY hkEnum = 0; 133 | char keyname[MAXDRVNAMELEN]; 134 | LPASIODRVSTRUCT pdl; 135 | LONG cr; 136 | DWORD index = 0; 137 | BOOL fin = FALSE; 138 | 139 | numdrv = 0; 140 | lpdrvlist = 0; 141 | 142 | cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum); 143 | while (cr == ERROR_SUCCESS) { 144 | if ((cr = RegEnumKey(hkEnum,index++,(LPTSTR)keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) { 145 | lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist); 146 | } 147 | else fin = TRUE; 148 | } 149 | if (hkEnum) RegCloseKey(hkEnum); 150 | 151 | pdl = lpdrvlist; 152 | while (pdl) { 153 | numdrv++; 154 | pdl = pdl->next; 155 | } 156 | 157 | if (numdrv) CoInitialize(0); // initialize COM 158 | } 159 | 160 | AsioDriverList::~AsioDriverList () 161 | { 162 | if (numdrv) { 163 | deleteDrvStruct(lpdrvlist); 164 | CoUninitialize(); 165 | } 166 | } 167 | 168 | 169 | LONG AsioDriverList::asioGetNumDev (VOID) 170 | { 171 | return (LONG)numdrv; 172 | } 173 | 174 | 175 | LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv) 176 | { 177 | LPASIODRVSTRUCT lpdrv = 0; 178 | long rc; 179 | 180 | if (!asiodrv) return DRVERR_INVALID_PARAM; 181 | 182 | if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { 183 | if (!lpdrv->asiodrv) { 184 | rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv); 185 | if (rc == S_OK) { 186 | lpdrv->asiodrv = *asiodrv; 187 | return 0; 188 | } 189 | // else if (rc == REGDB_E_CLASSNOTREG) 190 | // strcpy (info->messageText, "Driver not registered in the Registration Database!"); 191 | } 192 | else rc = DRVERR_DEVICE_ALREADY_OPEN; 193 | } 194 | else rc = DRVERR_DEVICE_NOT_FOUND; 195 | 196 | return rc; 197 | } 198 | 199 | 200 | LONG AsioDriverList::asioCloseDriver (int drvID) 201 | { 202 | LPASIODRVSTRUCT lpdrv = 0; 203 | IASIO *iasio; 204 | 205 | if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { 206 | if (lpdrv->asiodrv) { 207 | iasio = (IASIO *)lpdrv->asiodrv; 208 | iasio->Release(); 209 | lpdrv->asiodrv = 0; 210 | } 211 | } 212 | 213 | return 0; 214 | } 215 | 216 | LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize) 217 | { 218 | LPASIODRVSTRUCT lpdrv = 0; 219 | 220 | if (!drvname) return DRVERR_INVALID_PARAM; 221 | 222 | if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { 223 | if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) { 224 | strcpy(drvname,lpdrv->drvname); 225 | } 226 | else { 227 | memcpy(drvname,lpdrv->drvname,drvnamesize-4); 228 | drvname[drvnamesize-4] = '.'; 229 | drvname[drvnamesize-3] = '.'; 230 | drvname[drvnamesize-2] = '.'; 231 | drvname[drvnamesize-1] = 0; 232 | } 233 | return 0; 234 | } 235 | return DRVERR_DEVICE_NOT_FOUND; 236 | } 237 | 238 | LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize) 239 | { 240 | LPASIODRVSTRUCT lpdrv = 0; 241 | 242 | if (!dllpath) return DRVERR_INVALID_PARAM; 243 | 244 | if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { 245 | if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) { 246 | strcpy(dllpath,lpdrv->dllpath); 247 | return 0; 248 | } 249 | dllpath[0] = 0; 250 | return DRVERR_INVALID_PARAM; 251 | } 252 | return DRVERR_DEVICE_NOT_FOUND; 253 | } 254 | 255 | LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid) 256 | { 257 | LPASIODRVSTRUCT lpdrv = 0; 258 | 259 | if (!clsid) return DRVERR_INVALID_PARAM; 260 | 261 | if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { 262 | memcpy(clsid,&lpdrv->clsid,sizeof(CLSID)); 263 | return 0; 264 | } 265 | return DRVERR_DEVICE_NOT_FOUND; 266 | } 267 | 268 | 269 | -------------------------------------------------------------------------------- /ASIOSDK2.3/host/pc/asiolist.h: -------------------------------------------------------------------------------- 1 | #ifndef __asiolist__ 2 | #define __asiolist__ 3 | 4 | #define DRVERR -5000 5 | #define DRVERR_INVALID_PARAM DRVERR-1 6 | #define DRVERR_DEVICE_ALREADY_OPEN DRVERR-2 7 | #define DRVERR_DEVICE_NOT_FOUND DRVERR-3 8 | 9 | #define MAXPATHLEN 512 10 | #define MAXDRVNAMELEN 128 11 | 12 | struct asiodrvstruct 13 | { 14 | int drvID; 15 | CLSID clsid; 16 | char dllpath[MAXPATHLEN]; 17 | char drvname[MAXDRVNAMELEN]; 18 | LPVOID asiodrv; 19 | struct asiodrvstruct *next; 20 | }; 21 | 22 | typedef struct asiodrvstruct ASIODRVSTRUCT; 23 | typedef ASIODRVSTRUCT *LPASIODRVSTRUCT; 24 | 25 | class AsioDriverList { 26 | public: 27 | AsioDriverList(); 28 | ~AsioDriverList(); 29 | 30 | LONG asioOpenDriver (int,VOID **); 31 | LONG asioCloseDriver (int); 32 | 33 | // nice to have 34 | LONG asioGetNumDev (VOID); 35 | LONG asioGetDriverName (int,char *,int); 36 | LONG asioGetDriverPath (int,char *,int); 37 | LONG asioGetDriverCLSID (int,CLSID *); 38 | 39 | // or use directly access 40 | LPASIODRVSTRUCT lpdrvlist; 41 | int numdrv; 42 | }; 43 | 44 | typedef class AsioDriverList *LPASIODRIVERLIST; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /ASIOSDK2.3/host/sample/hostsample.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="hostsample" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=hostsample - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "hostsample.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "hostsample.mak" CFG="hostsample - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "hostsample - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "hostsample - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "hostsample - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c 45 | # ADD CPP /nologo /W3 /GX /O2 /I "../../common" /I "../../host" /I "../../host/pc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 46 | # ADD BASE RSC /l 0x809 /d "NDEBUG" 47 | # ADD RSC /l 0x809 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /machine:I386 54 | 55 | !ELSEIF "$(CFG)" == "hostsample - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "Debug" 60 | # PROP BASE Intermediate_Dir "Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "Debug" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c 69 | # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../common" /I "../../host" /I "../../host/pc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x809 /d "_DEBUG" 71 | # ADD RSC /l 0x809 /d "_DEBUG" 72 | BSC32=bscmake.exe 73 | # ADD BASE BSC32 /nologo 74 | # ADD BSC32 /nologo 75 | LINK32=link.exe 76 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | 79 | !ENDIF 80 | 81 | # Begin Target 82 | 83 | # Name "hostsample - Win32 Release" 84 | # Name "hostsample - Win32 Debug" 85 | # Begin Group "Source Files" 86 | 87 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\common\asio.cpp 91 | # End Source File 92 | # Begin Source File 93 | 94 | SOURCE=..\asiodrivers.cpp 95 | # End Source File 96 | # Begin Source File 97 | 98 | SOURCE=..\pc\asiolist.cpp 99 | # End Source File 100 | # Begin Source File 101 | 102 | SOURCE=.\hostsample.cpp 103 | # End Source File 104 | # End Group 105 | # Begin Group "Header Files" 106 | 107 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 108 | # Begin Source File 109 | 110 | SOURCE=..\..\common\asio.h 111 | # End Source File 112 | # Begin Source File 113 | 114 | SOURCE=..\asiodrivers.h 115 | # End Source File 116 | # Begin Source File 117 | 118 | SOURCE=..\pc\asiolist.h 119 | # End Source File 120 | # Begin Source File 121 | 122 | SOURCE=..\ginclude.h 123 | # End Source File 124 | # End Group 125 | # Begin Group "Resource Files" 126 | 127 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 128 | # End Group 129 | # Begin Source File 130 | 131 | SOURCE=.\ReadMe.txt 132 | # End Source File 133 | # End Target 134 | # End Project 135 | -------------------------------------------------------------------------------- /ASIOSDK2.3/readme.txt: -------------------------------------------------------------------------------- 1 | ASIO 2.3 SDK Contents 2 | --------------------- 3 | 4 | readme.txt - this file 5 | changes.txt - contains change information between 6 | SDK releases 7 | ASIO SDK 2.3.pdf - ASIO SDK 2.3 specification 8 | Steinberg ASIO Licensing Agreement.pdf - Licencing Agreement 9 | 10 | common: 11 | asio.h - ASIO C definition 12 | iasiodrv.h - interface definition for the ASIO driver class 13 | asio.cpp - asio host interface (not used on Mac) 14 | asiodrvr.h 15 | asiodrvr.cpp - ASIO driver class base definition 16 | combase.h 17 | combase.cpp - COM base definitions (PC only) 18 | dllentry.cpp - DLL functions (PC only) 19 | register.cpp - driver self registration functionality 20 | wxdebug.h 21 | debugmessage.cpp - some debugging help 22 | 23 | host: 24 | asiodrivers.h 25 | asiodrivers.cpp - ASIO driver managment (enumeration and instantiation) 26 | ASIOConvertSamples.h 27 | ASIOConvertSamples.cpp - sample data format conversion class 28 | ginclude.h - platform specific definitions 29 | 30 | host/mac: 31 | asioshlib.cpp - asio.cpp for the Mac, resolves the symbols 32 | codefragments.hpp 33 | codefragments.cpp - code fragment loader 34 | 35 | host/pc: 36 | asiolist.h 37 | asiolist.cpp - instantiates an ASIO driver via the COM model 38 | 39 | host/sample: 40 | hostsample.cpp - a simple console app which shows ASIO hosting 41 | hostsample.dsp - MSVC++ 5.0 project 42 | hostsample.vcproj - Visual Studio 2005 project (32 and 64 bit targets) 43 | 44 | driver/asiosample: 45 | asiosmpl.h 46 | asiosmpl.cpp - ASIO 2.0 sample driver 47 | wintimer.cpp - bufferSwitch() wakeup thread (Windows) 48 | asiosample.def - Windows DLL module export definition 49 | mactimer.cpp - bufferSwitch() wakeup thread (Macintosh) 50 | macnanosecs.cpp - Macintosh system reference time 51 | makesamp.cpp - Macintosh driver object instantiation 52 | 53 | driver/asiosample/asiosample: 54 | asiosample.dsp - MSVC++ 5.0 project 55 | asiosample.vcproj - Visual Studio 2005 project (32 and 64 bit targets) 56 | -------------------------------------------------------------------------------- /Feature-Extractor.jucer: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 15 | 16 | 17 | 19 | 21 | 22 | 23 | 25 | 26 | 28 | 30 | 31 | 32 | 33 | 35 | 37 | 39 | 41 | 42 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 56 | 57 | 59 | 60 | 61 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 71 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 96 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Feature-Extractor 2 | 3 | Feature Extractor is a real-time audio feature extraction tool. It can analyse audio on multiple input tracks in parallel. 4 | 5 | #Dependencies: 6 | 7 | The c++ JUCE framework: https://github.com/julianstorer/JUCE 8 | 9 | In order to build with the Projucer: Ensure that your JUCE repository folder location is ../JUCE (relative to the feature-extractor repository folder). Then open the Feature-Extractor.jucer file with the Projucer. The Projucer can be found at JUCE/extras/Projucer. If you've just cloned the JUCE repo you'll need to build the Projucer project first. Once you've opened the Feature-Extractor.jucer file in the projucer, click on the config tab and then click 'save and open in IDE' at the bottom left. This will open the project in Visual Studio (windows) or XCode (mac). Then you can build and run the Feature-Extractor app. 10 | 11 | #Audio input: 12 | 13 | The controls at the top of the app are used to switch bewtween input devices and enable / disable input channels. 14 | 15 | #Feature visualisers: 16 | 17 | The central bars show the real-time values of the various features, with their names at the bottom. 18 | 19 | #OSC Settings: 20 | 21 | The various audio features will be sent via OSC to the ip address which is set from the app. They will be sent together in an OSC bundle. 22 | 23 | The address of this bundle can also be set from the app. The bundle will contain the various features as an array of floats, between 24 | 0 and 1. The features will be ordered as they are in the app from left to right. 25 | 26 | #Features: 27 | 28 | #Amplitude 29 | Onset - the onset value will be 1 when an onset is detected and 0 otherwise. 30 | 31 | RMS (Amplitude) - the root-mean-squared amplitude of the audio signal. This is the average 'volume' of the signal. 32 | 33 | #Spectral 34 | 35 | Centroid - the spectral centroid of the signal. This can be a good indication of the 'brightness' of a sound. 36 | 37 | spectral Slope - the slope of the spectrum. Linearly dependent on the centroid. 38 | 39 | Spectral Spread - the spread of the spectrum around the mean. signals with narrow bandwidth will have smaller spectral spread. 40 | 41 | Spectral Flatness - good indication of the 'noisyness' of the signal (noisy tones have flatter spectrums). 42 | 43 | Spectral Flux - the level of change in spectral enery between consecutive frames. 44 | 45 | #Harmonic 46 | 47 | Pitch - a very crude estimation of the fundamental frequency. It is currently normalised between 0 and 5000 Hz 48 | 49 | Harmonic Energy Ratio - the proportion of the energy in the spectrum that is harmonic 50 | 51 | Inharmonicity - a measure of how much the peaks in the energy spectrum deviate from their closest harmonics 52 | 53 | 54 | #OSC Bundle Structure 55 | The OSC bundles will contain 10 floats in the following order: 56 | 57 | Onset, RMS amplitude, pitch, centroid, slope, spread, flatness, flux, harmonic energy ratio, inharmonicity 58 | -------------------------------------------------------------------------------- /Source/AnalyserTrack.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================== 3 | 4 | AnalyserTrack.h 5 | Created: 16 Jun 2016 4:25:58pm 6 | Author: Sean 7 | 8 | ============================================================================== 9 | */ 10 | 11 | #ifndef ANALYSERTRACK_H_INCLUDED 12 | #define ANALYSERTRACK_H_INCLUDED 13 | 14 | class AnalyserTrack : public Component, 15 | public Slider::Listener 16 | { 17 | public: 18 | AnalyserTrack (String channelName) 19 | : channelNameLabel ("AnalyserTrack", channelName), 20 | gainLabel ("gainLabel", "Gain:"), 21 | audioScrollingDisplay (1), 22 | featureListView (featureListModel), 23 | audioSourceTypeSelectorController (getAudioSourceTypeString) 24 | { 25 | setLookAndFeel (SharedResourcePointer()); 26 | 27 | audioScrollingDisplay.clear(); 28 | audioScrollingDisplay.setSamplesPerBlock (256); 29 | audioScrollingDisplay.setBufferSize (1024); 30 | addAndMakeVisible (audioScrollingDisplay); 31 | 32 | for (int i = (int) AudioFeatures::eAudioFeature::enRMS; i < (int) AudioFeatures::eAudioFeature::numFeatures; i++) 33 | featureListModel.addFeature ((AudioFeatures::eAudioFeature) i); 34 | 35 | featureListView.recreateVisualisersFromModel(); 36 | 37 | addAndMakeVisible (featureListView); 38 | 39 | addAndMakeVisible (oscSettingsController.getView()); 40 | 41 | addAndMakeVisible (audioFileTransportController.getView()); 42 | audioFileTransportController.getView().setVisible (false); 43 | 44 | addAndMakeVisible (audioSourceTypeSelectorController.getSelector()); 45 | 46 | gainLabel.setJustificationType (Justification::centredRight); 47 | gainSlider.setRange (0.0, 100.0, 0.01); 48 | gainSlider.addListener (this); 49 | gainSlider.setDoubleClickReturnValue (true, 1.0); 50 | gainSlider.setValue (1.0); 51 | gainSlider.setSliderStyle (Slider::SliderStyle::LinearBar); 52 | 53 | addAndMakeVisible (gainSlider); 54 | addAndMakeVisible (gainLabel); 55 | 56 | addAndMakeVisible (channelNameLabel); 57 | 58 | } 59 | 60 | ~AnalyserTrack() 61 | { 62 | stopAnimation(); 63 | setAudioSourceTypeChangedCallback (nullptr); 64 | setAddressChangedCallback (nullptr); 65 | setBundleAddressChangedCallback (nullptr); 66 | setFileDroppedCallback (nullptr); 67 | setPlayPressedCallback (nullptr); 68 | setPausePressedCallback (nullptr); 69 | setRestartPressedCallback (nullptr); 70 | setStopPressedCallback (nullptr); 71 | setOnsetSensitivityCallback (nullptr); 72 | setOnsetWindowSizeCallback (nullptr); 73 | setOnsetDetectionTypeCallback (nullptr); 74 | setFeatureValueQueryCallback (nullptr); 75 | setGainChangedCallback (nullptr); 76 | } 77 | 78 | void setChannelName (String n) { channelNameLabel.setText (n, dontSendNotification); } 79 | 80 | void resized() override 81 | { 82 | auto localBounds = getLocalBounds(); 83 | auto trackBounds = localBounds.removeFromTop (150);//<- magic number to go in LnF 84 | const auto& availableWidth = trackBounds.getWidth(); 85 | const auto& audioDisplayWidth = (int)(availableWidth * 0.75f); 86 | const auto& oscWidth = (int)(availableWidth * 0.25f); 87 | auto audioAndFeaturesBounds = trackBounds.removeFromLeft (audioDisplayWidth); 88 | const int displayHeight = audioAndFeaturesBounds.getHeight() / 2; 89 | 90 | audioScrollingDisplay.setBounds (audioAndFeaturesBounds.removeFromTop (displayHeight)); 91 | featureListView.setBounds (audioAndFeaturesBounds.removeFromTop (displayHeight)); 92 | oscSettingsController.getView().setBounds (trackBounds.removeFromLeft (audioDisplayWidth)); 93 | 94 | const auto w = localBounds.getWidth() / 2; 95 | 96 | auto labelBounds = getLocalBounds().removeFromTop (FeatureExtractorLookAndFeel::getDeviceSettingsItemHeight() 97 | + FeatureExtractorLookAndFeel::getInnerComponentSpacing()); 98 | 99 | auto sliderLabelBounds = labelBounds.removeFromBottom (FeatureExtractorLookAndFeel::getDeviceSettingsItemHeight()); 100 | channelNameLabel.setBounds (sliderLabelBounds.removeFromLeft (100)); 101 | sliderLabelBounds.removeFromLeft (10); 102 | gainLabel.setBounds (sliderLabelBounds.removeFromLeft (100)); 103 | gainSlider.setBounds (sliderLabelBounds.removeFromLeft (100)); 104 | } 105 | 106 | void sliderValueChanged (Slider* s) override 107 | { 108 | if (s == &gainSlider) 109 | if (gainChangedCallback != nullptr) 110 | gainChangedCallback ((float) s->getValue()); 111 | } 112 | 113 | void stopAnimation() 114 | { 115 | featureListView.setFeatureValueQueryCallback (nullptr); 116 | featureListView.stopTimer(); 117 | } 118 | 119 | AudioVisualiserComponent& getAudioDisplayComponent() { return audioScrollingDisplay; } 120 | OSCSettingsController& getOSCSettingsController() { return oscSettingsController; } 121 | 122 | void setAudioSourceTypeChangedCallback (std::function f) { audioSourceTypeSelectorController.setAudioSourceTypeChangedCallback (f); } 123 | void setAddressChangedCallback (std::function f) { oscSettingsController.setAddressChangedCallback (f); } 124 | void setDisplayedOSCAddress (String address) { oscSettingsController.getView().getAddressEditor().setText (address); } 125 | void setSecondaryAddressChangedCallback (std::function f) { oscSettingsController.setSecondaryAddressChangedCallback (f); } 126 | void setSecondaryDisplayedOSCAddress (String address) { oscSettingsController.getView().getSecondaryAddressEditor().setText (address); } 127 | void setBundleAddressChangedCallback (std::function f) { oscSettingsController.setBundleAddressChangedCallback (f); } 128 | void setDisplayedBundleAddress (String address) { oscSettingsController.getView().getBundleAddressEditor().setText (address); } 129 | 130 | void setFileDroppedCallback (std::function f) { audioFileTransportController.setFileDroppedCallback (f); } 131 | void toggleShowTransportControls (bool shouldShowControls) { audioFileTransportController.getView().setVisible (shouldShowControls); } 132 | void setAudioTransportState (AudioFileTransportController::eAudioTransportState state) { audioFileTransportController.setAudioTransportState (state); } 133 | void setPlayPressedCallback (std::function f) { audioFileTransportController.setPlayPressedCallback (f); } 134 | void setPausePressedCallback (std::function f) { audioFileTransportController.setPausePressedCallback (f); } 135 | void setRestartPressedCallback (std::function f) { audioFileTransportController.setRestartPressedCallback (f); } 136 | void setStopPressedCallback (std::function f) { audioFileTransportController.setStopPressedCallback (f); } 137 | 138 | void clearAudioDisplayData() { audioScrollingDisplay.clear(); } 139 | 140 | void featureTriggered (AudioFeatures::eAudioFeature triggerType) 141 | { 142 | MessageManager::getInstance()->callAsync ([this, triggerType]() 143 | { 144 | featureListView.featureTriggered (triggerType); 145 | }); 146 | } 147 | 148 | void updateBufferToPush (AudioSampleBuffer* buffer) 149 | { 150 | if (buffer != nullptr) 151 | { 152 | bufferToPush = AudioSampleBuffer (*buffer); 153 | MessageManager::getInstance()->callAsync ([this]() 154 | { 155 | audioScrollingDisplay.pushBuffer (bufferToPush); 156 | }); 157 | } 158 | } 159 | 160 | void startAnimation() { featureListView.startAnimation(); } 161 | 162 | void setOnsetSensitivityCallback (std::function f) { featureListView.setOnsetSensitivityCallback (f); } 163 | void setOnsetWindowSizeCallback (std::function f) { featureListView.setOnsetWindowLengthCallback (f); } 164 | void setOnsetDetectionTypeCallback (std::function f) { featureListView.setOnsetDetectionTypeCallback (f); } 165 | void setFeatureValueQueryCallback (std::function f) { featureListView.setFeatureValueQueryCallback (f); } 166 | void setGainChangedCallback (std::function f) { gainChangedCallback = f; } 167 | 168 | private: 169 | std::function gainChangedCallback; 170 | Label channelNameLabel; 171 | Label gainLabel; 172 | Slider gainSlider; 173 | AudioSampleBuffer bufferToPush; 174 | AudioVisualiserComponent audioScrollingDisplay; 175 | AudioFileTransportController audioFileTransportController; 176 | FeatureListModel featureListModel; 177 | FeatureListView featureListView; 178 | OSCSettingsController oscSettingsController; 179 | AudioSourceSelectorController<> audioSourceTypeSelectorController; 180 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnalyserTrack); 181 | }; 182 | 183 | 184 | 185 | #endif // ANALYSERTRACK_H_INCLUDED 186 | -------------------------------------------------------------------------------- /Source/AnalyserTrackController.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================== 3 | 4 | AnalyserTrackController.h 5 | Created: 16 Jun 2016 4:41:40pm 6 | Author: Sean 7 | 8 | ============================================================================== 9 | */ 10 | 11 | #ifndef ANALYSERTRACKCONTROLLER_H_INCLUDED 12 | #define ANALYSERTRACKCONTROLLER_H_INCLUDED 13 | 14 | class AnalyserTrackController 15 | { 16 | public: 17 | AnalyserTrackController (AudioDeviceManager& deviceManagerRef, int channelToAnalyse, String nameOfInputChannel, String ip, String secondaryIP, String bundle) 18 | : audioDataCollectorHarm (channelToAnalyse), 19 | audioDataCollectorSpec (channelToAnalyse), 20 | audioAnalyserHarm (audioDataCollectorHarm, features, 2048), 21 | audioAnalyserSpec (audioDataCollectorSpec, features, 2048), 22 | oscFeatureSender (features, ip, bundle), 23 | secondaryOSCFeatureSender (features, secondaryIP, bundle), 24 | deviceManager (deviceManagerRef), 25 | channelName (nameOfInputChannel) 26 | { 27 | enabled = channelToAnalyse >= 0; 28 | 29 | if (enabled) 30 | { 31 | audioDataCollectorHarm.setNotifyAnalysisThreadCallback ([this]() 32 | { 33 | audioAnalyserHarm.notify(); 34 | }); 35 | deviceManager.addAudioCallback (&audioDataCollectorHarm); 36 | 37 | audioDataCollectorSpec.setNotifyAnalysisThreadCallback ([this]() 38 | { 39 | audioAnalyserSpec.notify(); 40 | }); 41 | deviceManager.addAudioCallback (&audioDataCollectorSpec); 42 | 43 | audioFilePlayer.setupAudioCallback (deviceManager); 44 | } 45 | } 46 | 47 | ~AnalyserTrackController() 48 | { 49 | if (enabled) 50 | { 51 | deviceManager.removeAudioCallback (audioFilePlayer.getAudioSourcePlayer()); 52 | deviceManager.removeAudioCallback (&audioDataCollectorHarm); 53 | deviceManager.removeAudioCallback (&audioDataCollectorSpec); 54 | } 55 | stopAnalysis(); 56 | audioDataCollectorHarm.setNotifyAnalysisThreadCallback (nullptr); 57 | audioDataCollectorSpec.setNotifyAnalysisThreadCallback (nullptr); 58 | clearGUICallbacks(); 59 | } 60 | 61 | void clearGUICallbacks() 62 | { 63 | audioDataCollectorHarm.setBufferToDrawUpdatedCallback (nullptr); 64 | audioDataCollectorSpec.setBufferToDrawUpdatedCallback (nullptr); 65 | audioAnalyserSpec.setOnsetDetectedCallback (nullptr); 66 | setGUITrackSamplesPerBlockCallback = nullptr; 67 | } 68 | 69 | void linkGUIDisplayToTrack (AnalyserTrack* guiTrack, const CustomAudioDeviceSetupDetails& audioSetupDetails, String oscBundleAddress) 70 | { 71 | stopAnalysis(); 72 | guiTrack->setChannelName (getChannelName()); 73 | guiTrack->getOSCSettingsController().getView().setBundleAddress (oscBundleAddress); 74 | audioDataCollectorHarm.setBufferToDrawUpdatedCallback ([this, guiTrack] (AudioSampleBuffer& b) 75 | { 76 | if (guiTrack != nullptr) 77 | guiTrack->updateBufferToPush (&b); 78 | }); 79 | 80 | audioAnalyserSpec.setOnsetDetectedCallback ([this, guiTrack] () 81 | { 82 | if (guiTrack != nullptr) 83 | guiTrack->featureTriggered (AudioFeatures::eAudioFeature::enOnset); 84 | }); 85 | 86 | guiTrack->setFeatureValueQueryCallback ([this] (AudioFeatures::eAudioFeature featureType, float maxValue) 87 | { 88 | return getAudioFeature (featureType) / maxValue; 89 | }); 90 | 91 | //switches between listening to input or output 92 | guiTrack->setAudioSourceTypeChangedCallback ([this, guiTrack] (eAudioSourceType type) 93 | { 94 | bool input = type == eAudioSourceType::enIncomingAudio; 95 | 96 | if (input) 97 | audioFilePlayer.stop(); 98 | 99 | audioDataCollectorHarm.toggleCollectInput (input); 100 | audioDataCollectorSpec.toggleCollectInput (input); 101 | JUCE_COMPILER_WARNING("Should these just go durectly after the callback from within auio analyser track?"); 102 | if (guiTrack != nullptr) 103 | { 104 | guiTrack->toggleShowTransportControls (type == eAudioSourceType::enAudioFile); 105 | guiTrack->clearAudioDisplayData(); 106 | } 107 | }); 108 | 109 | guiTrack->setFileDroppedCallback ([this, guiTrack] (File& f) 110 | { 111 | audioDataCollectorHarm.clearBuffer(); 112 | audioDataCollectorSpec.clearBuffer(); 113 | if (guiTrack != nullptr) 114 | guiTrack->clearAudioDisplayData(); 115 | audioFilePlayer.loadFileIntoTransport (f); 116 | 117 | if (guiTrack != nullptr) 118 | { 119 | if (audioFilePlayer.hasFile()) 120 | guiTrack->setAudioTransportState (AudioFileTransportController::eAudioTransportState::enFileStopped); 121 | else 122 | guiTrack->setAudioTransportState (AudioFileTransportController::eAudioTransportState::enNoFileSelected); 123 | } 124 | } ); 125 | 126 | guiTrack->setGainChangedCallback ([this] (float g) 127 | { 128 | audioDataCollectorHarm.setGain (g); 129 | audioDataCollectorSpec.setGain (g); 130 | }); 131 | 132 | guiTrack->setOnsetSensitivityCallback ([this] (float s) { audioAnalyserSpec.setOnsetDetectionSensitivity (s); }); 133 | guiTrack->setOnsetWindowSizeCallback ([this] (int s) { audioAnalyserSpec.setOnsetWindowLength (s); }); 134 | guiTrack->setOnsetDetectionTypeCallback ([this] (OnsetDetector::eOnsetDetectionType t) { audioAnalyserSpec.setOnsetDetectionType (t); }); 135 | guiTrack->setPlayPressedCallback ([this] () { audioFilePlayer.play(); clearAnalysisBuffers(); }); 136 | guiTrack->setPausePressedCallback ([this] () { audioFilePlayer.pause(); clearAnalysisBuffers(); }); 137 | guiTrack->setStopPressedCallback ([this] () { audioFilePlayer.stop(); clearAnalysisBuffers(); }); 138 | guiTrack->setRestartPressedCallback ([this] () { audioFilePlayer.restart(); }); 139 | 140 | guiTrack->setAddressChangedCallback ([this] (String address) { return oscFeatureSender.connectToAddress (address); }); 141 | guiTrack->setSecondaryAddressChangedCallback ([this] (String address) { return secondaryOSCFeatureSender.connectToAddress (address); }); 142 | 143 | guiTrack->setBundleAddressChangedCallback ([this] (String address) 144 | { 145 | oscFeatureSender.bundleAddress = address; 146 | secondaryOSCFeatureSender.bundleAddress = address; 147 | }); 148 | 149 | 150 | guiTrack->setDisplayedOSCAddress (oscFeatureSender.address); 151 | guiTrack->setSecondaryDisplayedOSCAddress (secondaryOSCFeatureSender.address); 152 | guiTrack->setDisplayedBundleAddress (oscFeatureSender.bundleAddress); 153 | 154 | setGUITrackSamplesPerBlockCallback = [this, guiTrack](int samplesPerBlockExpected) 155 | { 156 | if (guiTrack != nullptr) 157 | guiTrack->getAudioDisplayComponent().setSamplesPerBlock (samplesPerBlockExpected); 158 | }; 159 | 160 | AudioDeviceManager::AudioDeviceSetup setup; 161 | deviceManager.getAudioDeviceSetup (setup); 162 | prepareToPlay (setup.bufferSize, setup.sampleRate); 163 | 164 | guiTrack->startAnimation(); 165 | } 166 | 167 | void clearAnalysisBuffers() 168 | { 169 | audioDataCollectorHarm.clearBuffer(); 170 | audioDataCollectorSpec.clearBuffer(); 171 | } 172 | 173 | float getAudioFeature (AudioFeatures::eAudioFeature featureType) const { return features.getValue (featureType); } 174 | 175 | void prepareToPlay (int samplesPerBlockExpected, double sampleRate) 176 | { 177 | stopAnalysis(); 178 | audioAnalyserHarm.sampleRateChanged (sampleRate); 179 | audioAnalyserSpec.sampleRateChanged (sampleRate); 180 | 181 | if (setGUITrackSamplesPerBlockCallback != nullptr) 182 | setGUITrackSamplesPerBlockCallback (samplesPerBlockExpected); 183 | 184 | audioAnalyserHarm.startThread (4); 185 | audioAnalyserSpec.startThread (4); 186 | audioDataCollectorHarm.setExpectedSamplesPerBlock (samplesPerBlockExpected); 187 | audioDataCollectorSpec.setExpectedSamplesPerBlock (samplesPerBlockExpected); 188 | } 189 | 190 | void stopAnalysis() 191 | { 192 | audioAnalyserHarm.stopThread (100); 193 | audioAnalyserSpec.stopThread (100); 194 | } 195 | 196 | String getChannelName() const noexcept { return channelName; } 197 | bool isEnabled() const noexcept { return enabled; } 198 | private: 199 | std::function setGUITrackSamplesPerBlockCallback; 200 | AudioFilePlayer audioFilePlayer; 201 | AudioFeatures features; 202 | AudioDataCollector audioDataCollectorHarm; 203 | AudioDataCollector audioDataCollectorSpec; 204 | RealTimeHarmonicAnalyser audioAnalyserHarm; 205 | RealTimeSpectralAnalyser audioAnalyserSpec; 206 | OSCFeatureAnalysisOutput oscFeatureSender; 207 | OSCFeatureAnalysisOutput secondaryOSCFeatureSender; 208 | AudioDeviceManager &deviceManager; 209 | String channelName; 210 | bool enabled { true }; 211 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnalyserTrackController); 212 | }; 213 | 214 | 215 | 216 | #endif // ANALYSERTRACKCONTROLLER_H_INCLUDED 217 | -------------------------------------------------------------------------------- /Source/AudioDataCollector.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================== 3 | 4 | AudioDataCollector.h 5 | Created: 10 Feb 2016 8:02:00pm 6 | Author: Sean 7 | 8 | ============================================================================== 9 | */ 10 | 11 | #ifndef AUDIODATACOLLECTOR_H_INCLUDED 12 | #define AUDIODATACOLLECTOR_H_INCLUDED 13 | 14 | //============================================================================== 15 | /* 16 | Periodically collects the incoming audio into a buffer that is used for audio feature extraction 17 | */ 18 | class AudioDataCollector : public AudioIODeviceCallback 19 | { 20 | public: 21 | AudioDataCollector (int audioChannelToCollect) 22 | : channelToCollect (audioChannelToCollect) 23 | { 24 | circleBuffer.setSize (1, 4096); 25 | circleBuffer.clear(); 26 | } 27 | 28 | void audioDeviceAboutToStart (AudioIODevice* d) override 29 | { 30 | jassert(channelToCollect <= d->getActiveInputChannels().getHighestBit()); 31 | } 32 | 33 | void audioDeviceStopped() override 34 | { } 35 | 36 | void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels, 37 | float** outputChannelData, int numOutputChannels, 38 | int numberOfSamples) override 39 | { 40 | ignoreUnused (numInputChannels); 41 | ignoreUnused (numOutputChannels); 42 | const float* const* channelData = collectInput ? inputChannelData : outputChannelData; 43 | 44 | if (collectInput) 45 | jassert (numInputChannels >= channelToCollect); 46 | if (!collectInput) 47 | jassert (numOutputChannels >= channelToCollect); 48 | 49 | analysisBufferUpdating.set (1); 50 | 51 | if (writeIndex + numberOfSamples <= circleBuffer.getNumSamples()) 52 | { 53 | circleBuffer.copyFrom (0, writeIndex, channelData[channelToCollect], numberOfSamples); 54 | } 55 | else 56 | { 57 | for (int index = 0; index < numberOfSamples; index++) 58 | { 59 | const int modIndex = (index + writeIndex) % circleBuffer.getNumSamples(); 60 | circleBuffer.setSample (0, modIndex, channelData[channelToCollect][index]); 61 | } 62 | } 63 | 64 | writeIndex = (writeIndex + numberOfSamples) % circleBuffer.getNumSamples(); 65 | 66 | analysisBufferUpdating.set (0); 67 | 68 | if (notifyAnalysisThread != nullptr) 69 | notifyAnalysisThread(); 70 | } 71 | 72 | AudioSampleBuffer getAnalysisBuffer (int numSamplesRequired) 73 | { 74 | AudioSampleBuffer buffer = AudioSampleBuffer(); 75 | buffer.clear(); 76 | buffer.setSize (1, numSamplesRequired); 77 | while (analysisBufferUpdating.get() == 1 || indexesOverlap (numSamplesRequired)) {} 78 | if (analysisBufferUpdating.get() != 1) 79 | { 80 | const bool wrap = readIndex + numSamplesRequired > circleBuffer.getNumSamples(); 81 | for (int index = 0; index < numSamplesRequired; index++) 82 | { 83 | int rIndex = index + readIndex; 84 | 85 | if (wrap) 86 | rIndex = rIndex % circleBuffer.getNumSamples(); 87 | 88 | buffer.setSample (0, index, circleBuffer.getReadPointer (0)[rIndex] * gain); 89 | } 90 | readIndex = (readIndex + numSamplesRequired) % circleBuffer.getNumSamples(); 91 | updateBufferToDraw (buffer); 92 | } 93 | return buffer; 94 | } 95 | 96 | void updateBufferToDraw (AudioSampleBuffer& buffer) 97 | { 98 | if (bufferToDrawUpdated != nullptr) 99 | { 100 | bufferToDrawUpdated (buffer); 101 | } 102 | } 103 | 104 | bool indexesOverlap (int numSamplesToFill) 105 | { 106 | if (writeIndex < readIndex) 107 | if (readIndex < writeIndex + expectedSamplesPerBlock) 108 | return true; 109 | if (readIndex < writeIndex) 110 | if (writeIndex < readIndex + numSamplesToFill) 111 | return true; 112 | return false; 113 | 114 | } 115 | 116 | void setBufferToDrawUpdatedCallback (std::function f) { bufferToDrawUpdated = f; } 117 | void setNotifyAnalysisThreadCallback (std::function f) { notifyAnalysisThread = f; } 118 | 119 | void toggleCollectInput (bool shouldCollectInput) noexcept { clearBuffer(); collectInput = shouldCollectInput; } 120 | void setExpectedSamplesPerBlock (int spb) noexcept { expectedSamplesPerBlock = spb; } 121 | 122 | void clearBuffer() { circleBuffer.clear(); } 123 | void setChannelToCollect (int c) { channelToCollect = c; } 124 | void setGain (float g) { gain = g; } 125 | private: 126 | AudioSampleBuffer circleBuffer; 127 | std::function bufferToDrawUpdated; 128 | std::function notifyAnalysisThread; 129 | float gain { 1.0f }; 130 | Atomic analysisBufferUpdating { 0 }; 131 | int writeIndex { 0 }; 132 | int readIndex { 0 }; 133 | int expectedSamplesPerBlock { 512 }; 134 | int channelToCollect { 0 }; 135 | bool collectInput { true }; 136 | 137 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioDataCollector) 138 | }; 139 | 140 | 141 | 142 | #endif // AUDIODATACOLLECTOR_H_INCLUDED 143 | -------------------------------------------------------------------------------- /Source/AudioFilePlayer.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================== 3 | 4 | AudioFilePlayer.h 5 | Created: 12 Feb 2016 3:30:43pm 6 | Author: Sean 7 | 8 | ============================================================================== 9 | */ 10 | 11 | #ifndef AUDIOFILEPLAYER_H_INCLUDED 12 | #define AUDIOFILEPLAYER_H_INCLUDED 13 | 14 | class AudioFilePlayer 15 | { 16 | public: 17 | AudioFilePlayer () 18 | : thread ("audio preload thread") 19 | { 20 | formatManager.registerBasicFormats(); 21 | thread.startThread (3); 22 | } 23 | 24 | ~AudioFilePlayer() 25 | { 26 | audioTransportSource.setSource (nullptr); 27 | audioSourcePlayer.setSource (nullptr); 28 | } 29 | 30 | void setupAudioCallback (AudioDeviceManager& deviceManager) 31 | { 32 | deviceManager.addAudioCallback (&audioSourcePlayer); 33 | audioSourcePlayer.setSource (&audioTransportSource); 34 | } 35 | 36 | AudioSourcePlayer* getAudioSourcePlayer() 37 | { 38 | return &audioSourcePlayer; 39 | } 40 | 41 | void loadFileIntoTransport (const File& audioFile) 42 | { 43 | // unload the previous file source and delete it.. 44 | audioTransportSource.stop(); 45 | audioTransportSource.setSource (nullptr); 46 | currentAudioFileSource = nullptr; 47 | 48 | AudioFormatReader* reader = formatManager.createReaderFor (audioFile); 49 | 50 | if (reader != nullptr) 51 | { 52 | currentAudioFileSource = new AudioFormatReaderSource (reader, true); 53 | currentAudioFileSource->setLooping (true); 54 | // ..and plug it into our transport source 55 | audioTransportSource.setSource (currentAudioFileSource, 56 | 32768, // tells it to buffer this many samples ahead 57 | &thread, // this is the background thread to use for reading-ahead 58 | reader->sampleRate); // allows for sample rate correction 59 | } 60 | } 61 | 62 | void play () { audioTransportSource.start(); } 63 | void pause() { audioTransportSource.stop(); } 64 | void stop() { pause(); audioTransportSource.setPosition (0.0); } 65 | void restart() { audioTransportSource.setPosition (0.0); } 66 | 67 | bool hasFile() { return currentAudioFileSource != nullptr; } 68 | 69 | private: 70 | AudioFormatManager formatManager; 71 | TimeSliceThread thread; 72 | AudioSourcePlayer audioSourcePlayer; 73 | AudioTransportSource audioTransportSource; 74 | ScopedPointer currentAudioFileSource; 75 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFilePlayer) 76 | }; 77 | 78 | 79 | 80 | #endif // AUDIOFILEPLAYER_H_INCLUDED 81 | -------------------------------------------------------------------------------- /Source/AudioFileTransportComponent.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================== 3 | 4 | AudioFileTransportComponent.h 5 | Created: 12 Feb 2016 5:57:29pm 6 | Author: Sean 7 | 8 | ============================================================================== 9 | */ 10 | 11 | #ifndef AUDIOFILETRANSPORTCOMPONENT_H_INCLUDED 12 | #define AUDIOFILETRANSPORTCOMPONENT_H_INCLUDED 13 | class AudioTransportButton : public TextButton 14 | { 15 | public: 16 | AudioTransportButton (FeatureExtractorLookAndFeel::eAudioTransportButtonType t) 17 | : TextButton (String::empty), 18 | type (t) 19 | {} 20 | 21 | void paint (Graphics& g) 22 | { 23 | FeatureExtractorLookAndFeel::drawAudioTransportButton (g, type, getLocalBounds(), *this); 24 | } 25 | 26 | private: 27 | FeatureExtractorLookAndFeel::eAudioTransportButtonType type; 28 | }; 29 | 30 | class AudioFileTransportView : public Component, 31 | public FileDragAndDropTarget 32 | { 33 | public: 34 | AudioFileTransportView() 35 | : dropFileHere ("file target notifier", "Drop file here"), 36 | playButton (FeatureExtractorLookAndFeel::eAudioTransportButtonType::enPlay), 37 | pauseButton (FeatureExtractorLookAndFeel::eAudioTransportButtonType::enPause), 38 | restartButton (FeatureExtractorLookAndFeel::eAudioTransportButtonType::enRestart), 39 | stopButton (FeatureExtractorLookAndFeel::eAudioTransportButtonType::enStop) 40 | { 41 | dropFileHere.setJustificationType (Justification::centredTop); 42 | addAndMakeVisible (dropFileHere); 43 | addChildComponent (playButton); 44 | addChildComponent (pauseButton); 45 | addChildComponent (restartButton); 46 | addChildComponent (stopButton); 47 | } 48 | 49 | static bool isFileRecognised (File& f) 50 | { 51 | String extension = f.getFileExtension(); 52 | return extension == String (".wav") || extension == String (".mp3") || extension == String (".aiff"); 53 | } 54 | 55 | void resized() override 56 | { 57 | auto localBounds = getLocalBounds(); 58 | const int controlsWidth = FeatureExtractorLookAndFeel::getAudioTransportControlsWidth(); 59 | const int controlsHeight = FeatureExtractorLookAndFeel::getAudioTransportControlsHeight(); 60 | auto controlBounds = localBounds.withSizeKeepingCentre (controlsWidth, controlsHeight); 61 | 62 | dropFileHere.setBounds (controlBounds); 63 | const int buttonWidth = controlBounds.getWidth() / 3; 64 | const auto restartBounds = controlBounds.removeFromLeft (buttonWidth); 65 | 66 | restartButton.setBounds (restartBounds); 67 | const auto playAndPauseBounds = controlBounds.removeFromLeft (buttonWidth); 68 | pauseButton.setBounds (playAndPauseBounds); 69 | playButton.setBounds (playAndPauseBounds); 70 | const auto stopBounds = controlBounds.removeFromLeft (buttonWidth); 71 | stopButton.setBounds (stopBounds); 72 | } 73 | 74 | bool isInterestedInFileDrag (const StringArray& files) override 75 | { 76 | if (files.size() > 1) 77 | return false; 78 | 79 | jassert (files.size() == 1); 80 | String fileName = files[0]; 81 | 82 | if (fileName.endsWith ("wav") || fileName.endsWith ("mp3") || fileName.endsWith ("aiff")) 83 | return true; 84 | 85 | return false; 86 | } 87 | 88 | void filesDropped (const StringArray& files, int /*x*/, int /*y*/) override 89 | { 90 | jassert (files.size() == 1); 91 | File file = File (files[0]); 92 | 93 | if (isFileRecognised (file) && validFileDropped != nullptr) 94 | validFileDropped (file); 95 | } 96 | 97 | void setFileDroppedCallback (std::function f) { validFileDropped = f; } 98 | 99 | AudioTransportButton& getPlayButton() { return playButton; } 100 | AudioTransportButton& getPauseButton() { return pauseButton; } 101 | AudioTransportButton& getRestartButton() { return restartButton; } 102 | AudioTransportButton& getStopButton() { return stopButton; } 103 | 104 | void hideAllChildComponents() 105 | { 106 | for (int i = 0; i < getNumChildComponents(); i++) 107 | { 108 | auto child = getChildComponent (i); 109 | child->setVisible (false); 110 | } 111 | } 112 | 113 | Label& getLabel() { return dropFileHere; } 114 | 115 | private: 116 | std::function validFileDropped; 117 | 118 | AudioTransportButton playButton; 119 | AudioTransportButton pauseButton; 120 | AudioTransportButton restartButton; 121 | AudioTransportButton stopButton; 122 | Label dropFileHere; 123 | 124 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFileTransportView) 125 | }; 126 | 127 | //============================================================================================ 128 | //============================================================================================ 129 | 130 | class AudioFileTransportController : public ButtonListener 131 | { 132 | public: 133 | enum eAudioTransportState 134 | { 135 | enNoFileSelected, 136 | enFilePlaying, 137 | enFilePaused, 138 | enFileStopped 139 | }; 140 | 141 | AudioFileTransportController() 142 | { 143 | view.getPlayButton().addListener (this); 144 | view.getPauseButton().addListener (this); 145 | view.getStopButton().addListener (this); 146 | view.getRestartButton().addListener (this); 147 | } 148 | 149 | void buttonClicked (Button* b) 150 | { 151 | if (b == &view.getPlayButton()) 152 | { 153 | setAudioTransportState (enFilePlaying); 154 | if (playPressed != nullptr) 155 | playPressed(); 156 | } 157 | else if (b == &view.getPauseButton()) 158 | { 159 | setAudioTransportState (enFilePaused); 160 | if (pausePressed != nullptr) 161 | pausePressed(); 162 | } 163 | else if (b == &view.getRestartButton()) 164 | { 165 | setAudioTransportState (enFilePlaying); 166 | if (restartPressed != nullptr) 167 | restartPressed(); 168 | } 169 | else if (b == &view.getStopButton()) 170 | { 171 | setAudioTransportState (enFileStopped); 172 | if (stopPressed != nullptr) 173 | stopPressed(); 174 | } 175 | else 176 | { 177 | jassertfalse; 178 | } 179 | } 180 | 181 | void setAudioTransportState (eAudioTransportState state) 182 | { 183 | view.hideAllChildComponents(); 184 | 185 | switch (state) 186 | { 187 | case enNoFileSelected: 188 | view.getLabel().setVisible (true); 189 | break; 190 | case enFilePlaying: 191 | view.getPauseButton().setVisible (true); 192 | view.getRestartButton().setVisible (true); 193 | view.getStopButton().setVisible (true); 194 | break; 195 | case enFilePaused: 196 | view.getPlayButton().setVisible (true); 197 | view.getRestartButton().setVisible (true); 198 | view.getStopButton().setVisible (true); 199 | break; 200 | case enFileStopped: 201 | view.getPlayButton().setVisible (true); 202 | break; 203 | default: 204 | jassertfalse; 205 | break; 206 | } 207 | } 208 | 209 | AudioFileTransportView& getView() { return view; } 210 | 211 | void setFileDroppedCallback (std::function f) { view.setFileDroppedCallback (f); } 212 | 213 | void setPlayPressedCallback (std::function f) { playPressed = f; } 214 | void setPausePressedCallback (std::function f) { pausePressed = f; } 215 | void setRestartPressedCallback (std::function f) { restartPressed = f; } 216 | void setStopPressedCallback (std::function f) { stopPressed = f; } 217 | 218 | private: 219 | std::function playPressed; 220 | std::function pausePressed; 221 | std::function restartPressed; 222 | std::function stopPressed; 223 | 224 | AudioFileTransportView view; 225 | }; 226 | 227 | 228 | 229 | 230 | 231 | #endif // AUDIOFILETRANSPORTCOMPONENT_H_INCLUDED 232 | -------------------------------------------------------------------------------- /Source/AudioSourceSelectorComboBox.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================== 3 | 4 | AudioSourceSelectorComboBox.h 5 | Created: 12 Feb 2016 3:43:52pm 6 | Author: Sean 7 | 8 | ============================================================================== 9 | */ 10 | 11 | #ifndef AUDIOSOURCESELECTORCOMBOBOX_H_INCLUDED 12 | #define AUDIOSOURCESELECTORCOMBOBOX_H_INCLUDED 13 | 14 | enum eAudioSourceType 15 | { 16 | enIncomingAudio = 0, 17 | enAudioFile, 18 | enNumSourceTypes 19 | }; 20 | 21 | static String getAudioSourceTypeString (eAudioSourceType type) 22 | { 23 | switch (type) 24 | { 25 | case enIncomingAudio: 26 | return String ("Analyse incoming audio"); 27 | case enAudioFile: 28 | return String ("Analyse audio file"); 29 | default: 30 | jassertfalse; 31 | return ("UNKNOWN"); 32 | } 33 | } 34 | 35 | enum eChannelType 36 | { 37 | enLeft = 0, 38 | enRight, 39 | enNumChannels 40 | }; 41 | 42 | static String getChannelTypeString (eChannelType type) 43 | { 44 | switch (type) 45 | { 46 | case enLeft: 47 | return String ("Analyse left channel"); 48 | case enRight: 49 | return String ("Analyse right channel"); 50 | default: 51 | jassertfalse; 52 | return ("UNKNOWN"); 53 | } 54 | } 55 | 56 | template 57 | class AudioSourceSelectorController : ComboBox::Listener 58 | { 59 | public: 60 | static int getComboBoxIDForAudioSourceType (EnumType type) 61 | { 62 | return (int) type + 1; 63 | } 64 | 65 | static EnumType getAudioSourceTypeForComboBoxID (int iD) 66 | { 67 | return (EnumType) (iD - 1); 68 | } 69 | 70 | AudioSourceSelectorController (std::function getSourceTypeFunction) 71 | : getSourceTypeString (getSourceTypeFunction) 72 | { 73 | fillComboBoxSelections(); 74 | selectorComboBox.setSelectedId (1); 75 | selectorComboBox.addListener (this); 76 | } 77 | 78 | ComboBox& getSelector() 79 | { 80 | return selectorComboBox; 81 | } 82 | 83 | void comboBoxChanged (ComboBox* comboBoxThatHasChanged) override 84 | { 85 | if (comboBoxThatHasChanged == &selectorComboBox) 86 | { 87 | EnumType sourceType = getAudioSourceTypeForComboBoxID (comboBoxThatHasChanged->getSelectedId()); 88 | 89 | if (audioSourceTypeChangedCallback != nullptr) 90 | audioSourceTypeChangedCallback (sourceType); 91 | } 92 | else 93 | { 94 | jassertfalse; 95 | } 96 | } 97 | 98 | void setAudioSourceTypeChangedCallback (std::function f) { audioSourceTypeChangedCallback = f; } 99 | 100 | private: 101 | ComboBox selectorComboBox; 102 | std::function audioSourceTypeChangedCallback; 103 | std::function getSourceTypeString; 104 | 105 | void fillComboBoxSelections() 106 | { 107 | for (int type = 0; type < (int) enNumSourceTypes; type++) 108 | { 109 | EnumType sourceType = (EnumType) type; 110 | 111 | if (getSourceTypeString != nullptr) 112 | { 113 | String sourceTypeText = getSourceTypeString (sourceType); 114 | selectorComboBox.addItem (sourceTypeText, getComboBoxIDForAudioSourceType (sourceType)); 115 | } 116 | } 117 | } 118 | }; 119 | 120 | 121 | 122 | #endif // AUDIOSOURCESELECTORCOMBOBOX_H_INCLUDED 123 | -------------------------------------------------------------------------------- /Source/CustomAudioSettingsComponent.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================== 3 | 4 | This file is a modified version of part of the JUCE library. 5 | Copyright (c) 2015 - ROLI Ltd. 6 | 7 | Permission is granted to use this software under the terms of either: 8 | a) the GPL v2 (or any later version) 9 | b) the Affero GPL v3 10 | 11 | Details of these licenses can be found at: www.gnu.org/licenses 12 | 13 | JUCE is distributed in the hope that it will be useful, but WITHOUT ANY 14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 15 | A PARTICULAR PURPOSE. See the GNU General Public License for more details. 16 | 17 | ------------------------------------------------------------------------------ 18 | 19 | To release a closed-source product which uses JUCE, commercial licenses are 20 | available: visit www.juce.com for more information. 21 | 22 | ============================================================================== 23 | */ 24 | 25 | #ifndef CUSTOM_AUDIODEVICESELECTORCOMPONENT_H_INCLUDED 26 | #define CUSTOM_AUDIODEVICESELECTORCOMPONENT_H_INCLUDED 27 | 28 | 29 | //============================================================================== 30 | /** 31 | A component containing controls to let the user change the audio settings of 32 | an AudioDeviceManager object. 33 | 34 | Very easy to use - just create one of these and show it to the user. 35 | 36 | @see AudioDeviceManager 37 | */ 38 | class CustomAudioDeviceSelectorComponent : public Component, 39 | private ComboBoxListener, // (can't use ComboBox::Listener due to idiotic VC2005 bug) 40 | private ChangeListener, 41 | private Timer 42 | { 43 | public: 44 | //============================================================================== 45 | /** Creates the component. 46 | 47 | If your app needs only output channels, you might ask for a maximum of 0 input 48 | channels, and the component won't display any options for choosing the input 49 | channels. And likewise if you're doing an input-only app. 50 | 51 | @param deviceManager the device manager that this component should control 52 | @param minAudioInputChannels the minimum number of audio input channels that the application needs 53 | @param maxAudioInputChannels the maximum number of audio input channels that the application needs 54 | @param minAudioOutputChannels the minimum number of audio output channels that the application needs 55 | @param maxAudioOutputChannels the maximum number of audio output channels that the application needs 56 | @param showMidiInputOptions if true, the component will allow the user to select which midi inputs are enabled 57 | @param showMidiOutputSelector if true, the component will let the user choose a default midi output device 58 | @param showChannelsAsStereoPairs if true, channels will be treated as pairs; if false, channels will be 59 | treated as a set of separate mono channels. 60 | @param hideAdvancedOptionsWithButton if true, only the minimum amount of UI components 61 | are shown, with an "advanced" button that shows the rest of them 62 | */ 63 | CustomAudioDeviceSelectorComponent (AudioDeviceManager& deviceManager, 64 | int minAudioInputChannels, 65 | int maxAudioInputChannels, 66 | int minAudioOutputChannels, 67 | int maxAudioOutputChannels, 68 | bool showMidiInputOptions, 69 | bool showMidiOutputSelector, 70 | bool showChannelsAsStereoPairs, 71 | std::function audioDeviceAboutToChangeCB); 72 | 73 | /** Destructor */ 74 | ~CustomAudioDeviceSelectorComponent(); 75 | 76 | /** The device manager that this component is controlling */ 77 | AudioDeviceManager& deviceManager; 78 | 79 | /** Sets the standard height used for items in the panel. */ 80 | void setItemHeight (int itemHeight); 81 | 82 | /** Returns the standard height used for items in the panel. */ 83 | int getItemHeight() const noexcept { return itemHeight; } 84 | 85 | int getRequiredHeight() const noexcept 86 | { 87 | auto numBoxes = 1; 88 | if (audioDeviceSettingsComp != nullptr) 89 | numBoxes += audioDeviceSettingsComp->getNumChildComponents() / 2;//count only boxes (not labels) 90 | 91 | return numBoxes * FeatureExtractorLookAndFeel::getDeviceSettingsItemHeight() 92 | + (numBoxes + 1) * FeatureExtractorLookAndFeel::getInnerComponentSpacing(); 93 | } 94 | 95 | const CustomAudioDeviceSetupDetails getDeviceSetupDetails(); 96 | //============================================================================== 97 | /** @internal */ 98 | void resized() override; 99 | /** @internal */ 100 | void timerCallback() override; 101 | 102 | private: 103 | //============================================================================== 104 | 105 | //============================================================================== 106 | std::function audioDeviceAboutToChangeCallback; 107 | ScopedPointer deviceTypeDropDown; 108 | ScopedPointer