Fix a problem with ASIO buffer sizes on Windows

PortAudio uses what it calls 'default suggested latencies' but in callback streaming mode, they can result in wildly inaccurate buffer sizing (e.g. the user requests a buffer size of 128 but PortAudio actually instructs ASIO to use a much bigger size).

What we do now is to improve PortAudio's suggested latency calculation by basing it on the actual buffer size requested by the user.
This commit is contained in:
John Emmas 2021-03-18 16:12:28 +00:00
parent 3bda6020b9
commit a2b1482cad
2 changed files with 20 additions and 6 deletions

View File

@ -698,7 +698,9 @@ PortAudioIO::get_input_stream_params(int device_input,
#else
inputParam.sampleFormat = paFloat32 | paNonInterleaved;
#endif
inputParam.suggestedLatency = nfo_in->defaultLowInputLatency;
if (!inputParam.suggestedLatency) {
inputParam.suggestedLatency = nfo_in->defaultLowInputLatency;
}
inputParam.hostApiSpecificStreamInfo = NULL;
return true;
@ -732,7 +734,9 @@ PortAudioIO::get_output_stream_params(int device_output,
#else
outputParam.sampleFormat = paFloat32 | paNonInterleaved;
#endif
outputParam.suggestedLatency = nfo_out->defaultLowOutputLatency;
if (!outputParam.suggestedLatency) {
outputParam.suggestedLatency = nfo_out->defaultLowOutputLatency;
}
outputParam.hostApiSpecificStreamInfo = NULL;
return true;
@ -742,7 +746,9 @@ PaErrorCode
PortAudioIO::pre_stream_open(int device_input,
PaStreamParameters& inputParam,
int device_output,
PaStreamParameters& outputParam)
PaStreamParameters& outputParam,
uint32_t sample_rate,
uint32_t samples_per_period)
{
if (!pa_initialize()) {
DEBUG_AUDIO ("PortAudio Initialization Failed\n");
@ -758,6 +764,12 @@ PortAudioIO::pre_stream_open(int device_input,
return paBadIODeviceCombination;
}
if ((get_current_host_api_type() == paASIO) && sample_rate) {
outputParam.suggestedLatency = inputParam.suggestedLatency = ((double)samples_per_period / (double)sample_rate);
} else {
outputParam.suggestedLatency = inputParam.suggestedLatency = 0;
}
if (get_input_stream_params(device_input, inputParam)) {
_capture_channels = inputParam.channelCount;
}
@ -790,7 +802,7 @@ PortAudioIO::open_callback_stream(int device_input,
PaStreamParameters outputParam;
PaErrorCode error_code =
pre_stream_open(device_input, inputParam, device_output, outputParam);
pre_stream_open(device_input, inputParam, device_output, outputParam, sample_rate, samples_per_period);
if (error_code != paNoError) return error_code;
@ -832,7 +844,7 @@ PortAudioIO::open_blocking_stream(int device_input,
PaStreamParameters outputParam;
PaErrorCode error_code =
pre_stream_open(device_input, inputParam, device_output, outputParam);
pre_stream_open(device_input, inputParam, device_output, outputParam, sample_rate, samples_per_period);
if (error_code != paNoError) return error_code;

View File

@ -128,7 +128,9 @@ private: // Methods
PaErrorCode pre_stream_open(int device_input,
PaStreamParameters& inputParam,
int device_output,
PaStreamParameters& outputParam);
PaStreamParameters& outputParam,
uint32_t sample_rate,
uint32_t samples_per_period);
void reset_stream_dependents ();