gpt4 book ai didi

c++ - AudioUnit 中的输入缓冲区结构

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:26:42 24 4
gpt4 key购买 nike

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

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

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

我的输入缓冲区中的前 4 个值是:0.0001040.0001010.0000800.000113

输出是:0.0001010.0001040.0001130.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;
}
}
}

最佳答案

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

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

编辑:好的,事实证明内核回调总是传递 1 个音频 channel 。此外,按照我最初的建议覆盖 Render() 并不是执行此操作的最佳方法。根据 AUEffectBase.h 源代码中的注释:

If your unit processes N to N channels, and there are no interactions between channels, it can override NewKernel to create a mono processing object per channel. Otherwise, don't override NewKernel, and instead, override ProcessBufferLists.

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

我的效果.h:

#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
};

我的效果.cpp:

// Other stuff ....

OSStatus MyEffect::ProcessBufferLists(AudioUnitRenderActionFlags &ioActionFlags,
const AudioBufferList &inBuffer,
AudioBufferList &outBuffer,
UInt32 inFramesToProcess) {
const float *srcBufferL = (Float32 *)inBuffer.mBuffers[0].mData;
const float *srcBufferR = (Float32 *)inBuffer.mBuffers[1].mData;
float *destBufferL = (Float32 *)outBuffer.mBuffers[0].mData;
float *destBufferR = (Float32 *)outBuffer.mBuffers[1].mData;

for(UInt32 frame = 0; frame < inFramesToProcess; ++frame) {
*destBufferL++ = *srcBufferL++;
*destBufferR++ = *srcBufferR++;
}
}

关于c++ - AudioUnit 中的输入缓冲区结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6066140/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com