fix for bad audio under Mac for some USB sound cards

This commit is contained in:
Volker Fischer 2012-01-23 21:01:18 +00:00
parent 18ff7f2dc4
commit e50abe3a67
3 changed files with 46 additions and 2 deletions

View file

@ -306,6 +306,14 @@ QString CSound::LoadAndInitializeDriver ( int iDriverIdx )
{ {
// store ID of selected driver if initialization was successful // store ID of selected driver if initialization was successful
lCurDev = iDriverIdx; lCurDev = iDriverIdx;
// setup callback for xruns (only for input is enough)
AudioDeviceAddPropertyListener ( audioInputDevice[lCurDev],
0,
true,
kAudioDeviceProcessorOverload,
deviceNotification,
this );
} }
return strStat; return strStat;
@ -358,7 +366,7 @@ QString CSound::CheckDeviceCapabilities ( ComponentInstance& NewAudioInputUnit,
void CSound::CloseCoreAudio() void CSound::CloseCoreAudio()
{ {
// clean up "gOutputUnit" // clean up
AudioUnitUninitialize ( audioInputUnit ); AudioUnitUninitialize ( audioInputUnit );
AudioUnitUninitialize ( audioOutputUnit ); AudioUnitUninitialize ( audioOutputUnit );
CloseComponent ( audioInputUnit ); 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].mDataByteSize = iCoreAudioBufferSizeMono * 4; // 2 bytes, 2 channels
pBufferList->mBuffers[0].mData = &vecsTmpAudioSndCrdStereo[0]; pBufferList->mBuffers[0].mData = &vecsTmpAudioSndCrdStereo[0];
// initialize unit // initialize units
if ( AudioUnitInitialize ( audioInputUnit ) ) if ( AudioUnitInitialize ( audioInputUnit ) )
{ {
throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) ); throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) );
@ -477,6 +485,27 @@ UInt32 CSound::SetBufferSize ( AudioDeviceID& audioDeviceID,
return iActualMonoBufferSize; return iActualMonoBufferSize;
} }
OSStatus CSound::deviceNotification ( AudioDeviceID,
UInt32,
Boolean,
AudioDevicePropertyID inPropertyID,
void* inRefCon )
{
CSound* pSound = reinterpret_cast<CSound*> ( 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, OSStatus CSound::processInput ( void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags, AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, const AudioTimeStamp* inTimeStamp,

View file

@ -69,6 +69,12 @@ protected:
bool& bIsOutput ); bool& bIsOutput );
// callbacks // callbacks
static OSStatus deviceNotification ( AudioDeviceID,
UInt32,
Boolean,
AudioDevicePropertyID inPropertyID,
void* inRefCon );
static OSStatus processInput ( void* inRefCon, static OSStatus processInput ( void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags, AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, const AudioTimeStamp* inTimeStamp,

View file

@ -468,7 +468,16 @@ void CClient::OnSndCrdReinitRequest()
// of doing setdev with the old driver ID -> avoid unloading driver // of doing setdev with the old driver ID -> avoid unloading driver
Sound.SetDev ( Sound.GetDev() ); 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(); Init();
#endif
if ( bWasRunning ) if ( bWasRunning )
{ {