3

我正在构建一个使用麦克风输入来检测声音和触发事件的应用程序。我的代码基于 AKAmplitudeTap,但是当我运行它时,我发现我只获取了缺少部分的间隔的样本数据。

Tap 代码看起来像这样(去掉了胆量,只是跟踪将处理多少个样本):

open class MyTap {
//   internal let bufferSize: UInt32 = 1_024  // 8-9 kSamples/sec
     internal let bufferSize: UInt32 = 4096   // 39.6 kSamples/sec   
//   internal let bufferSize: UInt32 = 16536  // 43.3 kSamples/sec

public init(_ input: AKNode?) {
    input?.avAudioNode.installTap(onBus: 0, bufferSize: bufferSize, format: nil ) { buffer, _ in

        sampleCount += self.bufferSize

    }
}

我初始化水龙头:

func afterLoad() {
    assert(!loaded)
    AKSettings.audioInputEnabled = true
    do {
        try AKSettings.setSession(category: .playAndRecord, with: .allowBluetoothA2DP)
    } catch {
        print("Could not set session category.")
    }
    mic = AKMicrophone()
    myTap = MyTap(mic)  // seriously, can it be that easy?  

    loaded = true
}

原始的点击代码将样本捕获到缓冲区,但我看到缓冲区大小为 1024 时丢失了大量时间。我怀疑样本缓冲区的处理时间可能过长,所以......

我简化了代码以简单地跟踪有多少样本被传递到水龙头。在代码的另一部分,我简单地打印出 sampleCount/elapsedTime,并且如“bufferSize”之后的注释中所述,我每秒得到不同数量的样本。

使用 16K 缓冲区的采样率收敛到 43.1 KSamples/sec,并且使用 1K 缓冲区仅收集大约 20% 的样本。我更喜欢使用较小的缓冲区大小来获得对检测到的声音的近实时响应。在我写这篇文章时,4K 缓冲区版本一直在运行,并稳定在 39678 样本/秒。

我错过了什么吗?一个小缓冲区大小的抽头实际上可以捕获 44.1 Khz 的样本数据吗?

4

1 回答 1

1

问题已解决...水龙头需要这行代码

buffer.frameLength = self.bufferSize

...突然间所有的样本都出现了。我显然从我显然不理解的代码中删除了太多代码。

于 2017-11-11T19:52:06.200 回答