Browse Source

ASIO: when a device refuses to change sample-rate, it now ignores this and carries on with the device's current rate.

tags/2021-05-28
jules 12 years ago
parent
commit
990a67a01e
1 changed files with 153 additions and 151 deletions
  1. +153
    -151
      modules/juce_audio_devices/native/juce_win32_ASIO.cpp

+ 153
- 151
modules/juce_audio_devices/native/juce_win32_ASIO.cpp View File

@@ -35,12 +35,13 @@
//==============================================================================
namespace ASIODebugging
{
#if ASIO_DEBUGGING
#if JUCE_ASIO_DEBUGGING
#define JUCE_ASIO_LOG(a) ASIODebugging::logMessage (a)
#define JUCE_ASIO_LOG_ERROR(a, b) ASIODebugging::logError ((a), (b))
static void logMessage (const String& message)
static void logMessage (String message)
{
message = "ASIO: " + message;
DBG (message);
Logger::writeToLog (message);
}
@@ -62,7 +63,7 @@ namespace ASIODebugging
default: break;
}
logMessage ("ASIO error: " + context + " - " + err);
logMessage ("error: " + context + " - " + err);
}
#else
static void dummyLog() {}
@@ -341,7 +342,7 @@ public:
currentASIODev[i] = nullptr;
close();
JUCE_ASIO_LOG ("ASIO - exiting");
JUCE_ASIO_LOG ("closed");
removeCurrentDriver();
}
@@ -493,7 +494,7 @@ public:
else
{
if (numSources == 0)
JUCE_ASIO_LOG ("ASIO - no clock sources!");
JUCE_ASIO_LOG ("no clock sources!");
}
{
@@ -509,7 +510,7 @@ public:
if (currentSampleRate != sampleRate)
{
JUCE_ASIO_LOG ("ASIO samplerate: " + String (currentSampleRate) + " to " + String (sampleRate));
JUCE_ASIO_LOG ("rate change: " + String (currentSampleRate) + " to " + String (sampleRate));
err = asioObject->setSampleRate (sampleRate);
if (err == ASE_NoClock && numSources > 0)
@@ -522,192 +523,157 @@ public:
Thread::sleep (10);
err = asioObject->setSampleRate (sampleRate);
}
}
if (err == 0)
{
currentSampleRate = sampleRate;
if (err == 0)
currentSampleRate = sampleRate;
if (needToReset)
{
JUCE_ASIO_LOG ("! Resetting ASIO after sample rate change");
removeCurrentDriver();
// on fail, ignore the attempt to change rate, and run with the current one..
}
loadDriver();
const String error (initDriver());
if (needToReset)
{
JUCE_ASIO_LOG (" Resetting");
removeCurrentDriver();
if (error.isNotEmpty())
JUCE_ASIO_LOG ("ASIOInit: " + error);
loadDriver();
const String error (initDriver());
needToReset = false;
}
if (error.isNotEmpty())
JUCE_ASIO_LOG ("ASIOInit: " + error);
numActiveInputChans = 0;
numActiveOutputChans = 0;
needToReset = false;
}
ASIOBufferInfo* info = bufferInfos;
for (int i = 0; i < totalNumInputChans; ++i)
{
if (inputChannels[i])
{
currentChansIn.setBit (i);
info->isInput = 1;
info->channelNum = i;
info->buffers[0] = info->buffers[1] = nullptr;
++info;
++numActiveInputChans;
}
}
const int totalBuffers = resetBuffers (inputChannels, outputChannels);
for (int i = 0; i < totalNumOutputChans; ++i)
{
if (outputChannels[i])
{
currentChansOut.setBit (i);
info->isInput = 0;
info->channelNum = i;
info->buffers[0] = info->buffers[1] = nullptr;
++info;
++numActiveOutputChans;
}
}
setCallbackFunctions();
const int totalBuffers = numActiveInputChans + numActiveOutputChans;
JUCE_ASIO_LOG ("disposing buffers");
err = asioObject->disposeBuffers();
setCallbackFunctions();
JUCE_ASIO_LOG ("creating buffers: " + String (totalBuffers) + ", " + String (currentBlockSizeSamples));
err = asioObject->createBuffers (bufferInfos,
totalBuffers,
currentBlockSizeSamples,
&callbacks);
JUCE_ASIO_LOG ("disposing buffers");
err = asioObject->disposeBuffers();
if (err != 0)
{
currentBlockSizeSamples = preferredSize;
JUCE_ASIO_LOG_ERROR ("create buffers 2", err);
JUCE_ASIO_LOG ("creating buffers: " + String (totalBuffers) + ", " + String (currentBlockSizeSamples));
asioObject->disposeBuffers();
err = asioObject->createBuffers (bufferInfos,
totalBuffers,
currentBlockSizeSamples,
&callbacks);
}
if (err != 0)
{
currentBlockSizeSamples = preferredSize;
JUCE_ASIO_LOG_ERROR ("create buffers 2", err);
asioObject->disposeBuffers();
err = asioObject->createBuffers (bufferInfos,
totalBuffers,
currentBlockSizeSamples,
&callbacks);
}
if (err == 0)
{
buffersCreated = true;
if (err == 0)
{
buffersCreated = true;
tempBuffer.calloc (totalBuffers * currentBlockSizeSamples + 32);
tempBuffer.calloc (totalBuffers * currentBlockSizeSamples + 32);
int n = 0;
Array <int> types;
currentBitDepth = 16;
int n = 0;
Array <int> types;
currentBitDepth = 16;
for (int i = 0; i < (int) totalNumInputChans; ++i)
for (int i = 0; i < (int) totalNumInputChans; ++i)
{
if (inputChannels[i])
{
if (inputChannels[i])
{
inBuffers[n] = tempBuffer + (currentBlockSizeSamples * n);
inBuffers[n] = tempBuffer + (currentBlockSizeSamples * n);
ASIOChannelInfo channelInfo = { 0 };
channelInfo.channel = i;
channelInfo.isInput = 1;
asioObject->getChannelInfo (&channelInfo);
ASIOChannelInfo channelInfo = { 0 };
channelInfo.channel = i;
channelInfo.isInput = 1;
asioObject->getChannelInfo (&channelInfo);
types.addIfNotAlreadyThere (channelInfo.type);
inputFormat[n] = ASIOSampleFormat (channelInfo.type);
types.addIfNotAlreadyThere (channelInfo.type);
inputFormat[n] = ASIOSampleFormat (channelInfo.type);
currentBitDepth = jmax (currentBitDepth, inputFormat[n].bitDepth);
++n;
}
currentBitDepth = jmax (currentBitDepth, inputFormat[n].bitDepth);
++n;
}
}
jassert (numActiveInputChans == n);
n = 0;
jassert (numActiveInputChans == n);
n = 0;
for (int i = 0; i < (int) totalNumOutputChans; ++i)
for (int i = 0; i < (int) totalNumOutputChans; ++i)
{
if (outputChannels[i])
{
if (outputChannels[i])
{
outBuffers[n] = tempBuffer + (currentBlockSizeSamples * (numActiveInputChans + n));
outBuffers[n] = tempBuffer + (currentBlockSizeSamples * (numActiveInputChans + n));
ASIOChannelInfo channelInfo = { 0 };
channelInfo.channel = i;
channelInfo.isInput = 0;
asioObject->getChannelInfo (&channelInfo);
ASIOChannelInfo channelInfo = { 0 };
channelInfo.channel = i;
channelInfo.isInput = 0;
asioObject->getChannelInfo (&channelInfo);
types.addIfNotAlreadyThere (channelInfo.type);
outputFormat[n] = ASIOSampleFormat (channelInfo.type);
types.addIfNotAlreadyThere (channelInfo.type);
outputFormat[n] = ASIOSampleFormat (channelInfo.type);
currentBitDepth = jmax (currentBitDepth, outputFormat[n].bitDepth);
++n;
}
currentBitDepth = jmax (currentBitDepth, outputFormat[n].bitDepth);
++n;
}
}
jassert (numActiveOutputChans == n);
jassert (numActiveOutputChans == n);
for (int i = types.size(); --i >= 0;)
JUCE_ASIO_LOG ("channel format: " + String (types[i]));
for (int i = types.size(); --i >= 0;)
JUCE_ASIO_LOG ("channel format: " + String (types[i]));
jassert (n <= totalBuffers);
jassert (n <= totalBuffers);
for (int i = 0; i < numActiveOutputChans; ++i)
{
outputFormat[i].clear (bufferInfos [numActiveInputChans + i].buffers[0], currentBlockSizeSamples);
outputFormat[i].clear (bufferInfos [numActiveInputChans + i].buffers[1], currentBlockSizeSamples);
}
for (int i = 0; i < numActiveOutputChans; ++i)
{
outputFormat[i].clear (bufferInfos [numActiveInputChans + i].buffers[0], currentBlockSizeSamples);
outputFormat[i].clear (bufferInfos [numActiveInputChans + i].buffers[1], currentBlockSizeSamples);
}
inputLatency = outputLatency = 0;
inputLatency = outputLatency = 0;
if (asioObject->getLatencies (&inputLatency, &outputLatency) != 0)
JUCE_ASIO_LOG ("ASIO - no latencies");
else
JUCE_ASIO_LOG ("ASIO latencies: " + String ((int) outputLatency) + ", " + String ((int) inputLatency));
if (asioObject->getLatencies (&inputLatency, &outputLatency) != 0)
JUCE_ASIO_LOG ("no latencies");
else
JUCE_ASIO_LOG ("latencies: " + String ((int) outputLatency) + ", " + String ((int) inputLatency));
deviceIsOpen = true;
deviceIsOpen = true;
JUCE_ASIO_LOG ("starting ASIO");
calledback = false;
err = asioObject->start();
JUCE_ASIO_LOG ("starting");
calledback = false;
err = asioObject->start();
if (err != 0)
{
deviceIsOpen = false;
JUCE_ASIO_LOG ("ASIO - stop on failure");
Thread::sleep (10);
asioObject->stop();
error = "Can't start device";
if (err != 0)
{
deviceIsOpen = false;
JUCE_ASIO_LOG ("stop on failure");
Thread::sleep (10);
asioObject->stop();
error = "Can't start device";
Thread::sleep (10);
}
else
{
int count = 300;
while (--count > 0 && ! calledback)
Thread::sleep (10);
}
else
{
int count = 300;
while (--count > 0 && ! calledback)
Thread::sleep (10);
isStarted = true;
isStarted = true;
if (! calledback)
{
error = "Device didn't start correctly";
JUCE_ASIO_LOG ("ASIO didn't callback - stopping..");
asioObject->stop();
}
if (! calledback)
{
error = "Device didn't start correctly";
JUCE_ASIO_LOG ("no callbacks - stopping..");
asioObject->stop();
}
}
else
{
error = "Can't create i/o buffers";
}
}
else
{
error = "Can't set sample rate: ";
error << sampleRate;
error = "Can't create i/o buffers";
}
if (error.isNotEmpty())
@@ -742,7 +708,7 @@ public:
isStarted = false;
needToReset = false;
JUCE_ASIO_LOG ("ASIO - stopping");
JUCE_ASIO_LOG ("stopping");
if (asioObject != nullptr)
{
@@ -798,7 +764,7 @@ public:
bool showControlPanel()
{
JUCE_ASIO_LOG ("ASIO - showing control panel");
JUCE_ASIO_LOG ("showing control panel");
bool done = false;
@@ -843,7 +809,7 @@ public:
stopTimer();
// used to cause a reset
JUCE_ASIO_LOG ("! ASIO restart request!");
JUCE_ASIO_LOG ("restart request!");
if (deviceIsOpen)
{
@@ -914,6 +880,42 @@ private:
return wideVersion;
}
int resetBuffers (const BigInteger& inputChannels,
const BigInteger& outputChannels)
{
numActiveInputChans = 0;
numActiveOutputChans = 0;
ASIOBufferInfo* info = bufferInfos;
for (int i = 0; i < totalNumInputChans; ++i)
{
if (inputChannels[i])
{
currentChansIn.setBit (i);
info->isInput = 1;
info->channelNum = i;
info->buffers[0] = info->buffers[1] = nullptr;
++info;
++numActiveInputChans;
}
}
for (int i = 0; i < totalNumOutputChans; ++i)
{
if (outputChannels[i])
{
currentChansOut.setBit (i);
info->isInput = 0;
info->channelNum = i;
info->buffers[0] = info->buffers[1] = nullptr;
++info;
++numActiveOutputChans;
}
}
return numActiveInputChans + numActiveOutputChans;
}
void removeCurrentDriver()
{
if (asioObject != nullptr)
@@ -1004,7 +1006,7 @@ private:
String openDevice()
{
// open the device and get its info..
JUCE_ASIO_LOG ("opening ASIO device: " + getName());
JUCE_ASIO_LOG ("opening device: " + getName());
needToReset = false;
outputChannelNames.clear();
@@ -1089,14 +1091,14 @@ private:
postOutput = (asioObject->outputReady() == 0);
if (postOutput)
JUCE_ASIO_LOG ("ASIO outputReady = ok");
JUCE_ASIO_LOG ("outputReady true");
updateSampleRates();
// ..because cubase does it at this point
inputLatency = outputLatency = 0;
if (asioObject->getLatencies (&inputLatency, &outputLatency) != 0)
JUCE_ASIO_LOG ("ASIO - no latencies");
JUCE_ASIO_LOG ("no latencies");
JUCE_ASIO_LOG ("latencies: " + String ((int) inputLatency) + ", " + String ((int) outputLatency));
@@ -1187,7 +1189,7 @@ private:
err = asioObject->start();
// ignore an error here, as it might start later after setting other stuff up
JUCE_ASIO_LOG_ERROR ("ASIO start", err);
JUCE_ASIO_LOG_ERROR ("start", err);
Thread::sleep (100);
asioObject->stop();
@@ -1218,7 +1220,7 @@ private:
else
{
isASIOOpen = true;
JUCE_ASIO_LOG ("ASIO device open");
JUCE_ASIO_LOG ("device open");
}
deviceIsOpen = false;


Loading…
Cancel
Save