在Swift 3中使用音频队列获取麦克风输入 [英] Get microphone input using Audio Queue in Swift 3
问题描述
我正在开发一个通过内置麦克风录制语音并将其实时发送到服务器的应用程序.因此,我需要在录音时从麦克风获取字节流.
I am developing an app that records voice via built-in microphone and sends it to a server live. So I need to get the byte stream from the microphone while recording.
在谷歌搜索和堆栈溢出一段时间之后,我想我已经弄清楚了它应该如何工作,但事实并非如此.我认为使用音频队列可能是可行的方法.
After googling and stack-overflowing for quite a while, I think I figured out how it should work, but it does not. I think using Audio Queues might be the way to go.
这是我到目前为止尝试过的:
Here is what I tried so far:
func test() {
func callback(_ a :UnsafeMutableRawPointer?, _ b : AudioQueueRef, _ c :AudioQueueBufferRef, _ d :UnsafePointer<AudioTimeStamp>, _ e :UInt32, _ f :UnsafePointer<AudioStreamPacketDescription>?) {
print("test")
}
var inputQueue: AudioQueueRef? = nil
var aqData = AQRecorderState(
mDataFormat: AudioStreamBasicDescription(
mSampleRate: 16000,
mFormatID: kAudioFormatLinearPCM,
mFormatFlags: 0,
mBytesPerPacket: 2,
mFramesPerPacket: 1, // Must be set to 1 for uncomressed formats
mBytesPerFrame: 2,
mChannelsPerFrame: 1, // Mono recording
mBitsPerChannel: 2 * 8, // 2 Bytes
mReserved: 0), // Must be set to 0 according to https://developer.apple.com/reference/coreaudio/audiostreambasicdescription
mQueue: inputQueue!,
mBuffers: [AudioQueueBufferRef](),
bufferByteSize: 32,
mCurrentPacket: 0,
mIsRunning: true)
var error = AudioQueueNewInput(&aqData.mDataFormat,
callback,
nil,
nil,
nil,
0,
&inputQueue)
AudioQueueStart(inputQueue!, nil)
}
它可以编译并启动应用程序,但是一旦我调用test(),我就会收到一个异常:
It compiles and the app starts, but as soon as I call test() I get an exception:
致命错误:解开可选值时意外发现nil
fatal error: unexpectedly found nil while unwrapping an Optional value
该异常是由
mQueue: inputQueue!
我理解为什么会发生这种情况(inputQueue没有值),但是我不知道如何正确初始化inputQueue.问题在于,对于Swift用户而言,音频队列的文档非常少,而且我在互联网上找不到任何有效的示例.
I understand why this happens (inputQueue has no value) but I don't know how to initialise inputQueue correctly. The problem is that Audio Queues are very poorly documented for Swift users and I didn't find any working example on the internet.
有人可以告诉我我做错了什么吗?
Can anybody tell me what I am doing wrong?
推荐答案
在使用之前,使用AudioQueueNewInput(...)
(或输出)初始化音频队列:
Use AudioQueueNewInput(...)
(or output) to initialize your audio queue before you are using it:
let sampleRate = 16000
let numChannels = 2
var inFormat = AudioStreamBasicDescription(
mSampleRate: Double(sampleRate),
mFormatID: kAudioFormatLinearPCM,
mFormatFlags: kAudioFormatFlagsNativeFloatPacked,
mBytesPerPacket: UInt32(numChannels * MemoryLayout<UInt32>.size),
mFramesPerPacket: 1,
mBytesPerFrame: UInt32(numChannels * MemoryLayout<UInt32>.size),
mChannelsPerFrame: UInt32(numChannels),
mBitsPerChannel: UInt32(8 * (MemoryLayout<UInt32>.size)),
mReserved: UInt32(0)
var inQueue: AudioQueueRef? = nil
AudioQueueNewInput(&inFormat, callback, nil, nil, nil, 0, &inQueue)
var aqData = AQRecorderState(
mDataFormat: inFormat,
mQueue: inQueue!, // inQueue is initialized now and can be unwrapped
mBuffers: [AudioQueueBufferRef](),
bufferByteSize: 32,
mCurrentPacket: 0,
mIsRunning: true)
在 Apple文档
这篇关于在Swift 3中使用音频队列获取麦克风输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!