2016-08-08 9 views
17

Я хочу записывать и воспроизводить аудио в Mac. Теперь у меня есть некоторые проблемы с настройками Input/Output/ChannelFormat ... Я показал вам код, который я пытаюсь сделать ниже.Как настроить запись и воспроизведение звука на Mac. Приложение VOIP на Mac

// 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. Но это все еще не работает. Here is my example project

+0

Таким образом, вы показать все ваши удобные методы, но не показывает, как и когда вы их называете. Пожалуйста, покажите код, который использует эти методы. И что именно не работает? Есть ли ошибка? – rocky

+0

@rocky Я отправил свой тестовый проект здесь https://github.com/longpham2310/audio-unit-mac-example. Можете ли вы посмотреть, пожалуйста! –

ответ

2

Я думаю, вы должны проверить kAudioFormatLinearPCM является signed16 или signed32, ль или быть затем

audioFormat.mBitsPerChannel  = 8 * sizeof(UInt32); 
audioFormat.mBytesPerPacket  = sizeof(UInt32); 
audioFormat.mBytesPerFrame  = sizeof(UInt32); 

должен быть изменен соответствующим образом