diff --git a/modules/juce_audio_devices/native/juce_win32_ASIO.cpp b/modules/juce_audio_devices/native/juce_win32_ASIO.cpp index 0eaca9ff33..3569135ca2 100644 --- a/modules/juce_audio_devices/native/juce_win32_ASIO.cpp +++ b/modules/juce_audio_devices/native/juce_win32_ASIO.cpp @@ -52,7 +52,7 @@ namespace ASIODebugging switch (error) { - case 0: return; + case ASE_OK: return; case ASE_NotPresent: err = "Not Present"; break; case ASE_HWMalfunction: err = "Hardware Malfunction"; break; case ASE_InvalidParameter: err = "Invalid Parameter"; break; @@ -313,20 +313,30 @@ class ASIOAudioIODevice : public AudioIODevice, private Timer { public: - ASIOAudioIODevice (ASIOAudioIODeviceType* ownerType, - const String& devName, const CLSID clsID, - const int slotNumber, const String& dllForDirectLoading) + ASIOAudioIODevice (ASIOAudioIODeviceType* ownerType, const String& devName, + const CLSID clsID, const int slotNumber) : AudioIODevice (devName, "ASIO"), owner (ownerType), asioObject (nullptr), classId (clsID), - optionalDllForDirectLoading (dllForDirectLoading), + inputLatency (0), + outputLatency (0), + minSize (0), maxSize (0), + preferredSize (0), + granularity (0), + currentBlockSizeSamples (0), currentBitDepth (16), currentSampleRate (0), currentCallback (nullptr), + bufferIndex (0), + numActiveInputChans (0), + numActiveOutputChans (0), deviceIsOpen (false), isStarted (false), buffersCreated (false), + isASIOOpen (false), + calledback (false), + littleEndian (false), postOutput (true), needToReset (false), insideControlPanelModalLoop (false), @@ -401,13 +411,12 @@ public: String open (const BigInteger& inputChannels, const BigInteger& outputChannels, - double sr, - int bufferSizeSamples) + double sr, int bufferSizeSamples) { close(); jassert (currentCallback == nullptr); - if (bufferSizeSamples <= 0) + if (bufferSizeSamples < 8 || bufferSizeSamples > 16384) shouldUsePreferredSize = true; { @@ -432,6 +441,9 @@ public: if (preferredSize != 0 && newPreferredSize != 0 && newPreferredSize != preferredSize) shouldUsePreferredSize = true; + if (bufferSizeSamples < minSize || bufferSizeSamples > maxSize) + shouldUsePreferredSize = true; + preferredSize = newPreferredSize; } @@ -562,24 +574,18 @@ public: err = asioObject->disposeBuffers(); JUCE_ASIO_LOG ("creating buffers: " + String (totalBuffers) + ", " + String (currentBlockSizeSamples)); - err = asioObject->createBuffers (bufferInfos, - totalBuffers, - currentBlockSizeSamples, - &callbacks); + err = asioObject->createBuffers (bufferInfos, totalBuffers, currentBlockSizeSamples, &callbacks); - if (err != 0) + if (err != ASE_OK) { currentBlockSizeSamples = preferredSize; JUCE_ASIO_LOG_ERROR ("create buffers 2", err); asioObject->disposeBuffers(); - err = asioObject->createBuffers (bufferInfos, - totalBuffers, - currentBlockSizeSamples, - &callbacks); + err = asioObject->createBuffers (bufferInfos, totalBuffers, currentBlockSizeSamples, &callbacks); } - if (err == 0) + if (err == ASE_OK) { buffersCreated = true; @@ -848,7 +854,6 @@ private: ASIOCallbacks callbacks; CLSID classId; - const String optionalDllForDirectLoading; String error; long totalNumInputChans, totalNumOutputChans; @@ -958,6 +963,36 @@ private: return numActiveInputChans + numActiveOutputChans; } + void addBufferSizes (long minSize, long maxSize, long preferredSize, long granularity) + { + // find a list of buffer sizes.. + JUCE_ASIO_LOG (String ((int) minSize) + "->" + String ((int) maxSize) + ", " + + String ((int) preferredSize) + ", " + String ((int) granularity)); + + if (granularity >= 0) + { + granularity = jmax (16, (int) granularity); + + for (int i = jmax ((int) (minSize + 15) & ~15, (int) granularity); i < jmin (6400, (int) maxSize); i += granularity) + bufferSizes.addIfNotAlreadyThere (granularity * (i / granularity)); + } + else if (granularity < 0) + { + for (int i = 0; i < 18; ++i) + { + const int s = (1 << i); + + if (s >= minSize && s <= maxSize) + bufferSizes.add (s); + } + } + + bufferSizes.addIfNotAlreadyThere (preferredSize); + + DefaultElementComparator comparator; + bufferSizes.sort (comparator); + } + void removeCurrentDriver() { if (asioObject != nullptr) @@ -971,45 +1006,28 @@ private: { removeCurrentDriver(); - JUCE_TRY - { - if (CoCreateInstance (classId, 0, CLSCTX_INPROC_SERVER, - classId, (void**) &asioObject) == S_OK) - { - return true; - } + bool crashed = false; + bool ok = tryCreatingDriver (crashed); - // If a class isn't registered but we have a path for it, we can fallback to - // doing a direct load of the COM object (only available via the juce_createASIOAudioIODeviceForGUID function). - if (optionalDllForDirectLoading.isNotEmpty()) - { - HMODULE h = LoadLibrary (optionalDllForDirectLoading.toWideCharPointer()); + if (crashed) + JUCE_ASIO_LOG ("** Driver crashed while being opened"); - if (h != 0) - { - typedef HRESULT (CALLBACK* DllGetClassObjectFunc) (REFCLSID clsid, REFIID iid, LPVOID* ppv); - DllGetClassObjectFunc dllGetClassObject = (DllGetClassObjectFunc) GetProcAddress (h, "DllGetClassObject"); - - if (dllGetClassObject != 0) - { - IClassFactory* classFactory = nullptr; - HRESULT hr = dllGetClassObject (classId, IID_IClassFactory, (void**) &classFactory); - - if (classFactory != nullptr) - { - hr = classFactory->CreateInstance (0, classId, (void**) &asioObject); - classFactory->Release(); - } + return ok; + } - return asioObject != nullptr; - } - } - } + bool tryCreatingDriver (bool& crashed) + { + #if ! JUCE_MINGW + __try + #endif + { + return CoCreateInstance (classId, 0, CLSCTX_INPROC_SERVER, + classId, (void**) &asioObject) == S_OK; } - JUCE_CATCH_ALL - - asioObject = nullptr; + #if ! JUCE_MINGW + __except (EXCEPTION_EXECUTE_HANDLER) { crashed = true; } return false; + #endif } String getLastDriverError() const @@ -1093,29 +1111,7 @@ private: if ((err = asioObject->getBufferSize (&minSize, &maxSize, &preferredSize, &granularity)) == 0) { - // find a list of buffer sizes.. - JUCE_ASIO_LOG (String ((int) minSize) + "->" + String ((int) maxSize) + ", " + String ((int) preferredSize) + ", " + String ((int) granularity)); - - if (granularity >= 0) - { - granularity = jmax (16, (int) granularity); - - for (int i = jmax ((int) (minSize + 15) & ~15, (int) granularity); i < jmin (6400, (int) maxSize); i += granularity) - bufferSizes.addIfNotAlreadyThere (granularity * (i / granularity)); - } - else if (granularity < 0) - { - for (int i = 0; i < 18; ++i) - { - const int s = (1 << i); - - if (s >= minSize && s <= maxSize) - bufferSizes.add (s); - } - } - - if (! bufferSizes.contains (preferredSize)) - bufferSizes.insert (0, preferredSize); + addBufferSizes (minSize, maxSize, preferredSize, granularity); double currentRate = 0; asioObject->getSampleRate (¤tRate); @@ -1412,7 +1408,6 @@ public: : AudioIODeviceType ("ASIO"), hasScanned (false) { - CoInitialize (0); } ~ASIOAudioIODeviceType() @@ -1501,7 +1496,8 @@ public: const int freeSlot = findFreeSlot(); if (freeSlot >= 0) - return new ASIOAudioIODevice (this, outputDeviceName, *(classIds [index]), freeSlot, String::empty); + return new ASIOAudioIODevice (this, outputDeviceName, + classIds.getReference (index), freeSlot); } return nullptr; @@ -1516,7 +1512,7 @@ public: private: StringArray deviceNames; - OwnedArray classIds; + Array classIds; bool hasScanned; @@ -1595,7 +1591,7 @@ private: JUCE_ASIO_LOG ("found " + deviceName); deviceNames.add (deviceName); - classIds.add (new CLSID (classId)); + classIds.add (classId); } } @@ -1617,14 +1613,3 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() { return new ASIOAudioIODeviceType(); } - -AudioIODevice* juce_createASIOAudioIODeviceForGUID (const String& name, void* guid, - const String& optionalDllForDirectLoading) -{ - const int freeSlot = ASIOAudioIODeviceType::findFreeSlot(); - - if (freeSlot < 0) - return nullptr; - - return new ASIOAudioIODevice (nullptr, name, *(CLSID*) guid, freeSlot, optionalDllForDirectLoading); -}