首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AudioKit -如何从麦克风获得实时floatChannelData?

AudioKit -如何从麦克风获得实时floatChannelData?
EN

Stack Overflow用户
提问于 2018-06-11 20:06:50
回答 2查看 2.1K关注 0票数 3

我是Audiokit的新手,我试图在麦克风输入的音频上做一些实时的数字信号处理。

我知道我想要的数据在AKAudioFile的FloatChannelData中,但是如果我想实时获得这些数据呢?我目前正在使用AKMicrophone,AKFrequencyTracker,AKNodeOutputPlot,AKBooster和我正在绘制跟踪器的振幅数据。然而,这些数据与音频信号不一样(如您所知,这是RMS)。有什么方法可以从麦克风获取信号的浮动数据吗?甚至是来自AKNodeOutputPlot?我只需要阅读。

代码语言:javascript
复制
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中如何工作呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-12 19:13:29

使用要从哪个节点获取数据的点击。我在上面的引号中使用了AKNodeOutputPlot,因为它非常简单,只是使用这些数据作为绘图的输入,但是您可以获取数据并对它做任何事情。在此代码中(来自AKNodeOutputPlot):

代码语言:javascript
复制
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“,在那里它会被绘制,但不是策划,你会做其他的事情。

票数 2
EN

Stack Overflow用户

发布于 2019-05-07 22:58:40

要完成Aurelius Prochazka的回答:

要记录流经节点的音频,您需要附加一个点击。tap只是一个闭包,每次可用缓冲区时都会调用它。

下面是可以在您自己的类中重用的示例代码:

代码语言:javascript
复制
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或其他同步机制。在我的例子中,我确实使用:

代码语言:javascript
复制
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)
}

所以我的函数在主线程中运行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50805268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档