2016-08-08 31 views
17

Chcę nagrywać i odtwarzać dźwięk na komputerze Mac. Teraz mam pewne problemy z ustawieniami Input/Output/ChannelFormat ... Pokazałem ci kod, który próbuję poniżej.Jak skonfigurować nagrywanie i odtwarzanie dźwięku na komputerze Mac. Aplikacja VOIP na Macu

// 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. Ale nadal nie działa. Here is my example project

+0

więc pokazać wszystkich swoich metod wygody, ale nie pokazują, jak i kiedy do nich dzwonisz. Pokaż kod korzystający z tych metod. Co dokładnie nie działa? Czy wystąpił błąd? – rocky

+0

@rocky Wysłałem swój projekt testowy tutaj https://github.com/longpham2310/audio-unit-mac-example. Możesz go zobaczyć! –

Odpowiedz

2

myślę, że należy sprawdzić kAudioFormatLinearPCM jest signed16 lub signed32, le lub być następnie

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

powinna zostać odpowiednio zmieniona