Good thought myhrman, but after a couple of hours of mucking around I’ve yet to see a non-zero stream latency.
The following code grafted into juce_mac_CoreAudio.cpp only checks the first stream, but I’ve tried looping through them all and checking that the AudioObjectGetPropertyData is successful. However I still only get zero unfortunately.
int getLatencyFromDevice (AudioObjectPropertyScope scope) const
{
UInt32 deviceLatency = 0;
UInt32 size = sizeof (deviceLatency);
AudioObjectPropertyAddress pa;
pa.mElement = kAudioObjectPropertyElementMaster;
pa.mSelector = kAudioDevicePropertyLatency;
pa.mScope = scope;
AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &deviceLatency);
UInt32 safetyOffset = 0;
size = sizeof (safetyOffset);
pa.mSelector = kAudioDevicePropertySafetyOffset;
AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &safetyOffset);
// Query stream latency
UInt32 streamLatency = 0;
UInt32 numStreams;
pa.mSelector = kAudioDevicePropertyStreams;
if (OK(AudioObjectGetPropertyDataSize (deviceID, &pa, 0, nullptr, &numStreams)))
{
HeapBlock<AudioStreamID> streams (numStreams);
size = sizeof (AudioStreamID*);
if (OK(AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, streams)))
{
pa.mSelector = kAudioStreamPropertyLatency;
size = sizeof (streamLatency);
// We could check all streams for the device, but it only ever seems to return the stream latency on the first stream
AudioObjectGetPropertyData (streams[0], &pa, 0, nullptr, &size, &streamLatency);
}
}
std::cout << "deviceLatency: " << String(deviceLatency).toRawUTF8() << ", ";
std::cout << "safetyOffset: " << String(safetyOffset).toRawUTF8() << ", ";
std::cout << "streamLatency: " << String(streamLatency).toRawUTF8() << std::endl;
return (int) (deviceLatency + safetyOffset + streamLatency);
}