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

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

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

【问题讨论】:

    标签: objective-c c audio signal-processing


    【解决方案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 的真子集。

      【讨论】:

        猜你喜欢
        • 2013-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多