2016-05-01 57 views
8

Objective-Cでは、オーディオの録音と再生を同時に行うことはかなり簡単です。そして、インターネット上にサンプルコードのトンがあります。しかし、SwiftのAudio Unit/Core Audioを使って、同時にオーディオを録音して再生したいと思っています。 Swiftを使用してこれに関するヘルプとサンプルコードが少しずつ異なります。そして、私はこれを達成する方法を示すことができる助けを見つけることができませんでした。Swiftを使ってiOSで同時にオーディオを録音して再生する方法は?

私は迷惑メールコードに苦しんでいます。

let preferredIOBufferDuration = 0.005 
let kInputBus = AudioUnitElement(1) 
let kOutputBus = AudioUnitElement(0) 

init() { 
    // This is my Audio Unit settings code. 
    var status: OSStatus 

    do { 
     try AVAudioSession.sharedInstance().setPreferredIOBufferDuration(preferredIOBufferDuration) 
    } catch let error as NSError { 
     print(error) 
    } 


    var desc: AudioComponentDescription = AudioComponentDescription() 
    desc.componentType = kAudioUnitType_Output 
    desc.componentSubType = kAudioUnitSubType_VoiceProcessingIO 
    desc.componentFlags = 0 
    desc.componentFlagsMask = 0 
    desc.componentManufacturer = kAudioUnitManufacturer_Apple 

    let inputComponent: AudioComponent = AudioComponentFindNext(nil, &desc) 

    status = AudioComponentInstanceNew(inputComponent, &audioUnit) 
    checkStatus(status) 

    var flag = UInt32(1) 
    status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, UInt32(sizeof(UInt32))) 
    checkStatus(status) 

    status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, UInt32(sizeof(UInt32))) 
    checkStatus(status) 

    var audioFormat: AudioStreamBasicDescription! = AudioStreamBasicDescription() 
    audioFormat.mSampleRate = 8000 
    audioFormat.mFormatID = kAudioFormatLinearPCM 
    audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked 
    audioFormat.mFramesPerPacket = 1 
    audioFormat.mChannelsPerFrame = 1 
    audioFormat.mBitsPerChannel = 16 
    audioFormat.mBytesPerPacket = 2 
    audioFormat.mBytesPerFrame = 2 

    status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &audioFormat, UInt32(sizeof(UInt32))) 
    checkStatus(status) 


    try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord) 
    status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &audioFormat, UInt32(sizeof(UInt32))) 
    checkStatus(status) 


    // Set input/recording callback 
    var inputCallbackStruct: AURenderCallbackStruct! = AURenderCallbackStruct(inputProc: recordingCallback, inputProcRefCon: UnsafeMutablePointer(unsafeAddressOf(self))) 
    inputCallbackStruct.inputProc = recordingCallback 
    inputCallbackStruct.inputProcRefCon = UnsafeMutablePointer(unsafeAddressOf(self)) 
    status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, kInputBus, &inputCallbackStruct, UInt32(sizeof(UInt32))) 
    checkStatus(status) 


    // Set output/renderar/playback callback 
    var renderCallbackStruct: AURenderCallbackStruct! = AURenderCallbackStruct(inputProc: playbackCallback, inputProcRefCon: UnsafeMutablePointer(unsafeAddressOf(self))) 
    renderCallbackStruct.inputProc = playbackCallback 
    renderCallbackStruct.inputProcRefCon = UnsafeMutablePointer(unsafeAddressOf(self)) 
    status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus, &renderCallbackStruct, UInt32(sizeof(UInt32))) 
    checkStatus(status) 


    flag = 0 
    status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_ShouldAllocateBuffer, kAudioUnitScope_Output, kInputBus, &flag, UInt32(sizeof(UInt32))) 
} 


func recordingCallback(inRefCon: UnsafeMutablePointer<Void>, 
         ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, 
         inTimeStamp: UnsafePointer<AudioTimeStamp>, 
         inBufNumber: UInt32, 
         inNumberFrames: UInt32, 
         ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus { 

    print("recordingCallback got fired >>>") 


    return noErr 
} 



func playbackCallback(inRefCon: UnsafeMutablePointer<Void>, 
         ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, 
         inTimeStamp: UnsafePointer<AudioTimeStamp>, 
         inBufNumber: UInt32, 
         inNumberFrames: UInt32, 
         ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus { 

    print("playbackCallback got fired <<<") 


    return noErr 
} 

このコードでは、recordingCallbackメソッドが呼び出されています。そして、playbackCallbackメソッドはまったく実行されていません。私はここに何か間違っていると確信しています。誰かがこれで私を助けてくださいできますか?私はこの問題に頭を悩ましている。

+0

ここで、audioUnit var? –

答えて

4

InputCallbackRenderCallbackの方法を間違って設定しています。他の設定はOKと思われます。したがって、あなたのinitメソッドはこのようになります。

init() { 

    var status: OSStatus 

    do { 
     try AVAudioSession.sharedInstance().setPreferredIOBufferDuration(preferredIOBufferDuration) 
    } catch let error as NSError { 
     print(error) 
    } 


    var desc: AudioComponentDescription = AudioComponentDescription() 
    desc.componentType = kAudioUnitType_Output 
    desc.componentSubType = kAudioUnitSubType_VoiceProcessingIO 
    desc.componentFlags = 0 
    desc.componentFlagsMask = 0 
    desc.componentManufacturer = kAudioUnitManufacturer_Apple 

    let inputComponent: AudioComponent = AudioComponentFindNext(nil, &desc) 

    status = AudioComponentInstanceNew(inputComponent, &audioUnit) 
    checkStatus(status) 

    var flag = UInt32(1) 
    status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, UInt32(sizeof(UInt32))) 
    checkStatus(status) 

    status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, UInt32(sizeof(UInt32))) 
    checkStatus(status) 

    var audioFormat: AudioStreamBasicDescription! = AudioStreamBasicDescription() 
    audioFormat.mSampleRate = 8000 
    audioFormat.mFormatID = kAudioFormatLinearPCM 
    audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked 
    audioFormat.mFramesPerPacket = 1 
    audioFormat.mChannelsPerFrame = 1 
    audioFormat.mBitsPerChannel = 16 
    audioFormat.mBytesPerPacket = 2 
    audioFormat.mBytesPerFrame = 2 

    status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &audioFormat, UInt32(sizeof(UInt32))) 
    checkStatus(status) 


    try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord) 
    status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &audioFormat, UInt32(sizeof(UInt32))) 
    checkStatus(status) 


    // Set input/recording callback 
    var inputCallbackStruct = AURenderCallbackStruct(inputProc: recordingCallback, inputProcRefCon: UnsafeMutablePointer(unsafeAddressOf(self))) 
    AudioUnitSetProperty(audioUnit, AudioUnitPropertyID(kAudioOutputUnitProperty_SetInputCallback), AudioUnitScope(kAudioUnitScope_Global), 1, &inputCallbackStruct, UInt32(sizeof(AURenderCallbackStruct))) 


    // Set output/renderar/playback callback 
    var renderCallbackStruct = AURenderCallbackStruct(inputProc: playbackCallback, inputProcRefCon: UnsafeMutablePointer(unsafeAddressOf(self))) 
    AudioUnitSetProperty(audioUnit, AudioUnitPropertyID(kAudioUnitProperty_SetRenderCallback), AudioUnitScope(kAudioUnitScope_Global), 0, &renderCallbackStruct, UInt32(sizeof(AURenderCallbackStruct))) 


    flag = 0 
    status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_ShouldAllocateBuffer, kAudioUnitScope_Output, kInputBus, &flag, UInt32(sizeof(UInt32))) 
} 

このコードで試してみてください。

+1

このコードを録音してマイクのように再生する方法は、話している間はスピーカーで再生されます –

+0

どこから録音したいのかを指定できますか?つまり、iPhone対ヘッドセット? – Surz

関連する問題