Audaspace: Workaround Core Audio clock quirk
This commit is contained in:
committed by
Sebastian Parborg
parent
034478fe07
commit
898877e8b3
@@ -46,6 +46,22 @@ OSStatus CoreAudioDevice::CoreAudio_mix(void* data, AudioUnitRenderActionFlags*
|
||||
device->notifyMixingThread();
|
||||
}
|
||||
|
||||
if (!device->m_audio_clock_ready) {
|
||||
// Workaround CoreAudio quirk that corrupts the clock time data when the first mix callback occurs.
|
||||
// Both the start time and current time will be invalid. We need to reset them.
|
||||
if(device->isSynchronizerPlaying())
|
||||
CAClockStop(device->m_clock_ref);
|
||||
|
||||
CAClockTime clock_time;
|
||||
clock_time.format = kCAClockTimeFormat_Seconds;
|
||||
clock_time.time.seconds = device->m_synchronizerStartTime;
|
||||
CAClockSetCurrentTime(device->m_clock_ref, &clock_time);
|
||||
|
||||
if(device->isSynchronizerPlaying())
|
||||
CAClockStart(device->m_clock_ref);
|
||||
device->m_audio_clock_ready = true;
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
@@ -62,7 +78,7 @@ void CoreAudioDevice::playing(bool playing)
|
||||
m_playback = playing;
|
||||
}
|
||||
|
||||
CoreAudioDevice::CoreAudioDevice(DeviceSpecs specs, int buffersize) : m_buffersize(uint32_t(buffersize)), m_playback(false), m_audio_unit(nullptr)
|
||||
CoreAudioDevice::CoreAudioDevice(DeviceSpecs specs, int buffersize) : m_buffersize(uint32_t(buffersize)), m_playback(false), m_audio_unit(nullptr), m_audio_clock_ready(false)
|
||||
{
|
||||
if(specs.channels == CHANNELS_INVALID)
|
||||
specs.channels = CHANNELS_STEREO;
|
||||
@@ -208,12 +224,6 @@ CoreAudioDevice::CoreAudioDevice(DeviceSpecs specs, int buffersize) : m_buffersi
|
||||
throw;
|
||||
}
|
||||
|
||||
/* Workaround CoreAudio quirk that makes the Clock (m_clock_ref) be in an invalid state
|
||||
* after we try to re-init the device. (It is fine the first time we init the device...)
|
||||
* We have to do a start/stop toggle to get it into a valid state again. */
|
||||
AudioOutputUnitStart(m_audio_unit);
|
||||
AudioOutputUnitStop(m_audio_unit);
|
||||
|
||||
create();
|
||||
|
||||
startMixingThread(buffersize * 2 * AUD_DEVICE_SAMPLE_SIZE(specs));
|
||||
@@ -244,6 +254,7 @@ void CoreAudioDevice::seekSynchronizer(double time)
|
||||
clock_time.format = kCAClockTimeFormat_Seconds;
|
||||
clock_time.time.seconds = time;
|
||||
CAClockSetCurrentTime(m_clock_ref, &clock_time);
|
||||
m_synchronizerStartTime = time;
|
||||
|
||||
if(isSynchronizerPlaying())
|
||||
CAClockStart(m_clock_ref);
|
||||
@@ -257,7 +268,7 @@ double CoreAudioDevice::getSynchronizerPosition()
|
||||
|
||||
OSStatus status;
|
||||
|
||||
if(isSynchronizerPlaying())
|
||||
if(isSynchronizerPlaying() && m_audio_clock_ready)
|
||||
status = CAClockGetCurrentTime(m_clock_ref, kCAClockTimeFormat_Seconds, &clock_time);
|
||||
else
|
||||
status = CAClockGetStartTime(m_clock_ref, kCAClockTimeFormat_Seconds, &clock_time);
|
||||
|
||||
@@ -56,6 +56,8 @@ private:
|
||||
|
||||
/// The CoreAudio clock referene.
|
||||
CAClockRef m_clock_ref;
|
||||
bool m_audio_clock_ready;
|
||||
double m_synchronizerStartTime{0};
|
||||
|
||||
/**
|
||||
* Mixes the next bytes into the buffer.
|
||||
|
||||
Reference in New Issue
Block a user