take care of problem if input/output buffer sizes cannot be set to a common value, some cleanup
This commit is contained in:
parent
c4ae143efa
commit
db636f9d96
2 changed files with 55 additions and 45 deletions
|
@ -29,7 +29,7 @@
|
||||||
void CSound::OpenCoreAudio()
|
void CSound::OpenCoreAudio()
|
||||||
{
|
{
|
||||||
UInt32 size;
|
UInt32 size;
|
||||||
ComponentResult err;
|
ComponentResult err;
|
||||||
|
|
||||||
// open the default unit
|
// open the default unit
|
||||||
ComponentDescription desc;
|
ComponentDescription desc;
|
||||||
|
@ -45,15 +45,15 @@ void CSound::OpenCoreAudio()
|
||||||
throw CGenErr ( tr ( "No CoreAudio next component found" ) );
|
throw CGenErr ( tr ( "No CoreAudio next component found" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( OpenAComponent ( comp, &audioInputUnit ) )
|
if ( OpenAComponent ( comp, &audioInputUnit ) )
|
||||||
{
|
{
|
||||||
throw CGenErr ( tr ( "CoreAudio creating input component instance failed" ) );
|
throw CGenErr ( tr ( "CoreAudio creating input component instance failed" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( OpenAComponent ( comp, &audioOutputUnit ) )
|
if ( OpenAComponent ( comp, &audioOutputUnit ) )
|
||||||
{
|
{
|
||||||
throw CGenErr ( tr ( "CoreAudio creating output component instance failed" ) );
|
throw CGenErr ( tr ( "CoreAudio creating output component instance failed" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// we enable input and disable output for input component
|
// we enable input and disable output for input component
|
||||||
UInt32 enableIO = 1;
|
UInt32 enableIO = 1;
|
||||||
|
@ -123,7 +123,7 @@ void CSound::OpenCoreAudio()
|
||||||
sizeof ( audioOutputDevice ) ) )
|
sizeof ( audioOutputDevice ) ) )
|
||||||
{
|
{
|
||||||
throw CGenErr ( tr ( "CoreAudio output AudioUnitSetProperty call failed" ) );
|
throw CGenErr ( tr ( "CoreAudio output AudioUnitSetProperty call failed" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up a callback function for new output data
|
// set up a callback function for new output data
|
||||||
AURenderCallbackStruct output;
|
AURenderCallbackStruct output;
|
||||||
|
@ -173,17 +173,17 @@ void CSound::OpenCoreAudio()
|
||||||
throw CGenErr ( tr ( "CoreAudio stream format set property failed" ) );
|
throw CGenErr ( tr ( "CoreAudio stream format set property failed" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// check input device sample rate
|
// check input device sample rate
|
||||||
size = sizeof ( Float64 );
|
size = sizeof ( Float64 );
|
||||||
Float64 inputSampleRate;
|
Float64 inputSampleRate;
|
||||||
AudioUnitGetProperty ( audioInputUnit,
|
AudioUnitGetProperty ( audioInputUnit,
|
||||||
kAudioUnitProperty_SampleRate,
|
kAudioUnitProperty_SampleRate,
|
||||||
kAudioUnitScope_Input,
|
kAudioUnitScope_Input,
|
||||||
1,
|
1,
|
||||||
&inputSampleRate,
|
&inputSampleRate,
|
||||||
&size );
|
&size );
|
||||||
|
|
||||||
if ( static_cast<int> ( inputSampleRate ) != SYSTEM_SAMPLE_RATE )
|
if ( static_cast<int> ( inputSampleRate ) != SYSTEM_SAMPLE_RATE )
|
||||||
{
|
{
|
||||||
throw CGenErr ( QString ( tr ( "Current system audio input device sample "
|
throw CGenErr ( QString ( tr ( "Current system audio input device sample "
|
||||||
"rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in "
|
"rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in "
|
||||||
|
@ -191,17 +191,17 @@ void CSound::OpenCoreAudio()
|
||||||
static_cast<int> ( inputSampleRate ) ).arg ( SYSTEM_SAMPLE_RATE ) );
|
static_cast<int> ( inputSampleRate ) ).arg ( SYSTEM_SAMPLE_RATE ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// check output device sample rate
|
// check output device sample rate
|
||||||
size = sizeof ( Float64 );
|
size = sizeof ( Float64 );
|
||||||
Float64 outputSampleRate;
|
Float64 outputSampleRate;
|
||||||
AudioUnitGetProperty ( audioOutputUnit,
|
AudioUnitGetProperty ( audioOutputUnit,
|
||||||
kAudioUnitProperty_SampleRate,
|
kAudioUnitProperty_SampleRate,
|
||||||
kAudioUnitScope_Output,
|
kAudioUnitScope_Output,
|
||||||
0,
|
0,
|
||||||
&outputSampleRate,
|
&outputSampleRate,
|
||||||
&size );
|
&size );
|
||||||
|
|
||||||
if ( static_cast<int> ( outputSampleRate ) != SYSTEM_SAMPLE_RATE )
|
if ( static_cast<int> ( outputSampleRate ) != SYSTEM_SAMPLE_RATE )
|
||||||
{
|
{
|
||||||
throw CGenErr ( QString ( tr ( "Current system audio output device sample "
|
throw CGenErr ( QString ( tr ( "Current system audio output device sample "
|
||||||
"rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in "
|
"rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in "
|
||||||
|
@ -219,15 +219,15 @@ void CSound::CloseCoreAudio()
|
||||||
// clean up "gOutputUnit"
|
// clean up "gOutputUnit"
|
||||||
AudioUnitUninitialize ( audioInputUnit );
|
AudioUnitUninitialize ( audioInputUnit );
|
||||||
AudioUnitUninitialize ( audioOutputUnit );
|
AudioUnitUninitialize ( audioOutputUnit );
|
||||||
CloseComponent ( audioInputUnit );
|
CloseComponent ( audioInputUnit );
|
||||||
CloseComponent ( audioOutputUnit );
|
CloseComponent ( audioOutputUnit );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSound::Start()
|
void CSound::Start()
|
||||||
{
|
{
|
||||||
// start the rendering
|
// start the rendering
|
||||||
AudioOutputUnitStart ( audioInputUnit );
|
AudioOutputUnitStart ( audioInputUnit );
|
||||||
AudioOutputUnitStart ( audioOutputUnit );
|
AudioOutputUnitStart ( audioOutputUnit );
|
||||||
|
|
||||||
// call base class
|
// call base class
|
||||||
CSoundBase::Start();
|
CSoundBase::Start();
|
||||||
|
@ -236,8 +236,8 @@ void CSound::Start()
|
||||||
void CSound::Stop()
|
void CSound::Stop()
|
||||||
{
|
{
|
||||||
// stop the audio stream
|
// stop the audio stream
|
||||||
AudioOutputUnitStop ( audioInputUnit );
|
AudioOutputUnitStop ( audioInputUnit );
|
||||||
AudioOutputUnitStop ( audioOutputUnit );
|
AudioOutputUnitStop ( audioOutputUnit );
|
||||||
|
|
||||||
// call base class
|
// call base class
|
||||||
CSoundBase::Stop();
|
CSoundBase::Stop();
|
||||||
|
@ -247,7 +247,11 @@ int CSound::Init ( const int iNewPrefMonoBufferSize )
|
||||||
{
|
{
|
||||||
UInt32 iActualMonoBufferSize;
|
UInt32 iActualMonoBufferSize;
|
||||||
|
|
||||||
|
// Error message string: in case buffer sizes on input and output cannot be set to the same value
|
||||||
|
const QString strErrBufSize = tr ( "The buffer sizes of the current "
|
||||||
|
"input and output audio device cannot be set to a common value. Please "
|
||||||
|
"choose other input/output audio devices in your system settings." );
|
||||||
|
|
||||||
// try to set input buffer size
|
// try to set input buffer size
|
||||||
iActualMonoBufferSize =
|
iActualMonoBufferSize =
|
||||||
SetBufferSize ( audioInputDevice, true, iNewPrefMonoBufferSize );
|
SetBufferSize ( audioInputDevice, true, iNewPrefMonoBufferSize );
|
||||||
|
@ -256,14 +260,20 @@ int CSound::Init ( const int iNewPrefMonoBufferSize )
|
||||||
{
|
{
|
||||||
// try to set the input buffer size to the output so that we
|
// try to set the input buffer size to the output so that we
|
||||||
// have a matching pair
|
// have a matching pair
|
||||||
// TODO check if setting was successful
|
if ( SetBufferSize ( audioOutputDevice, false, iActualMonoBufferSize ) !=
|
||||||
SetBufferSize ( audioOutputDevice, false, iActualMonoBufferSize );
|
iActualMonoBufferSize )
|
||||||
|
{
|
||||||
|
throw CGenErr ( strErrBufSize );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// try to set output buffer size
|
// try to set output buffer size
|
||||||
// TODO check if setting was successful
|
if ( SetBufferSize ( audioOutputDevice, false, iNewPrefMonoBufferSize ) !=
|
||||||
SetBufferSize ( audioOutputDevice, false, iNewPrefMonoBufferSize );
|
static_cast<UInt32> ( iNewPrefMonoBufferSize ) )
|
||||||
|
{
|
||||||
|
throw CGenErr ( strErrBufSize );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// store buffer size
|
// store buffer size
|
||||||
|
@ -271,26 +281,26 @@ int CSound::Init ( const int iNewPrefMonoBufferSize )
|
||||||
|
|
||||||
// init base class
|
// init base class
|
||||||
CSoundBase::Init ( iCoreAudioBufferSizeMono );
|
CSoundBase::Init ( iCoreAudioBufferSizeMono );
|
||||||
|
|
||||||
// set internal buffer size value and calculate stereo buffer size
|
// set internal buffer size value and calculate stereo buffer size
|
||||||
iCoreAudioBufferSizeStero = 2 * iCoreAudioBufferSizeMono;
|
iCoreAudioBufferSizeStero = 2 * iCoreAudioBufferSizeMono;
|
||||||
|
|
||||||
// create memory for intermediate audio buffer
|
// create memory for intermediate audio buffer
|
||||||
vecsTmpAudioSndCrdStereo.Init ( iCoreAudioBufferSizeStero );
|
vecsTmpAudioSndCrdStereo.Init ( iCoreAudioBufferSizeStero );
|
||||||
|
|
||||||
// fill audio unit buffer struct
|
// fill audio unit buffer struct
|
||||||
pBufferList->mNumberBuffers = 1;
|
pBufferList->mNumberBuffers = 1;
|
||||||
pBufferList->mBuffers[0].mNumberChannels = 2; // stereo
|
pBufferList->mBuffers[0].mNumberChannels = 2; // stereo
|
||||||
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 unit
|
||||||
if ( AudioUnitInitialize ( audioInputUnit ) )
|
if ( AudioUnitInitialize ( audioInputUnit ) )
|
||||||
{
|
{
|
||||||
throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) );
|
throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( AudioUnitInitialize ( audioOutputUnit ) )
|
if ( AudioUnitInitialize ( audioOutputUnit ) )
|
||||||
{
|
{
|
||||||
throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) );
|
throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) );
|
||||||
}
|
}
|
||||||
|
@ -349,20 +359,20 @@ OSStatus CSound::processInput ( void* inRefCon,
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSStatus CSound::processOutput ( void* inRefCon,
|
OSStatus CSound::processOutput ( void* inRefCon,
|
||||||
AudioUnitRenderActionFlags*,
|
AudioUnitRenderActionFlags*,
|
||||||
const AudioTimeStamp*,
|
const AudioTimeStamp*,
|
||||||
UInt32,
|
UInt32,
|
||||||
UInt32,
|
UInt32,
|
||||||
AudioBufferList* ioData )
|
AudioBufferList* ioData )
|
||||||
{
|
{
|
||||||
CSound* pSound = reinterpret_cast<CSound*> ( inRefCon );
|
CSound* pSound = reinterpret_cast<CSound*> ( inRefCon );
|
||||||
|
|
||||||
QMutexLocker locker ( &pSound->Mutex );
|
QMutexLocker locker ( &pSound->Mutex );
|
||||||
|
|
||||||
memcpy ( ioData->mBuffers[0].mData,
|
memcpy ( ioData->mBuffers[0].mData,
|
||||||
&pSound->vecsTmpAudioSndCrdStereo[0],
|
&pSound->vecsTmpAudioSndCrdStereo[0],
|
||||||
pSound->pBufferList->mBuffers[0].mDataByteSize);
|
pSound->pBufferList->mBuffers[0].mDataByteSize);
|
||||||
|
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ protected:
|
||||||
|
|
||||||
static OSStatus processOutput ( void* inRefCon,AudioUnitRenderActionFlags*,
|
static OSStatus processOutput ( void* inRefCon,AudioUnitRenderActionFlags*,
|
||||||
const AudioTimeStamp*, UInt32, UInt32,
|
const AudioTimeStamp*, UInt32, UInt32,
|
||||||
AudioBufferList* ioData );
|
AudioBufferList* ioData );
|
||||||
|
|
||||||
ComponentInstance audioInputUnit;
|
ComponentInstance audioInputUnit;
|
||||||
AudioDeviceID audioInputDevice;
|
AudioDeviceID audioInputDevice;
|
||||||
|
|
Loading…
Reference in a new issue