Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to setup for record and playback audio on Mac. VOIP app on Mac

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

like image 984
Long Pham Avatar asked Aug 08 '16 04:08

Long Pham


People also ask

How do I record audio from an app on my Mac?

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.

How do I record my voice and record at the same time Mac?

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.


1 Answers

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

like image 194
Leon Nguyen Avatar answered Sep 23 '22 01:09

Leon Nguyen