From 5b0618e4c6c76161876ac15e09e2fa4f810c1270 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Tue, 9 Mar 2010 19:19:10 +0000 Subject: [PATCH] added lots of test and debug code, audio interface not working yet --- mac/sound.cpp | 377 ++++++++++++++++++++++++++++++++++++++++++-------- mac/sound.h | 2 +- 2 files changed, 321 insertions(+), 58 deletions(-) diff --git a/mac/sound.cpp b/mac/sound.cpp index a67b2612..e6f70b73 100755 --- a/mac/sound.cpp +++ b/mac/sound.cpp @@ -25,89 +25,122 @@ #include "sound.h" + + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// TODO remove the following code as soon as the Coreaudio is working!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// TEST Debug functions +#include +void StoreInOutStreamProps ( ComponentInstance in ); +void StoreAudioStreamBasicDescription ( AudioStreamBasicDescription in, std::string text ); +static FILE* pFile = fopen ( "test.dat", "w" ); + + + + + +// TEST +// allocated to hold buffer data +AudioBufferList* theBufferList; + + + + /* Implementation *************************************************************/ void CSound::OpenCoreAudio() { - // open the default output unit - AudioComponentDescription desc; + UInt32 size; + ComponentResult err; + + // open the default unit + ComponentDescription desc; desc.componentType = kAudioUnitType_Output; - desc.componentSubType = kAudioUnitSubType_DefaultOutput; + desc.componentSubType = kAudioUnitSubType_HALOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; - desc.componentManufacturer = 0; - AudioComponent comp = AudioComponentFindNext ( NULL, &desc ); + Component comp = FindNextComponent ( NULL, &desc ); if ( comp == NULL ) { throw CGenErr ( tr ( "No CoreAudio next component found" ) ); } - - if ( AudioComponentInstanceNew ( comp, &gOutputUnit ) ) + + if ( OpenAComponent ( comp, &audioUnit ) ) { throw CGenErr ( tr ( "CoreAudio creating component instance failed" ) ); } + // TODO + UInt32 enableIO = 0; + err = AudioUnitSetProperty ( audioUnit, + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Input, + 1, // input element + &enableIO, + sizeof ( enableIO ) ); + + enableIO = 1; + err = AudioUnitSetProperty ( audioUnit, + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Output, + 0, // output element + &enableIO, + sizeof ( enableIO ) ); + // set up a callback function to generate output to the output unit AURenderCallbackStruct input; input.inputProc = process; input.inputProcRefCon = this; - if ( AudioUnitSetProperty ( gOutputUnit, + if ( AudioUnitSetProperty ( audioUnit, kAudioUnitProperty_SetRenderCallback, - kAudioUnitScope_Input, + kAudioUnitScope_Global, 0, &input, - sizeof(input) ) ) + sizeof ( input ) ) ) { throw CGenErr ( tr ( "CoreAudio audio unit set property failed" ) ); } -} -void CSound::CloseCoreAudio() -{ - // clean up "gOutputUnit" - AudioUnitUninitialize ( gOutputUnit ); - CloseComponent ( gOutputUnit ); -} + // set input device + size = sizeof ( AudioDeviceID ); + AudioDeviceID inputDevice; + if ( AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultOutputDevice, + &size, + &inputDevice ) ) + { + throw CGenErr ( tr ( "CoreAudio AudioHardwareGetProperty call failed" ) ); + } -void CSound::Start() -{ - // start the rendering - if ( AudioOutputUnitStart ( gOutputUnit ) ) - { - throw CGenErr ( tr ( "CoreAudio starting failed" ) ); - } -} - -void CSound::Stop() -{ - // stop the audio stream - if ( AudioOutputUnitStop ( gOutputUnit ) ) - { - throw CGenErr ( tr ( "CoreAudio stopping failed" ) ); - } -} - -int CSound::Init ( const int iNewPrefMonoBufferSize ) -{ - // store buffer size - iCoreAudioBufferSizeMono = iNewPrefMonoBufferSize; - - // first uninitialize unit - AudioUnitUninitialize ( gOutputUnit ); + if ( AudioUnitSetProperty ( audioUnit, + kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Global, + 0, + &inputDevice, + sizeof ( inputDevice ) ) ) + { + throw CGenErr ( tr ( "CoreAudio AudioUnitSetProperty call failed" ) ); + } // set up stream format AudioStreamBasicDescription streamFormat; streamFormat.mSampleRate = SYSTEM_SAMPLE_RATE; streamFormat.mFormatID = kAudioFormatLinearPCM; streamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger; - streamFormat.mFramesPerPacket = iCoreAudioBufferSizeMono; - streamFormat.mBytesPerFrame = streamFormat.mChannelsPerFrame * 2; // short type - streamFormat.mBytesPerPacket = streamFormat.mBytesPerFrame * streamFormat.mFramesPerPacket; + streamFormat.mFramesPerPacket = 1; + streamFormat.mBytesPerFrame = 4; + streamFormat.mBytesPerPacket = 4; streamFormat.mChannelsPerFrame = 2; // stereo streamFormat.mBitsPerChannel = 16; - - if ( AudioUnitSetProperty ( gOutputUnit, + + // our output + if ( AudioUnitSetProperty ( audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, @@ -117,8 +150,101 @@ int CSound::Init ( const int iNewPrefMonoBufferSize ) throw CGenErr ( tr ( "CoreAudio stream format set property failed" ) ); } - // (re-)initialize unit - if ( AudioUnitInitialize ( gOutputUnit ) ) + // our input + if ( AudioUnitSetProperty ( audioUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 1, + &streamFormat, + sizeof(streamFormat) ) ) + { + throw CGenErr ( tr ( "CoreAudio stream format set property failed" ) ); + } + + +// TEST +StoreInOutStreamProps ( audioUnit ); + + +} + +void CSound::CloseCoreAudio() +{ + // clean up "gOutputUnit" + AudioUnitUninitialize ( audioUnit ); + CloseComponent ( audioUnit ); +} + +void CSound::Start() +{ + // start the rendering + if ( AudioOutputUnitStart ( audioUnit ) ) + { + throw CGenErr ( tr ( "CoreAudio starting failed" ) ); + } + + // call base class + CSoundBase::Start(); + +// TEST +printf ( "start\n" ); +} + +void CSound::Stop() +{ + // stop the audio stream + if ( AudioOutputUnitStop ( audioUnit ) ) + { + throw CGenErr ( tr ( "CoreAudio stopping failed" ) ); + } + + // call base class + CSoundBase::Stop(); + +// TEST +printf ( "stop\n" ); +} + +int CSound::Init ( const int iNewPrefMonoBufferSize ) +{ + // store buffer size + iCoreAudioBufferSizeMono = iNewPrefMonoBufferSize; + + + +// TEST +//Get the size of the IO buffer(s) +UInt32 bufferSizeFrames, bufferSizeBytes; + +UInt32 propertySize = sizeof(bufferSizeFrames); +AudioUnitGetProperty(audioUnit, kAudioDevicePropertyBufferFrameSize, + kAudioUnitScope_Global, 1, &bufferSizeFrames, &propertySize); + +bufferSizeBytes = bufferSizeFrames * sizeof(Float32); + +printf("Buffer_Size: %d", (int) bufferSizeFrames); + + +//malloc buffer lists +theBufferList = (AudioBufferList*) malloc( + offsetof(AudioBufferList, mBuffers[0]) + (sizeof(AudioBuffer) * 2)); + +theBufferList->mNumberBuffers = 2; + +//pre-malloc buffers for AudioBufferLists +for ( UInt32 i = 0; i < theBufferList->mNumberBuffers; i++ ) +{ + theBufferList->mBuffers[i].mNumberChannels = 2; + theBufferList->mBuffers[i].mDataByteSize = bufferSizeBytes; + theBufferList->mBuffers[i].mData = malloc(bufferSizeBytes); +} + + + + + + // (re-)initialize unit + if ( AudioUnitInitialize ( audioUnit ) ) { throw CGenErr ( tr ( "Initialization of CoreAudio failed" ) ); } @@ -144,15 +270,71 @@ OSStatus CSound::process ( void* inRefCon, { CSound* pSound = reinterpret_cast ( inRefCon ); +// TEST +for ( UInt32 channel = 0; channel < theBufferList->mNumberBuffers; channel++) +{ + memset ( theBufferList->mBuffers[channel].mData, 0, + theBufferList->mBuffers[channel].mDataByteSize ); +} + + + // get the new audio data + AudioUnitRender ( pSound->audioUnit, + ioActionFlags, + inTimeStamp, + inBusNumber, + inNumberFrames, + theBufferList); /* - for ( UInt32 channel = 1; channel < ioData->mNumberBuffers; channel++) - { - memcpy ( ioData->mBuffers[channel].mData, - ioData->mBuffers[0].mData, - ioData->mBuffers[0].mDataByteSize ); - } +// 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(theBufferList->mBuffers[0].mData)[test]); +} +fflush ( pFile ); +*/ + +/* +// TEST output seems to work!!! + for ( UInt32 i = 1; i < ioData->mBuffers[0].mDataByteSize / 2; i++) + { + static_cast ( ioData->mBuffers[0].mData)[i] = (short) ( (double) rand() / RAND_MAX * 10000 ); + } +*/ + +/* +// TEST +static FILE* pFile = fopen ( "test.dat", "w" ); +fprintf ( pFile, "%d %d %d\n", ioActionFlags, inNumberFrames, err); +fflush ( pFile ); +*/ + +/* +// TEST +static FILE* pFile = fopen ( "test.dat", "w" ); +for ( int test = 0; test < theBufferList->mBuffers[0].mDataByteSize / 4; test++ ) +{ + fprintf ( pFile, "%e %d %d\n", static_cast(theBufferList->mBuffers[0].mData)[test], + static_cast(theBufferList->mBuffers[0].mData)[test], + static_cast ( ioData->mBuffers[0].mData)[test]); +} +fflush ( pFile ); +*/ + +// TEST + printf ( "processing Core Audio %d, inBusNumber: %d\n", (int) inNumberFrames, (int) inBusNumber ); + + +/* + for ( UInt32 channel = 1; channel < ioData->mNumberBuffers; channel++) + { + memcpy ( ioData->mBuffers[channel].mData, + ioData->mBuffers[0].mData, + ioData->mBuffers[0].mDataByteSize ); + } */ /* @@ -172,6 +354,16 @@ OSStatus CSound::process ( void* inRefCon, pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = (short) ( in_right[i] * _MAXSHORT ); } */ + +/* +// TEST +for ( int i = 0; i < inNumberFrames; i++ ) +{ + pSound->vecsTmpAudioSndCrdStereo[2 * i] = static_cast(ioData->mBuffers[0].mData)[i]; + pSound->vecsTmpAudioSndCrdStereo[2 * i + 1] = static_cast(ioData->mBuffers[0].mData)[i]; +} +*/ + // call processing callback function pSound->ProcessCallback ( pSound->vecsTmpAudioSndCrdStereo ); @@ -202,8 +394,79 @@ OSStatus CSound::process ( void* inRefCon, ioData->mBuffers[0].mNumberChannels = 1; */ -// TEST -printf ( "processing Core Audio\n" ); return noErr; } + + + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// TODO remove the following code as soon as the Coreaudio is working!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// TEST Debug functions +void StoreAudioStreamBasicDescription ( AudioStreamBasicDescription in, + std::string text ) +{ + fprintf ( pFile, "*** AudioStreamBasicDescription: %s***\n", text.c_str() ); + fprintf ( pFile, "mSampleRate: %e\n", in.mSampleRate ); + fprintf ( pFile, "mFormatID: %d\n", (int) in.mFormatID ); + fprintf ( pFile, "mFormatFlags: %d\n", (int) in.mFormatFlags ); + fprintf ( pFile, "mFramesPerPacket: %d\n", (int) in.mFramesPerPacket ); + fprintf ( pFile, "mBytesPerFrame: %d\n", (int) in.mBytesPerFrame ); + fprintf ( pFile, "mBytesPerPacket: %d\n", (int) in.mBytesPerPacket ); + fprintf ( pFile, "mChannelsPerFrame: %d\n", (int) in.mChannelsPerFrame ); + fprintf ( pFile, "mBitsPerChannel: %d\n", (int) in.mBitsPerChannel ); +// fprintf ( pFile, "mReserved %d\n", in.mReserved ); + fflush ( pFile ); +} + +void StoreInOutStreamProps ( ComponentInstance in ) +{ + // input bus 1 + AudioStreamBasicDescription DeviceFormatin1; + UInt32 size = sizeof ( AudioStreamBasicDescription ); + AudioUnitGetProperty ( in, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 1, + &DeviceFormatin1, + &size ); + StoreAudioStreamBasicDescription ( DeviceFormatin1, "Input Bus 1" ); + + // output bus 1 + AudioStreamBasicDescription DeviceFormatout1; + size = sizeof ( AudioStreamBasicDescription ); + AudioUnitGetProperty ( in, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 1, + &DeviceFormatout1, + &size ); + StoreAudioStreamBasicDescription ( DeviceFormatout1, "Output Bus 1" ); + + // input bus 0 + AudioStreamBasicDescription DeviceFormatin0; + size = sizeof ( AudioStreamBasicDescription ); + AudioUnitGetProperty ( in, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, + &DeviceFormatin0, + &size ); + StoreAudioStreamBasicDescription ( DeviceFormatin0, "Input Bus 0" ); + + // output bus 0 + AudioStreamBasicDescription DeviceFormatout0; + size = sizeof ( AudioStreamBasicDescription ); + AudioUnitGetProperty ( in, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 0, + &DeviceFormatout0, + &size ); + StoreAudioStreamBasicDescription ( DeviceFormatout0, "Output Bus 0" ); +} diff --git a/mac/sound.h b/mac/sound.h index 0f1bf4ee..43336858 100755 --- a/mac/sound.h +++ b/mac/sound.h @@ -65,7 +65,7 @@ protected: const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData ); - AudioUnit gOutputUnit; + ComponentInstance audioUnit; }; #endif // !defined(_SOUND_H__9518A621345F78_363456876UZGSDF82CF549__INCLUDED_)