2013-01-05 27 views
3

我想用下面的代碼從核心音頻(遠程I/O音頻單元)獲得麥克風輸入:「的shm_open失敗」和錯誤3從AudioUnitInitialize與RemoteIO

- (void)audioAU 
{ 
    enum : AudioUnitElement { 
     kOutputElement = 0, 
     kInputElement = 1 
    }; 
    const UInt32 disableFlag = 0; 
    const UInt32 enableFlag = 1; 

    OSStatus err = noErr; 
    NSError *error = nil; 


    // Configure & activate audio session 

    AVAudioSession *session = [AVAudioSession sharedInstance]; 

    if (![session setCategory:AVAudioSessionCategoryRecord error:&error]) NSLog(@"Error configuring session category: %@", error); 
    if (![session setMode:AVAudioSessionModeMeasurement error:&error]) NSLog(@"Error configuring session mode: %@", error); 
    if (![session setActive:YES error:&error]) NSLog(@"Error activating audio session: %@", error); 

    NSLog(@"Session activated. sample rate %f", session.sampleRate); 
    NSLog(@"Number of channels %d", session.inputNumberOfChannels); 


    // Set up Remote I/O audio unit for audio capture 

    AudioComponent component = AudioComponentFindNext(NULL, &(const AudioComponentDescription){ 
     .componentType = kAudioUnitType_Output, 
     .componentSubType = kAudioUnitSubType_RemoteIO, 
     .componentManufacturer = kAudioUnitManufacturer_Apple, 
     .componentFlags = 0, 
     .componentFlagsMask = 0 
    }); 

    AudioComponentInstance unit; 

    // Create audio component 
    err = AudioComponentInstanceNew(component, &unit); 
    if (err != noErr) NSLog(@"Error instantiating audio unit: %ld", err); 

    // Enable input 
    err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputElement, &enableFlag, sizeof(enableFlag)); 
    if (err != noErr) NSLog(@"Error enabling input for audio unit: %ld", err); 

    AudioStreamBasicDescription streamDesc = { 
     .mSampleRate = session.sampleRate, 
     .mFormatID = kAudioFormatLinearPCM, 
     .mFormatFlags = kAudioFormatFlagsAudioUnitCanonical /*matches AudioUnitSampleType*/ | kAudioFormatFlagIsNonInterleaved, 
     .mBytesPerPacket = sizeof(AudioUnitSampleType), 
     .mFramesPerPacket = 1, 
     .mBytesPerFrame = sizeof(AudioUnitSampleType) * session.inputNumberOfChannels, 
     .mChannelsPerFrame = session.inputNumberOfChannels, 
     .mBitsPerChannel = 8 * sizeof(AudioUnitSampleType), 
     .mReserved = 0, 
    }; 
    err = AudioUnitSetProperty(unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputElement, &streamDesc, sizeof(streamDesc)); 
    if (err != noErr) NSLog(@"Error configuring input stream format for audio unit: %ld", err); 

    AURenderCallbackStruct callbacks = { 
     .inputProc = renderCallback, 
     .inputProcRefCon = unit 
    }; 
    err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Input, kOutputElement, &callbacks, sizeof(callbacks)); 
    if (err != noErr) NSLog(@"Error configuring input callbacks for audio unit: %ld", err); 

    err = AudioUnitInitialize(unit); 
    if (err != noErr) NSLog(@"Error initializing audio unit: %ld", err); 

    err = AudioOutputUnitStart(unit); 
    if (err != noErr) NSLog(@"Error starting audio unit: %ld", err); 

// err = AudioComponentInstanceDispose(unit); 
// if (err != noErr) NSLog(@"Error disposing audio unit: %ld", err); 
} 

它的工作原理(或至少不會崩潰)在模擬器,但在iPhone 5上運行時,我得到這樣的輸出:

Session activated. sample rate 44100.000000 
Number of channels 1 
15:48:45.170 <com.apple.main-thread> shm_open failed: "AppleAURemoteIO.o.262da" (23) flags=0x2 errno=2 
15:48:45.172 <com.apple.main-thread> AURemoteIO::ChangeHardwareFormats: error 3 
15:48:45.333 <com.apple.main-thread> shm_open failed: "AppleAURemoteIO.o.262da" (23) flags=0x2 errno=2 
15:48:45.336 <com.apple.main-thread> AURemoteIO::ChangeHardwareFormats: error 3 
15:48:45.497 <com.apple.main-thread> shm_open failed: "AppleAURemoteIO.o.262da" (23) flags=0x2 errno=2 
15:48:45.499 <com.apple.main-thread> AURemoteIO::ChangeHardwareFormats: error 3 
15:48:45.669 <com.apple.main-thread> shm_open failed: "AppleAURemoteIO.o.262da" (23) flags=0x2 errno=2 
15:48:45.671 <com.apple.main-thread> AURemoteIO::ChangeHardwareFormats: error 3 
15:48:45.839 <com.apple.main-thread> shm_open failed: "AppleAURemoteIO.o.262da" (23) flags=0x2 errno=2 
15:48:45.841 <com.apple.main-thread> AURemoteIO::ChangeHardwareFormats: error 3 
Error initializing audio unit: 3 
+0

我有同樣的錯誤,但與PlayAndRecord會話... –

回答

3

事實證明,使用AVAudioSessionCategoryRecord(或相當於kAudioSessionCategory_RecordAudio從C API時),你必須也禁用音頻單元上的輸出:

... 
    // Disable output 
    err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputElement, &disableFlag, sizeof(disableFlag)); 
    if (err != noErr) NSLog(@"Error disabling output for audio unit: %ld", err); 
相關問題