I want to record and playback audio in Mac. Now, I have some problems about the settings for Input/Output/ChannelFormat … I showed you some code I try below.
// Setup audio device
- (OSStatus) setupAudioDevice { // It's oks
AudioComponentDescription desc;
AudioComponent comp;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_VoiceProcessingIO; // This type support for both iOS and Mac
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
comp = AudioComponentFindNext(NULL, &desc);
if (comp == NULL)
{
return -1;
}
OSStatus err = AudioComponentInstanceNew(comp, &audioUnit);
checkStatus(err);
return err;
}
//Enable IO
//https://developer.apple.com/library/prerelease/content/technotes/tn2091/_index.html
- (OSStatus) setupEnableIO { // It's ok
UInt32 enableIO;
//When using AudioUnitSetProperty the 4th parameter in the method
//refer to an AudioUnitElement. When using an AudioOutputUnit
//the input element will be '1' and the output element will be '0'.
enableIO = 1;
OSStatus err = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
kInputBus, // input element
&enableIO,
sizeof(enableIO));
checkStatus(err);
enableIO = 0;
err = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
kOutputBus, //output element
&enableIO,
sizeof(enableIO));
checkStatus(err);
return err;
}
// Setup Microphone
- (OSStatus) setupMicInput { // It's ok
AudioObjectPropertyAddress addr;
UInt32 size = sizeof(AudioDeviceID);
AudioDeviceID deviceID = 0;
addr.mSelector = kAudioHardwarePropertyDefaultInputDevice;
addr.mScope = kAudioObjectPropertyScopeGlobal;
addr.mElement = kAudioObjectPropertyElementMaster;
OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, 0, NULL, &size, &deviceID);
checkStatus(err);
if (err == noErr) {
err = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceID, size);
}
checkStatus(err);
int m_valueCount = deviceID / sizeof(AudioValueRange) ;
NSLog(@"Available %d Sample Rates\n",m_valueCount);
NSLog(@"DeviceName: %@",[self deviceName:deviceID]);
NSLog(@"BufferSize: %d",[self bufferSize:deviceID]);
return err;
}
// Setup Input format
- (OSStatus)setupInputFormat {
AudioStreamBasicDescription audioFormat;// = [EZAudioUtilities monoFloatFormatWithSampleRate:SampleRate]
audioFormat.mSampleRate = SampleRate;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 8 * sizeof(UInt32);
audioFormat.mBytesPerPacket = sizeof(UInt32);
audioFormat.mBytesPerFrame = sizeof(UInt32);
UInt32 size = sizeof(AudioStreamBasicDescription);
// Apply format
OSStatus err = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&audioFormat,
size);
checkStatus(err);
err = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
1,
&audioFormat,
size);
checkStatus(err);
return err;
}
//Setup Input Callback
- (OSStatus)setupInputCallback {
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = recordingCallback;
callbackStruct.inputProcRefCon = (__bridge void * _Nullable)(self);
UInt32 size = sizeof(AURenderCallbackStruct);
OSStatus err = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&callbackStruct,
size);
checkStatus(err);
return err;
}
//Setup Output Playback
- (OSStatus)setupRenderPlayback {
// Set output callback
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = playbackCallback;
callbackStruct.inputProcRefCon = (__bridge void * _Nullable)(self);
UInt32 size = sizeof(AURenderCallbackStruct);
OSStatus err = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
1,
&callbackStruct,
size);
checkStatus(err);
return err;
}
I try to follow this suggestion. But It’s still doesn’t work. Here is my example project
In the Voice Memos app on your Mac, click the Record button (or use the Touch Bar). To pause, click the Pause button . To continue, click Resume. When you finish, click Done in the lower-right corner.
Open QuickTime Player from your Applications folder, then choose File > New Screen Recording from the menu bar. You will then see either the onscreen controls described above or the Screen Recording window described below. To record your voice or other audio with the screen recording, choose a microphone.
I think you should check kAudioFormatLinearPCM is signed16 or signed32, le or be then
audioFormat.mBitsPerChannel = 8 * sizeof(UInt32);
audioFormat.mBytesPerPacket = sizeof(UInt32);
audioFormat.mBytesPerFrame = sizeof(UInt32);
should be changed accordingly
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With