我是Audiokit的新手,我试图在麦克风输入的音频上做一些实时的数字信号处理。
我知道我想要的数据在AKAudioFile的FloatChannelData中,但是如果我想实时获得这些数据呢?我目前正在使用AKMicrophone,AKFrequencyTracker,AKNodeOutputPlot,AKBooster和我正在绘制跟踪器的振幅数据。然而,这些数据与音频信号不一样(如您所知,这是RMS)。有什么方法可以从麦克风获取信号的浮动数据吗?甚至是来自AKNodeOutputPlot?我只需要阅读。
AKSettings.audioInputEnabled = true
mic = AKMicrophone()
plot = AKNodeOutputPlot(mic, frame: audioInputPlot.bounds)
tracker = AKFrequencyTracker.init(mic)
silence = AKBooster(tracker,gain:0)
AudioKit.output = silence
AudioKit.start()推荐这里的创建者:
AKNodeOutputPlot工作,它只有一个短文件。你基本上只是点击节点和抓取数据。
如果有绘图(AKNodeOutputPlot)、麦克风(AKMicrophone)的实例并希望将这些值输出到标签中,那么在我的AKNodeOutputPlot中如何工作呢?
发布于 2018-06-12 19:13:29
使用要从哪个节点获取数据的点击。我在上面的引号中使用了AKNodeOutputPlot,因为它非常简单,只是使用这些数据作为绘图的输入,但是您可以获取数据并对它做任何事情。在此代码中(来自AKNodeOutputPlot):
internal func setupNode(_ input: AKNode?) {
if !isConnected {
input?.avAudioNode.installTap(
onBus: 0,
bufferSize: bufferSize,
format: nil) { [weak self] (buffer, _) in
guard let strongSelf = self else {
AKLog("Unable to create strong reference to self")
return
}
buffer.frameLength = strongSelf.bufferSize
let offset = Int(buffer.frameCapacity - buffer.frameLength)
if let tail = buffer.floatChannelData?[0] {
strongSelf.updateBuffer(&tail[offset], withBufferSize: strongSelf.bufferSize)
}
}
}
isConnected = true
}您可以实时获取缓冲区数据。在这里,我们只是把它发送到"updateBuffer“,在那里它会被绘制,但不是策划,你会做其他的事情。
发布于 2019-05-07 22:58:40
要完成Aurelius Prochazka的回答:
要记录流经节点的音频,您需要附加一个点击。tap只是一个闭包,每次可用缓冲区时都会调用它。
下面是可以在您自己的类中重用的示例代码:
var mic = AKMicrophone()
func initMicrophone() {
// Facultative, allow to set the sampling rate of the microphone
AKSettings.sampleRate = 44100
// Link the microphone note to the output of AudioKit with a volume of 0.
AudioKit.output = AKBooster(mic, gain:0)
// Start AudioKit engine
try! AudioKit.start()
// Add a tap to the microphone
mic?.avAudioNode.installTap(
onBus: audioBus, bufferSize: 4096, format: nil // I choose a buffer size of 4096
) { [weak self] (buffer, _) in //self is now a weak reference, to prevent retain cycles
// We try to create a strong reference to self, and name it strongSelf
guard let strongSelf = self else {
print("Recorder: Unable to create strong reference to self #1")
return
}
// We look at the buffer if it contains data
buffer.frameLength = strongSelf.bufferSize
let offset = Int(buffer.frameCapacity - buffer.frameLength)
if let tail = buffer.floatChannelData?[0] {
// We convert the content of the buffer to a swift array
let samples = Array(UnsafeBufferPointer(start: &tail[offset], count: 4096))
strongSelf.myFunctionHandlingData(samples)
}
}
func myFunctionhandlingData(data: [Float]) {
// ...
}如果需要在不同线程之间对此数据进行交互,请小心使用DispatchQueue或其他同步机制。在我的例子中,我确实使用:
DispatchQueue.main.async { [weak self] in
guard let strongSelf = self else {
print("Recorder: Unable to create strong reference to self #2")
return
}
strongSelf.myFunctionHandlingData(samples)
}所以我的函数在主线程中运行。
https://stackoverflow.com/questions/50805268
复制相似问题