first working version of CoreAudio interface, still a lot to do...

This commit is contained in:
Volker Fischer 2010-03-10 21:40:47 +00:00
parent 07be35a465
commit b6ee741e2c
2 changed files with 128 additions and 83 deletions

View file

@ -71,14 +71,19 @@ void CSound::OpenCoreAudio()
throw CGenErr ( tr ( "No CoreAudio next component found" ) ); throw CGenErr ( tr ( "No CoreAudio next component found" ) );
} }
if ( OpenAComponent ( comp, &audioUnit ) ) if ( OpenAComponent ( comp, &audioInputUnit ) )
{ {
throw CGenErr ( tr ( "CoreAudio creating component instance failed" ) ); throw CGenErr ( tr ( "CoreAudio creating input component instance failed" ) );
} }
// we enable input and disable output if ( OpenAComponent ( comp, &audioOutputUnit ) )
{
throw CGenErr ( tr ( "CoreAudio creating output component instance failed" ) );
}
// we enable input and disable output for input component
UInt32 enableIO = 1; UInt32 enableIO = 1;
err = AudioUnitSetProperty ( audioUnit, err = AudioUnitSetProperty ( audioInputUnit,
kAudioOutputUnitProperty_EnableIO, kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input, kAudioUnitScope_Input,
1, // input element 1, // input element
@ -86,28 +91,13 @@ void CSound::OpenCoreAudio()
sizeof ( enableIO ) ); sizeof ( enableIO ) );
enableIO = 0; enableIO = 0;
err = AudioUnitSetProperty ( audioUnit, err = AudioUnitSetProperty ( audioInputUnit,
kAudioOutputUnitProperty_EnableIO, kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output, kAudioUnitScope_Output,
0, // output element 0, // output element
&enableIO, &enableIO,
sizeof ( enableIO ) ); sizeof ( enableIO ) );
// set up a callback function for new input data
AURenderCallbackStruct input;
input.inputProc = process;
input.inputProcRefCon = this;
if ( AudioUnitSetProperty ( audioUnit,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&input,
sizeof ( input ) ) )
{
throw CGenErr ( tr ( "CoreAudio audio unit set property failed" ) );
}
// set input device // set input device
size = sizeof ( AudioDeviceID ); size = sizeof ( AudioDeviceID );
AudioDeviceID inputDevice; AudioDeviceID inputDevice;
@ -115,19 +105,69 @@ void CSound::OpenCoreAudio()
&size, &size,
&inputDevice ) ) &inputDevice ) )
{ {
throw CGenErr ( tr ( "CoreAudio AudioHardwareGetProperty call failed" ) ); throw CGenErr ( tr ( "CoreAudio input AudioHardwareGetProperty call failed" ) );
} }
if ( AudioUnitSetProperty ( audioUnit, if ( AudioUnitSetProperty ( audioInputUnit,
kAudioOutputUnitProperty_CurrentDevice, kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global, kAudioUnitScope_Global,
0, 1,
&inputDevice, &inputDevice,
sizeof ( inputDevice ) ) ) sizeof ( inputDevice ) ) )
{ {
throw CGenErr ( tr ( "CoreAudio input AudioUnitSetProperty call failed" ) ); throw CGenErr ( tr ( "CoreAudio input AudioUnitSetProperty call failed" ) );
} }
// set up a callback function for new input data
AURenderCallbackStruct input;
input.inputProc = processInput;
input.inputProcRefCon = this;
if ( AudioUnitSetProperty ( audioInputUnit,
kAudioOutputUnitProperty_SetInputCallback,//kAudioUnitProperty_SetRenderCallback,//
kAudioUnitScope_Global,
0,
&input,
sizeof ( input ) ) )
{
throw CGenErr ( tr ( "CoreAudio audio unit set property failed" ) );
}
// set output device
size = sizeof ( AudioDeviceID );
AudioDeviceID outputDevice;
if ( AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultOutputDevice,
&size,
&outputDevice ) )
{
throw CGenErr ( tr ( "CoreAudio output AudioHardwareGetProperty call failed" ) );
}
if ( AudioUnitSetProperty ( audioOutputUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global,
0,
&outputDevice,
sizeof ( outputDevice ) ) )
{
throw CGenErr ( tr ( "CoreAudio output AudioUnitSetProperty call failed" ) );
}
// set up a callback function for new output data
AURenderCallbackStruct output;
output.inputProc = processOutput;
output.inputProcRefCon = this;
if ( AudioUnitSetProperty ( audioOutputUnit,
kAudioUnitProperty_SetRenderCallback,//kAudioOutputUnitProperty_SetInputCallback,//
kAudioUnitScope_Global,
0,
&output,
sizeof ( output ) ) )
{
throw CGenErr ( tr ( "CoreAudio audio unit set property failed" ) );
}
// set up stream format // set up stream format
AudioStreamBasicDescription streamFormat; AudioStreamBasicDescription streamFormat;
streamFormat.mSampleRate = SYSTEM_SAMPLE_RATE; streamFormat.mSampleRate = SYSTEM_SAMPLE_RATE;
@ -140,7 +180,7 @@ void CSound::OpenCoreAudio()
streamFormat.mBitsPerChannel = 16; streamFormat.mBitsPerChannel = 16;
// our output // our output
if ( AudioUnitSetProperty ( audioUnit, if ( AudioUnitSetProperty ( audioOutputUnit,
kAudioUnitProperty_StreamFormat, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kAudioUnitScope_Input,
0, 0,
@ -151,7 +191,7 @@ void CSound::OpenCoreAudio()
} }
// our input // our input
if ( AudioUnitSetProperty ( audioUnit, if ( AudioUnitSetProperty ( audioInputUnit,
kAudioUnitProperty_StreamFormat, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, kAudioUnitScope_Output,
1, 1,
@ -167,7 +207,8 @@ void CSound::OpenCoreAudio()
// TEST // TEST
StoreInOutStreamProps ( audioUnit ); StoreInOutStreamProps ( audioInputUnit );
StoreInOutStreamProps ( audioOutputUnit );
} }
@ -175,17 +216,17 @@ StoreInOutStreamProps ( audioUnit );
void CSound::CloseCoreAudio() void CSound::CloseCoreAudio()
{ {
// clean up "gOutputUnit" // clean up "gOutputUnit"
AudioUnitUninitialize ( audioUnit ); AudioUnitUninitialize ( audioInputUnit );
CloseComponent ( audioUnit ); AudioUnitUninitialize ( audioOutputUnit );
CloseComponent ( audioInputUnit );
CloseComponent ( audioOutputUnit );
} }
void CSound::Start() void CSound::Start()
{ {
// start the rendering // start the rendering
if ( AudioOutputUnitStart ( audioUnit ) ) AudioOutputUnitStart ( audioInputUnit );
{ AudioOutputUnitStart ( audioOutputUnit );
throw CGenErr ( tr ( "CoreAudio starting failed" ) );
}
// call base class // call base class
CSoundBase::Start(); CSoundBase::Start();
@ -194,10 +235,8 @@ void CSound::Start()
void CSound::Stop() void CSound::Stop()
{ {
// stop the audio stream // stop the audio stream
if ( AudioOutputUnitStop ( audioUnit ) ) AudioOutputUnitStop ( audioInputUnit );
{ AudioOutputUnitStop ( audioOutputUnit );
throw CGenErr ( tr ( "CoreAudio stopping failed" ) );
}
// call base class // call base class
CSoundBase::Stop(); CSoundBase::Stop();
@ -211,7 +250,14 @@ int CSound::Init ( const int iNewPrefMonoBufferSize )
// get the audio unit buffer size // get the audio unit buffer size
UInt32 bufferSizeFrames; UInt32 bufferSizeFrames;
UInt32 propertySize = sizeof(UInt32); UInt32 propertySize = sizeof(UInt32);
AudioUnitGetProperty ( audioUnit, kAudioDevicePropertyBufferFrameSize,
// TEST
AudioUnitGetProperty ( audioOutputUnit, kAudioDevicePropertyBufferFrameSize,
kAudioUnitScope_Global, 1, &bufferSizeFrames, &propertySize );
printf("out buf size: %d\n",bufferSizeFrames);
AudioUnitGetProperty ( audioInputUnit, kAudioDevicePropertyBufferFrameSize,
kAudioUnitScope_Global, 1, &bufferSizeFrames, &propertySize ); kAudioUnitScope_Global, 1, &bufferSizeFrames, &propertySize );
// store buffer size // store buffer size
@ -236,15 +282,21 @@ printf ( "Buffer_Size: %d", (int) bufferSizeFrames );
theBufferList = (AudioBufferList*) malloc ( offsetof ( AudioBufferList, theBufferList = (AudioBufferList*) malloc ( offsetof ( AudioBufferList,
mBuffers[0] ) + sizeof(AudioBuffer) ); mBuffers[0] ) + sizeof(AudioBuffer) );
//(sizeof(AudioBufferList) + (numChannels-1)) * sizeof(AudioBuffer)
theBufferList->mNumberBuffers = 1; theBufferList->mNumberBuffers = 1;
theBufferList->mBuffers[0].mNumberChannels = 2; // stereo theBufferList->mBuffers[0].mNumberChannels = 2; // stereo
theBufferList->mBuffers[0].mDataByteSize = bufferSizeFrames * 4; // 2 bytes, 2 channels theBufferList->mBuffers[0].mDataByteSize = bufferSizeFrames * 4; // 2 bytes, 2 channels
theBufferList->mBuffers[0].mData = &vecsTmpAudioSndCrdStereo[0]; theBufferList->mBuffers[0].mData = &vecsTmpAudioSndCrdStereo[0];
//theBufferList->mBuffers[0].mData = malloc(bufferSizeBytes);
// initialize unit // initialize unit
if ( AudioUnitInitialize ( audioUnit ) ) if ( AudioUnitInitialize ( audioInputUnit ) )
{
throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) );
}
if ( AudioUnitInitialize ( audioOutputUnit ) )
{ {
throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) ); throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) );
} }
@ -252,7 +304,7 @@ theBufferList = (AudioBufferList*) malloc ( offsetof ( AudioBufferList,
return iCoreAudioBufferSizeMono; return iCoreAudioBufferSizeMono;
} }
OSStatus CSound::process ( void* inRefCon, OSStatus CSound::processInput ( void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags, AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, const AudioTimeStamp* inTimeStamp,
UInt32 inBusNumber, UInt32 inBusNumber,
@ -263,51 +315,39 @@ OSStatus CSound::process ( void* inRefCon,
// get the new audio data // get the new audio data
ComponentResult err = ComponentResult err =
AudioUnitRender ( pSound->audioUnit, AudioUnitRender ( pSound->audioInputUnit,
ioActionFlags, ioActionFlags,
inTimeStamp, inTimeStamp,
inBusNumber, inBusNumber,
inNumberFrames, inNumberFrames,
theBufferList ); theBufferList );
/*
// TEST
//static FILE* pFile = fopen ( "test.dat", "w" );
for ( int test = 0; test < theBufferList->mBuffers[0].mDataByteSize / 4; test++ )
{
fprintf ( pFile, "%e\n", static_cast<float*>(theBufferList->mBuffers[0].mData)[test]);
}
fflush ( pFile );
*/
/*
// TEST output seems to work!!!
for ( UInt32 i = 1; i < theBufferList->mBuffers[0].mDataByteSize / 2; i++)
{
static_cast<short*> ( theBufferList->mBuffers[0].mData)[i] = (short) ( (double) rand() / RAND_MAX * 10000 );
}
ioData = theBufferList;
*/
// TEST
printf ( "buffersize: %d, inBus: %d, ioActionFlags: %d, err: %d\n",
(int) inNumberFrames, (int) inBusNumber, (int) ioActionFlags, (int) err );
// call processing callback function // call processing callback function
pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo ); pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo );
return noErr;
}
OSStatus CSound::processOutput ( void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList* ioData )
{
CSound* pSound = reinterpret_cast<CSound*> ( inRefCon );
// TODO take care of outputting processed data memcpy ( ioData->mBuffers[0].mData,
&pSound->vecsTmpAudioSndCrdStereo[0],
theBufferList->mBuffers[0].mDataByteSize);
return noErr; return noErr;
} }
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

View file

@ -61,11 +61,16 @@ protected:
void CloseCoreAudio(); void CloseCoreAudio();
// callbacks // callbacks
static OSStatus process ( void* inRefCon,AudioUnitRenderActionFlags* ioActionFlags, static OSStatus processInput ( void* inRefCon,AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList* ioData ); AudioBufferList* ioData );
ComponentInstance audioUnit; static OSStatus processOutput ( void* inRefCon,AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList* ioData );
ComponentInstance audioInputUnit;
ComponentInstance audioOutputUnit;
}; };
#endif // !defined(_SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_) #endif // !defined(_SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_)