【发布时间】:2017-12-01 15:21:54
【问题描述】:
我正在尝试让 AudioKit 将麦克风通过管道传输到 Google 的 Speech-to-Text API,如 here 所示,但我不完全确定如何去做。
要为 Speech-to-Text 引擎准备音频,您需要设置编码并将其作为块传递。在 Google 使用的示例中,他们使用 Apple 的 AVFoundation,但我想使用 AudioKit,以便我可以进行一些预处理,例如切割低振幅等。
我相信正确的做法是使用Tap:
首先,我应该通过以下方式匹配格式:
var asbd = AudioStreamBasicDescription()
asbd.mSampleRate = 16000.0
asbd.mFormatID = kAudioFormatLinearPCM
asbd.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked
asbd.mBytesPerPacket = 2
asbd.mFramesPerPacket = 1
asbd.mBytesPerFrame = 2
asbd.mChannelsPerFrame = 1
asbd.mBitsPerChannel = 16
AudioKit.format = AVAudioFormat(streamDescription: &asbd)!
然后创建一个水龙头,例如:
open class TestTap {
internal let bufferSize: UInt32 = 1_024
@objc public init(_ input: AKNode?) {
input?.avAudioNode.installTap(onBus: 0, bufferSize: bufferSize, format: AudioKit.format) { buffer, _ in
// do work here
}
}
}
但我无法确定处理这些数据的正确方法,这些数据通过streamAudioData 和AudioKit 方法实时发送到 Google Speech-to-Text API,但也许我要去这是错误的方式吗?
更新:
我已经创建了一个Tap:
open class TestTap {
internal var audioData = NSMutableData()
internal let bufferSize: UInt32 = 1_024
func toData(buffer: AVAudioPCMBuffer) -> NSData {
let channelCount = 2 // given PCMBuffer channel count is
let channels = UnsafeBufferPointer(start: buffer.floatChannelData, count: channelCount)
return NSData(bytes: channels[0], length:Int(buffer.frameCapacity * buffer.format.streamDescription.pointee.mBytesPerFrame))
}
@objc public init(_ input: AKNode?) {
input?.avAudioNode.installTap(onBus: 0, bufferSize: bufferSize, format: AudioKit.format) { buffer, _ in
self.audioData.append(self.toData(buffer: buffer) as Data)
// We recommend sending samples in 100ms chunks (from Google)
let chunkSize: Int /* bytes/chunk */ = Int(0.1 /* seconds/chunk */
* AudioKit.format.sampleRate /* samples/second */
* 2 /* bytes/sample */ )
if self.audioData.length > chunkSize {
SpeechRecognitionService
.sharedInstance
.streamAudioData(self.audioData,
completion: { response, error in
if let error = error {
print("ERROR: \(error.localizedDescription)")
SpeechRecognitionService.sharedInstance.stopStreaming()
} else if let response = response {
print(response)
}
})
self.audioData = NSMutableData()
}
}
}
}
在 viewDidLoad: 中,我正在设置 AudioKit:
AKSettings.sampleRate = 16_000
AKSettings.bufferLength = .shortest
但是,Google 抱怨:
ERROR: Audio data is being streamed too fast. Please stream audio data approximately at real time.
我尝试更改多个参数,例如块大小,但无济于事。
【问题讨论】:
标签: ios google-cloud-platform google-speech-api audiokit