在 Objective-C 中处理大量音频样本

Posted

技术标签:

【中文标题】在 Objective-C 中处理大量音频样本【英文标题】:Manipulating a large array of audio samples in Objective-C 【发布时间】:2012-02-11 10:14:37 【问题描述】:

我在 C 语言中有一组音频样本,我在这些样本上运行低通滤波器等算法。在处理之前,我正在考虑将我的数组转换为 Objective-C。这主要是因为我更喜欢这种语言并且它很方便(尤其是能够轻松获取数组的长度而不必处理指针)。

我想知道是否有任何理由说明这可能是个坏主意。或者,如果这样做有什么我不知道的缺点。比如处理如此大量样本的速度(?)。

【问题讨论】:

【参考方案1】:

标准做法是使用 c 样式数组来处理音频数组。这是因为如果您必须使用带有 obj-c 消息传递的 Objective-c 容器对象来访问每个元素,那么性能会很差,而且正如您所注意到的,带有音频的样本数量可能会非常大。

这对于实时处理尤其如此,例如处理存在于系统音频 io 回调中的音频样本,它必须在一定的毫秒数内完成这项工作,否则声音会中断。

您可以做的是定义一个结构(甚至是一个目标 c 类),该结构具有音频缓冲区数组以及诸如大小、通道数等信息元素,以便在一个位置为您将其包装在一起。这样,当您访问缓冲区时,您就不需要陷入 obj-c 效率问题,并且您仍然可以获得缓冲区规范信息。

这是一个例子:

typedef struct filter_buffer 
   uint16_t* buffer;
   int   channels;
   int   num_frames;
 filter_buffer;

然后你只需要一个初始化它的调用。

你可以用objective-c做一些事情,比如:

@interface FilterBuffer : NSObject

  uint16_t* buffer;
  int   channels;
  int   num_frames;   


-initWithBuffer:(unit16_t*)buf channels:(int)c numFrames:(int)n;
...//accessors etc
@end

@implementation FilterBuffer
-initWithBuffer:(unit16_t*)buf channels:(int)c numFrames:(int)n

   if ((self = [super init)) 
      buffer = buf;
      channels = c;
      num_frames = n;
   
   return self;

...
@end

【讨论】:

虽然不是实时的。你认为这仍然是一个问题吗? 它会起作用,只是明显变慢了。我会考虑在 c 缓冲区周围定义一个 obj-c 包装器,而不是使用 NSMutableArray 之类的东西来跟踪每个样本。 是否有可能获得关于它的外观的代码的 sn-p。我有点菜鸟:)。 另外,我发现这与 CFArrays 有关。也许这就是我正在寻找的答案? developer.apple.com/library/ios/#documentation/CoreFoundation/… 我发布了一个使用普通数组(缓冲区)的示例。您正在那里查看动态数组。如果它只是对非实时处理代码进行原型设计,并且您真的对 NSMutableArray 感觉更舒服,我会在 CF 对应物上使用它。您以后可以随时更改。【参考方案2】:

缺点是:

速度。它会明显变慢。 它不能实时使用,objc 消息传递速度明显较慢并且可能会锁定。 它不是便携式的。 它不会与其他库很好地集成。 根据您的处理方式,它可能会产生巨大的内存影响。使用NSNumbers 的数组(例如)将需要几 的内存。事实上,这就是你的帖子所暗示的——NSMutableArrayNSNumbers。 您将无法正确地阅读或编写音频程序。您在现实世界中看到的程序通常是 C++ 和 C。 C 数组不是可怕的东西 =) 当您需要重用它时,您最终可能只是重写它,因为在大多数情况下,它是不适合这项工作的工具。

【讨论】:

【参考方案3】:

由于性能原因,在内部循环中使用 Objective C 对象的 DSP 是不好的。出于这个原因,除其他外,您会发现大多数音频过滤器和 DSP 算法以纯 C、可能是 C++ 或类似的伪代码发布。所以你可能不得不习惯于阅读纯 C DSP 代码。

此外,C 是 Objective C 的真子集。

【讨论】:

以上是关于在 Objective-C 中处理大量音频样本的主要内容,如果未能解决你的问题,请参考以下文章

音频处理Melodyne 音高调整 ( 打开音频文件 | 选择音高编辑工具 | 样本音高信息 | 音高自动调整 )

将音频样本转换为可听文件格式

处理 16 位样本音频

AudioQueue 录制音频样本

Objective-C 流式上传音频

如何从音频文件中获取样本的浮点数组