Browse Source

ASIO fixes and clean-ups.

tags/2021-05-28
jules 13 years ago
parent
commit
44318021f3
1 changed files with 76 additions and 91 deletions
  1. +76
    -91
      modules/juce_audio_devices/native/juce_win32_ASIO.cpp

+ 76
- 91
modules/juce_audio_devices/native/juce_win32_ASIO.cpp View File

@@ -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 <int> 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 (&currentRate);
@@ -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 <CLSID> classIds;
Array<CLSID> 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);
}

Loading…
Cancel
Save