diff --git a/mac/sound.cpp b/mac/sound.cpp index f4f5e7f0..37def7f9 100755 --- a/mac/sound.cpp +++ b/mac/sound.cpp @@ -306,6 +306,14 @@ QString CSound::LoadAndInitializeDriver ( int iDriverIdx ) { // store ID of selected driver if initialization was successful lCurDev = iDriverIdx; + + // setup callback for xruns (only for input is enough) + AudioDeviceAddPropertyListener ( audioInputDevice[lCurDev], + 0, + true, + kAudioDeviceProcessorOverload, + deviceNotification, + this ); } return strStat; @@ -358,7 +366,7 @@ QString CSound::CheckDeviceCapabilities ( ComponentInstance& NewAudioInputUnit, void CSound::CloseCoreAudio() { - // clean up "gOutputUnit" + // clean up AudioUnitUninitialize ( audioInputUnit ); AudioUnitUninitialize ( audioOutputUnit ); CloseComponent ( audioInputUnit ); @@ -437,7 +445,7 @@ int CSound::Init ( const int iNewPrefMonoBufferSize ) pBufferList->mBuffers[0].mDataByteSize = iCoreAudioBufferSizeMono * 4; // 2 bytes, 2 channels pBufferList->mBuffers[0].mData = &vecsTmpAudioSndCrdStereo[0]; - // initialize unit + // initialize units if ( AudioUnitInitialize ( audioInputUnit ) ) { throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) ); @@ -477,6 +485,27 @@ UInt32 CSound::SetBufferSize ( AudioDeviceID& audioDeviceID, return iActualMonoBufferSize; } +OSStatus CSound::deviceNotification ( AudioDeviceID, + UInt32, + Boolean, + AudioDevicePropertyID inPropertyID, + void* inRefCon ) +{ + CSound* pSound = reinterpret_cast ( inRefCon ); + + if ( inPropertyID == kAudioDeviceProcessorOverload ) + { + // xrun handling (it is important to act on xruns under CoreAudio + // since it seems that the xrun situation stays stable for a + // while and would give you a long time bad audio + +// TEST we reuse the signal which was intended only for Windows OS but +// with a modification in the client (see client.cpp) +pSound->EmitReinitRequestSignal(); + + } +} + OSStatus CSound::processInput ( void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, diff --git a/mac/sound.h b/mac/sound.h index 88264d79..57284056 100755 --- a/mac/sound.h +++ b/mac/sound.h @@ -69,6 +69,12 @@ protected: bool& bIsOutput ); // callbacks + static OSStatus deviceNotification ( AudioDeviceID, + UInt32, + Boolean, + AudioDevicePropertyID inPropertyID, + void* inRefCon ); + static OSStatus processInput ( void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, diff --git a/src/client.cpp b/src/client.cpp index dcdb5138..d5eab442 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -468,7 +468,16 @@ void CClient::OnSndCrdReinitRequest() // of doing setdev with the old driver ID -> avoid unloading driver Sound.SetDev ( Sound.GetDev() ); + +// This is a test. We reuse the SndCrdReinitRequest which was +// initially only intended for the Windows OS. But for Mac we +// must not call the client Init function to work properly, therefore +// we add the preprocesser check here +// TODO better solution was to introduce a new signal in the sound base +// and a new signal handler in the client +#if !defined ( __APPLE__ ) && !defined ( __MACOSX ) Init(); +#endif if ( bWasRunning ) {