Hi,
First, the context:
For a particular application I am trying to restrict the user in setting sensible settings for his soundcard (buffersize between 1024 and 4096, samplerate 44100). To do that, I am showing a component that has the standard AudioDeviceSelectorComponent, launch a dialog with that component, and upon returning, I check the selected settings. If they are not OK, I find out which settings are available that do meet my criteria, and try to set the device to these settings using AudioDeviceManager::setAudioDeviceSetup (followed by a warning dialog box informing the user).
I know:
- it could be better to restrict the options in the audio setup dialog itself, by creating my own AudioDeviceSelectorComponent but no time for that…
- my code should work properly with all samplerates and buffer sizes, and that’s going to happen in the end, but not now…
Anyway:
When I call AudioDeviceManager::setAudioDeviceSetup, it looks like the underlying code is not handling the requested buffersize correctly. [this is on Windows7 64-bit, latest Juce pulled from git just some minutes ago]
If the user had set the device to a buffersize of 64, I correct that by getting the current audio device setup, copying it and changing the bufferSize value to 1024, or in code:
AudioDeviceManager::AudioDeviceSetup oldDeviceSetup, newDeviceSetup;
deviceManager.getAudioDeviceSetup(oldDeviceSetup);
newDeviceSetup = oldDeviceSetup;
// ... some checking and condition handling ...
newDeviceSetup.bufferSize = 1024; // note: this is the only change made
String error = deviceManager.setAudioDeviceSetup(newDeviceSetup,true);
// ... check error string ...
What I am seeing, is that this does not always work (on the same computer with the same sound card). The buffer size is not changed to 1024, although the error string is empty, and the audio card can be set to 1024 at that sample rate.
When stepping into the code, AudioDeviceManager::setAudioDeviceSetup somewhere calls ASIOAudioIODevice::open (still with the correct new bufferSize 1024) and we reach the following lines of code:
[code]long newPreferredSize = 0;
if (asioObject->getBufferSize (&minSize, &maxSize, &newPreferredSize, &granularity) == ASE_OK)
{
if (preferredSize != 0 && newPreferredSize != 0 && newPreferredSize != preferredSize)
shouldUsePreferredSize = true;
if (bufferSizeSamples < minSize || bufferSizeSamples > maxSize)
shouldUsePreferredSize = true;
preferredSize = newPreferredSize;
}[/code]
What I see happen, is that the first if within the “if (asioObject->getBufferSize…” block evaluates to true, and makes shouldUsePreferredSize end up true. Further down, we then end up in:
[code]if (shouldUsePreferredSize)
{
JUCE_ASIO_LOG (“Using preferred size for buffer…”);
if ((err = asioObject->getBufferSize (&minSize, &maxSize, &preferredSize, &granularity)) == ASE_OK)
{
bufferSizeSamples = preferredSize;
}
else
{
bufferSizeSamples = 1024;
JUCE_ASIO_LOG_ERROR ("getBufferSize1", err);
}
shouldUsePreferredSize = false;
}[/code]
and this means my supplied bufferSizeSamples gets totally ignored, and replaced by the preferred buffer size of the sound card.
–> While I of course do understand the range checking with minSize and maxSize (the second if clause in the big if clause), it seems like that first if clause above that can lead to a situation where the supplied buffer size is totally ignored.
Why should the buffer size be set to the preferred size if that changed from the last preferred size? Shouldn’t the supplied buffer size be used if it is in the valid range for the sound card?