AudioKit/DSP:了解磁盘上未压缩音频的大小与内存中的差异

Posted

技术标签:

【中文标题】AudioKit/DSP:了解磁盘上未压缩音频的大小与内存中的差异【英文标题】:AudioKit/DSP: Understanding the different between the size of uncompressed audio on disk vs. in memory 【发布时间】:2019-02-16 01:38:32 【问题描述】:

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

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

如果我将此文件导入我的项目并将文件作为AKAudioFile 打开,然后检查.floatChannelData 属性(这是一个由两个数组组成的数组,每个通道一个(立体声文件的两个标准)) ,特别是这个文件总共大约有 2300 万个浮点数,堆上大约 180 兆字节。这是有道理的,因为 Swift 中的标准 Float 对象是一个 32 位浮点数,每个浮点数 8 个字节。

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

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

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

【问题讨论】:

【参考方案1】:

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

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

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

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

【讨论】:

我在 iOS App Store 的 Music Spectrograph 应用中测试了所有这些技术。 这是惊人的知识。非常感谢您的回答!关于 mmap 的 TIL! 如此有见地,非常感谢 hotpaw2 期待尝试这些!

以上是关于AudioKit/DSP:了解磁盘上未压缩音频的大小与内存中的差异的主要内容,如果未能解决你的问题,请参考以下文章

idea用激活码激活后显示jdk11在磁盘上未找到或已损坏

Unicode 字体在 Chrome 上未正确显示

iOS 中使用 AudioConverterFillComplexBuffer 进行实时音频压缩

Arch LINux 上未定义 O_DIRECT

OpenGL纹理在四边形上未对齐

程序员需要了解的硬核知识之压缩算法