AudioUnit中的输入缓冲区结构

时间:2011-05-19 23:58:27

标签: c++ xcode audio buffer audiounit

我写了一个简单的audiounit,应该交换立体声源的左右声道。对于使用BASS库的命令行程序,此代码的移植版本在C中运行良好,但我无法使用相同的代码在Xcode中进行音频处理。

对于缓冲输入,例如{1,2,3,4,5,6},我希望立体声反转为{2,1,4,3,5,5}。

我的代码以这种方式正确地反转了样本,但我听到的只是某种低通滤波,而不是样本的立体反转。

输入缓冲区中的前4个值是: 0.000104 0.000101 0.000080 0.000113

输出是: 0.000101 0.000104 0.000113 0.000080

我是否误解了输入/输出缓冲区的结构方式?

void        First::FirstKernel::Process(    const Float32   *inSourceP,
                                                Float32         *inDestP,
                                                UInt32          inSamplesToProcess,
                                                UInt32          inNumChannels, 
                                                bool            &ioSilence )
{


if (!ioSilence) {                                                 

    const Float32 *sourceP = inSourceP;  
    Float32  *destP = inDestP;  
    for (int i = inSamplesToProcess/2; i>0; --i) { 


        *(destP+1) = *sourceP;
        *destP = *(sourceP+1);

        sourceP = sourceP +2;
        destP = destP +2;
}   
}   
}

1 个答案:

答案 0 :(得分:6)

此代码不起作用的原因是因为您正在使用AudioUnit内核,它调用您的插件来处理单个音频数据通道(如果我理解正确的话)。虽然在某些情况下内核可能非常方便,但它肯定不适用于执行相互依赖的立体声处理的插件。您正在传递回调中的频道数 - 是否已检查此值?

无论如何,您应该继承AUEffectBase类并覆盖ProcessBufferLists()方法。然后,您将获得一个适当的AudioBufferList结构,其中包含每个音频通道的非隔行缓冲区。与使用内核相比,它还可以更好地控制渲染过程。

编辑:好的,事实证明,内核回调总是传递1个音频通道。另外,按照我最初的建议覆盖Render()并不是最好的方法。根据{{​​1}}源代码中的评论:

  

如果您的单位处理N到N个频道,并且频道之间没有互动,   它可以覆盖NewKernel以为每个通道创建单声道处理对象。除此以外,   不要覆盖NewKernel,而是覆盖ProcessBufferLists。

由于AUEffectBase.h不是“标准”AudioUnit代码的一部分,因此您需要将cpp / h文件添加到项目中。它们可以在AUEffectBase文件夹中的AudioUnit SDK根目录下找到。所以对于你的插件,它看起来像这样:

MyEffect.h:

AudioUnits/AUPublic/OtherBases

MyEffect.cpp:

#include "AUEffectBase.h"

class MyEffect : public AUEffectBase {
public:
  // Constructor, other overridden methods, etc.
  virtual OSStatus ProcessBufferLists(AudioUnitRenderActionFlags &ioActionFlags,
                                      const AudioBufferList &inBuffer,
                                      AudioBufferList &outBuffer,
                                      UInt32 inFramesToProcess);


private:
  // Private member variables, methods
};