Swift 3 AVAudioEngine set microphone input format

若如初见. 提交于 2019-12-07 20:09:32

问题


I want to process the bytes read from the microphone using Swift 3 on my iOS. I currently use AVAudioEngine.

print(inputNode.inputFormat(forBus: bus).settings)
print(inputNode.inputFormat(forBus: bus).formatDescription)

This gives me the following output:

["AVNumberOfChannelsKey": 1, "AVLinearPCMBitDepthKey": 32, "AVSampleRateKey": 16000, "AVLinearPCMIsNonInterleaved": 1, "AVLinearPCMIsBigEndianKey": 0, "AVFormatIDKey": 1819304813, "AVLinearPCMIsFloatKey": 1]
<CMAudioFormatDescription 0x14d5bbb0 [0x3a5fb7d8]> {
    mediaType:'soun' 
    mediaSubType:'lpcm' 
    mediaSpecific: {
        ASBD: {
            mSampleRate: 16000.000000 
            mFormatID: 'lpcm' 
            mFormatFlags: 0x29 
            mBytesPerPacket: 4 
            mFramesPerPacket: 1 
            mBytesPerFrame: 4 
            mChannelsPerFrame: 1 
            mBitsPerChannel: 32     } 
        cookie: {(null)} 
        ACL: {(null)}
        FormatList Array: {(null)} 
    } 
    extensions: {(null)}
}

The problem is that the server I want to send the data to does not expect 32 bit floats but 16 bit unsigned ints. I think I have to change the mFormatFlags. Does anybody know how I can do this and what value would be the right one?

The resulting byte stream should be equivalent to the one I get on android using

AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLES_PER_SECOND,
            AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
            recordSegmentSizeBytes);

I tried this:

let cfmt = AVAudioCommonFormat.pcmFormatInt16
        inputNode.inputFormat(forBus: bus) = AVAudioFormat(commonFormat: cfmt, sampleRate: 16000.0, channels: 1, interleaved: false)

but got this error

Cannot assign to value: function call returns immutable value

Any ideas?


回答1:


Oh my god, I think I got it. I was too blind to see that you can specify the format of the installTap callback. This seems to work

let audioEngine  = AVAudioEngine()

func startRecording() {
    let inputNode = audioEngine.inputNode!
    let bus = 0

    let format = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 16000.0, channels: 1, interleaved: false)

    inputNode.installTap(onBus: bus, bufferSize: 2048, format: format) { // inputNode.inputFormat(forBus: bus)
        (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in

        let values = UnsafeBufferPointer(start: buffer.int16ChannelData![0], count: Int(buffer.frameLength))
        let arr = Array(values)
        print(arr)
    }


    audioEngine.prepare()
    do {
        try audioEngine.start()
    } catch {
        print("Error info: \(error)")
    }
}


来源:https://stackoverflow.com/questions/44184169/swift-3-avaudioengine-set-microphone-input-format

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!