support for setting device buffer size, some cleanup

This commit is contained in:
Volker Fischer 2010-03-11 19:12:30 +00:00
parent d5cb9d821d
commit 0e624d3b99
2 changed files with 72 additions and 43 deletions

View File

@ -43,14 +43,6 @@ static FILE* pFile = fopen ( "test.dat", "w" );
// TEST
// allocated to hold buffer data
AudioBufferList* theBufferList;
/* Implementation *************************************************************/ /* Implementation *************************************************************/
void CSound::OpenCoreAudio() void CSound::OpenCoreAudio()
{ {
@ -100,10 +92,9 @@ void CSound::OpenCoreAudio()
// set input device // set input device
size = sizeof ( AudioDeviceID ); size = sizeof ( AudioDeviceID );
AudioDeviceID inputDevice;
if ( AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultInputDevice, if ( AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultInputDevice,
&size, &size,
&inputDevice ) ) &audioInputDevice ) )
{ {
throw CGenErr ( tr ( "CoreAudio input AudioHardwareGetProperty call failed" ) ); throw CGenErr ( tr ( "CoreAudio input AudioHardwareGetProperty call failed" ) );
} }
@ -112,8 +103,8 @@ void CSound::OpenCoreAudio()
kAudioOutputUnitProperty_CurrentDevice, kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global, kAudioUnitScope_Global,
1, 1,
&inputDevice, &audioInputDevice,
sizeof ( inputDevice ) ) ) sizeof ( audioInputDevice ) ) )
{ {
throw CGenErr ( tr ( "CoreAudio input AudioUnitSetProperty call failed" ) ); throw CGenErr ( tr ( "CoreAudio input AudioUnitSetProperty call failed" ) );
} }
@ -135,10 +126,9 @@ void CSound::OpenCoreAudio()
// set output device // set output device
size = sizeof ( AudioDeviceID ); size = sizeof ( AudioDeviceID );
AudioDeviceID outputDevice;
if ( AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultOutputDevice, if ( AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultOutputDevice,
&size, &size,
&outputDevice ) ) &audioOutputDevice ) )
{ {
throw CGenErr ( tr ( "CoreAudio output AudioHardwareGetProperty call failed" ) ); throw CGenErr ( tr ( "CoreAudio output AudioHardwareGetProperty call failed" ) );
} }
@ -147,8 +137,8 @@ void CSound::OpenCoreAudio()
kAudioOutputUnitProperty_CurrentDevice, kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global, kAudioUnitScope_Global,
0, 0,
&outputDevice, &audioOutputDevice,
sizeof ( outputDevice ) ) ) sizeof ( audioOutputDevice ) ) )
{ {
throw CGenErr ( tr ( "CoreAudio output AudioUnitSetProperty call failed" ) ); throw CGenErr ( tr ( "CoreAudio output AudioUnitSetProperty call failed" ) );
} }
@ -276,24 +266,28 @@ void CSound::Stop()
int CSound::Init ( const int iNewPrefMonoBufferSize ) int CSound::Init ( const int iNewPrefMonoBufferSize )
{ {
UInt32 iActualMonoBufferSize;
// TODO try to set the preferred buffer size to the audio unit
// get the audio unit buffer size
UInt32 bufferSizeFrames;
UInt32 propertySize = sizeof(UInt32);
// TEST
AudioUnitGetProperty ( audioOutputUnit, kAudioDevicePropertyBufferFrameSize,
kAudioUnitScope_Global, 1, &bufferSizeFrames, &propertySize );
printf("out buf size: %d\n",bufferSizeFrames);
AudioUnitGetProperty ( audioInputUnit, kAudioDevicePropertyBufferFrameSize, // try to set input buffer size
kAudioUnitScope_Global, 1, &bufferSizeFrames, &propertySize ); iActualMonoBufferSize =
SetBufferSize ( audioInputDevice, true, iNewPrefMonoBufferSize );
if ( iActualMonoBufferSize != static_cast<UInt32> ( iNewPrefMonoBufferSize ) )
{
// try to set the input buffer size to the output so that we
// have a matching pair
// TODO check if setting was successful
SetBufferSize ( audioOutputDevice, false, iActualMonoBufferSize );
}
else
{
// try to set output buffer size
// TODO check if setting was successful
SetBufferSize ( audioOutputDevice, false, iNewPrefMonoBufferSize );
}
// store buffer size // store buffer size
iCoreAudioBufferSizeMono = bufferSizeFrames; iCoreAudioBufferSizeMono = iActualMonoBufferSize;
// init base class // init base class
CSoundBase::Init ( iCoreAudioBufferSizeMono ); CSoundBase::Init ( iCoreAudioBufferSizeMono );
@ -305,22 +299,18 @@ printf("out buf size: %d\n",bufferSizeFrames);
vecsTmpAudioSndCrdStereo.Init ( iCoreAudioBufferSizeStero ); vecsTmpAudioSndCrdStereo.Init ( iCoreAudioBufferSizeStero );
// TEST
printf ( "Buffer_Size: %d", (int) bufferSizeFrames );
// TODO // TODO
// fill audio unit buffer struct // fill audio unit buffer struct
theBufferList = (AudioBufferList*) malloc ( offsetof ( AudioBufferList, pBufferList = (AudioBufferList*) malloc ( offsetof ( AudioBufferList,
mBuffers[0] ) + sizeof(AudioBuffer) ); mBuffers[0] ) + sizeof(AudioBuffer) );
//(sizeof(AudioBufferList) + (numChannels-1)) * sizeof(AudioBuffer) //(sizeof(AudioBufferList) + (numChannels-1)) * sizeof(AudioBuffer)
theBufferList->mNumberBuffers = 1; pBufferList->mNumberBuffers = 1;
theBufferList->mBuffers[0].mNumberChannels = 2; // stereo pBufferList->mBuffers[0].mNumberChannels = 2; // stereo
theBufferList->mBuffers[0].mDataByteSize = bufferSizeFrames * 4; // 2 bytes, 2 channels pBufferList->mBuffers[0].mDataByteSize = iCoreAudioBufferSizeMono * 4; // 2 bytes, 2 channels
theBufferList->mBuffers[0].mData = &vecsTmpAudioSndCrdStereo[0]; pBufferList->mBuffers[0].mData = &vecsTmpAudioSndCrdStereo[0];
// initialize unit // initialize unit
if ( AudioUnitInitialize ( audioInputUnit ) ) if ( AudioUnitInitialize ( audioInputUnit ) )
@ -336,6 +326,32 @@ theBufferList = (AudioBufferList*) malloc ( offsetof ( AudioBufferList,
return iCoreAudioBufferSizeMono; return iCoreAudioBufferSizeMono;
} }
UInt32 CSound::SetBufferSize ( AudioDeviceID& audioDeviceID,
const bool bIsInput,
UInt32 iPrefBufferSize )
{
// first set the value
UInt32 iSizeBufValue = sizeof ( UInt32 );
AudioDeviceSetProperty ( audioDeviceID,
NULL,
0,
bIsInput,
kAudioDevicePropertyBufferFrameSize,
iSizeBufValue,
&iPrefBufferSize );
// read back which value is actually used
UInt32 iActualMonoBufferSize;
AudioDeviceGetProperty ( audioDeviceID,
0,
bIsInput,
kAudioDevicePropertyBufferFrameSize,
&iSizeBufValue,
&iActualMonoBufferSize );
return iActualMonoBufferSize;
}
OSStatus CSound::processInput ( void* inRefCon, OSStatus CSound::processInput ( void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags, AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, const AudioTimeStamp* inTimeStamp,
@ -345,6 +361,8 @@ OSStatus CSound::processInput ( void* inRefCon,
{ {
CSound* pSound = reinterpret_cast<CSound*> ( inRefCon ); CSound* pSound = reinterpret_cast<CSound*> ( inRefCon );
QMutexLocker locker ( &pSound->Mutex );
// get the new audio data // get the new audio data
ComponentResult err = ComponentResult err =
AudioUnitRender ( pSound->audioInputUnit, AudioUnitRender ( pSound->audioInputUnit,
@ -352,7 +370,7 @@ OSStatus CSound::processInput ( void* inRefCon,
inTimeStamp, inTimeStamp,
inBusNumber, inBusNumber,
inNumberFrames, inNumberFrames,
theBufferList ); pSound->pBufferList );
// call processing callback function // call processing callback function
pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo ); pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo );
@ -369,9 +387,11 @@ OSStatus CSound::processOutput ( void* inRefCon,
{ {
CSound* pSound = reinterpret_cast<CSound*> ( inRefCon ); CSound* pSound = reinterpret_cast<CSound*> ( inRefCon );
memcpy ( ioData->mBuffers[0].mData, QMutexLocker locker ( &pSound->Mutex );
memcpy ( ioData->mBuffers[0].mData,
&pSound->vecsTmpAudioSndCrdStereo[0], &pSound->vecsTmpAudioSndCrdStereo[0],
theBufferList->mBuffers[0].mDataByteSize); pSound->pBufferList->mBuffers[0].mDataByteSize);
return noErr; return noErr;
} }

View File

@ -27,6 +27,7 @@
#include <CoreServices/CoreServices.h> #include <CoreServices/CoreServices.h>
#include <AudioUnit/AudioUnit.h> #include <AudioUnit/AudioUnit.h>
#include <qmutex.h>
#include "util.h" #include "util.h"
#include "soundbase.h" #include "soundbase.h"
#include "global.h" #include "global.h"
@ -59,6 +60,8 @@ public:
protected: protected:
void OpenCoreAudio(); void OpenCoreAudio();
void CloseCoreAudio(); void CloseCoreAudio();
UInt32 SetBufferSize ( AudioDeviceID& audioDeviceID, const bool bIsInput,
UInt32 iPrefBufferSize );
// callbacks // callbacks
static OSStatus processInput ( void* inRefCon,AudioUnitRenderActionFlags* ioActionFlags, static OSStatus processInput ( void* inRefCon,AudioUnitRenderActionFlags* ioActionFlags,
@ -70,7 +73,13 @@ protected:
AudioBufferList* ioData ); AudioBufferList* ioData );
ComponentInstance audioInputUnit; ComponentInstance audioInputUnit;
AudioDeviceID audioInputDevice;
ComponentInstance audioOutputUnit; ComponentInstance audioOutputUnit;
AudioDeviceID audioOutputDevice;
AudioBufferList* pBufferList;
QMutex Mutex;
}; };
#endif // !defined(_SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_) #endif // !defined(_SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_)