1

这是一个更通用的 RTFM DSP 问题,来自对音频制作和软件非常熟悉的人,但对于音频软件开发来说是新的,关于未压缩(wav、caf、aiff)文件(44.1 采样率,16 位)之间的大小差异磁盘,与此音频在内存中的实际浮点值。

例如,我有一个测试 WAV 文件,根据 MacOS,它为 7 分 14 秒 (7:14),大小为 83.4 MB。

如果我将此文件导入我的项目并将文件AKAudioFile作为.floatChannelData.大约 2300 万个浮点数,堆上大约 180 兆字节。这是有道理的,因为FloatSwift 中的标准对象是一个 32 位浮点数,每个浮点数 8 个字节。

我了解它的大小,但是我希望至少在我的应用程序中能够使用更接近 16 位的东西,我只是在分析这个音频,而不是以任何方式处理它,即使经过一些基本的优化并防止深度复制,任何超过 10 分钟左右的音频都会占用堆上的内存。

根据这个SO question,有一些将 32 位转换为 16 位的新颖方法,但老实说,这对于我想要做的事情来说感觉像是错误/矫枉过正的方法。举个例子,如果我只是简单地从我的引用 它会自动向堆中添加大约 300 兆!即使没有复制,附加等......floatChannelDataAKAudioFile

对于更有经验的 DSP 音频开发人员,是否有任何资源可用于对程序中的大浮点数进行良好的堆/堆栈管理?AudioKit 可以将内容录制到 16 位吗?我目前正在使用 C 和 C++ 进行处理,所以如果它具有更高的性能,我觉得在那里进行任何类型的数学或转换都很舒服。任何线索都非常感激,谢谢!

4

1 回答 1

4

AudioKit 使用各种需要 32 位浮点数组格式的数据的 3rd 方 DSP 例程。当这些数组以某种方式被引用或以某种方式作为参数传递时,Swift 会复制 Swift 数组。因此,如果您将基本的 Swift 编码技术与常见的 AudioKit API 一起使用,您可能会遇到大量内存使用问题。

另一种方法是不将 AudioKit API 与标准 Swift 数组一起使用,仅在需要时将数据转换为 32 位。

例如,您可以内存映射(mmap)您的 WAVE 文件,这允许 iOS 根据需要将 16 位数据分页到 VM 系统中,而不是一次全部转换为 32 位 AudioKit 格式。然后使用 vDSP 仅将映射文件中需要的 16 位 WAVE 数据切片转换为更小的预分配 C 浮点数组,这是调用 DSP 例程所需的最小值(可能与 AudioKit 内部使用的 C 代码相同) . 在将(可变的、不安全的原始)指针传递给 C 例程时,Swift 通常不会复制这些预分配的 C 数组。

这些技术可以让你的应用程序的内存占用更小,使用更少的 CPU 周期,并有助于防止你的应用程序以最快的速度耗尽 iOS 设备的电池)。

于 2019-02-16T18:42:28.667 回答