在 iOS5 中使用 Filter Audio Unit Effect

Posted

技术标签:

【中文标题】在 iOS5 中使用 Filter Audio Unit Effect【英文标题】:Using a Filter Audio Unit Effect in iOS5 【发布时间】:2012-01-23 21:41:48 【问题描述】:

我正在尝试使用远程 IO 连接并通过内置过滤器效果(仅限 ios 5)路由音频输入,然后退出硬件。我可以让它直接从输入路由到输出,但我无法让过滤器工作。我不确定是过滤器音频单元还是路由错误。

这一点只是我尝试设置过滤器和更改路由以便由它处理数据。

感谢任何帮助。

// ******* BEGIN FILTER ********

NSLog(@"Begin filter");

// Creates Audio Component Description - Output Filter    
AudioComponentDescription filterCompDesc;
filterCompDesc .componentType = kAudioUnitType_Effect;
filterCompDesc.componentSubType = kAudioUnitSubType_LowPassFilter;
filterCompDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
filterCompDesc.componentFlags = 1;
filterCompDesc.componentFlagsMask = 1;


// Create Filter Unit
AudioUnit lpFilterUnit;
AudioComponent filterComponent = AudioComponentFindNext(NULL, &filterCompDesc);
setupErr = AudioComponentInstanceNew(filterComponent, &lpFilterUnit);
NSAssert(setupErr == noErr, @"No instance of filter");

AudioUnitElement bus2 = 2;
setupErr = AudioUnitSetProperty(lpFilterUnit, kAudioUnitSubType_LowPassFilter, kAudioUnitScope_Output, bus2, &oneFlag, sizeof(oneFlag));

AudioUnitElement bus3 = 3;
setupErr = AudioUnitSetProperty(lpFilterUnit, kAudioUnitSubType_LowPassFilter, kAudioUnitScope_Input, bus3, &oneFlag, sizeof(oneFlag));



// ******** END FILTER ******** //


AudioUnitConnection hardInToLP;
hardInToLP.sourceAudioUnit    = remoteIOunit;
hardInToLP.sourceOutputNumber = 1;
hardInToLP.destInputNumber    = 3;

setupErr = AudioUnitSetProperty (
                      remoteIOunit,                     // connection destination
                      kAudioUnitProperty_MakeConnection,  // property key
                      kAudioUnitScope_Input,              // destination scope
                      bus3,                // destination element
                      &hardInToLP,                // connection definition
                      sizeof (hardInToLP)
                      );

AudioUnitConnection LPToHardOut;
LPToHardOut.sourceAudioUnit    = lpFilterUnit;
LPToHardOut.sourceOutputNumber = 1;
LPToHardOut.destInputNumber    = 3;

setupErr = AudioUnitSetProperty (
                      remoteIOunit,                     // connection destination
                      kAudioUnitProperty_MakeConnection,  // property key
                      kAudioUnitScope_Input,              // destination scope
                      bus3,                // destination element
                      &hardInToLP,                // connection definition
                      sizeof (hardInToLP)
                      );


/*
// Sets up the Audio Units Connection - new instance called connection
AudioUnitConnection connection;

// Connect Audio Input's out to Audio Out's in
connection.sourceAudioUnit = remoteIOunit;
connection.sourceOutputNumber = bus1;
connection.destInputNumber = bus0;


setupErr = AudioUnitSetProperty(remoteIOunit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, bus0, &connection, sizeof(connection));
*/ 

NSAssert(setupErr == noErr, @"No RIO connection");

【问题讨论】:

【参考方案1】:

这里发生了一些事情:

如果您在每次可以返回 OSStatus 的调用后执行断言(或某种检查错误并记录它),您将获得很大帮助。这样你就会知道你能走多远。可能还想在实际 OSStatus 值 != noErr 时记录它,然后查找它(从 Xcode 文档查看器中的“音频单元组件服务参考”开始)。 创建过滤器 AudioUnit 后,我​​不明白您对 AudioUnitSetProperty() 调用的操作。第二个参数应该是属性的名称(以 kAudioUnitProperty... 开头的东西)。这几乎肯定会在那里返回一个错误。 remoteIOunit 只有两条总线,它们有特殊的含义。总线 1 从麦克风输入,总线 0 输出到硬件。尝试连接到远程 io 输入范围总线 3 可能会是另一个错误

建议您回滚到音频直通工作时。这意味着您只有 remoteIO,以及从输出范围/总线 1 到输入范围/总线 0 的连接。

然后创建过滤器单元。更改您的连接以便连接:

remoteIO 输出范围总线 1 过滤输入范围总线 0 过滤输出范围总线 0 到 remoteIO 输入范围总线 0

另外一个问题是所有这些 iOS 5 过滤器似乎都想使用浮点 LPCM 格式,这不是您的其他单元默认使用的规范格式。您可能必须从过滤器单元获取流格式(输入或输出范围可能相同?),然后将其设置为 remoteIO 输出范围/总线 1 产生和 remoteIO 输入范围/总线 0 接受的格式。另一种选择是在过滤器单元之前和之后引入 AUConverter 单元。

【讨论】:

“所有这些 iOS 5 过滤器似乎都想使用浮点 LPCM 格式” - 我想这就是为什么当我将其设置为混合器时我的图表无法启动(使用 kAudioUnitErr_CannotDoInCurrentContext) - >bandpass->io,但如果我将带通滤波器更改为 iOS 5 之前的 iPod EQualizer,它就可以正常工作。【参考方案2】:

这里给出的第一个答案只是让我更加沮丧。 Apple 文档在哪里没有告诉您效果单元的文件格式需要浮点数。在我阅读这篇文章之前,我无法弄清楚为什么它一直无法正确播放我的音频。我按照上面的建议从低通滤波器单元中检索了流格式,并用它来设置我创建的两个转换器单元(即设置前置滤波器转换器的输出格式和后置滤波器的输入格式转换器。一旦我这样做并将所有节点连接在一起,它就开始按预期工作。

【讨论】:

同意。 Apple 应该将音频单元文档完全更新到我们生活的后 iOS 5 世界!【参考方案3】:

我尝试使用低通滤波器,当尝试按照建议进行设置格式时,我不断收到错误“操作无法完成”这段代码有什么问题? 检索 lowpassUnit 后,我​​还检查了错误,但没有。

result = AudioUnitSetProperty(lowpassUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &stereoStreamFormat, sizeof (stereoStreamFormat));
    if (noErr != result)

    NSLog(@"%@", [NSError errorWithDomain:NSOSStatusErrorDomain code:result        userInfo:nil]);
    return;

PS:如果有人知道正确的音频单元文档,请分享,因为官方文档确实缺乏

【讨论】:

以上是关于在 iOS5 中使用 Filter Audio Unit Effect的主要内容,如果未能解决你的问题,请参考以下文章

试图弄清楚 Core Audio 的 NBandEQ

为啥我的U盘里面有一个audio_play_list.txt的文件删了又出来?删都删不了.

在 iPad 上播放音频

django中filter的values_list条件使用

ffmpeg filter学习混音实现 二

在 iOS 5 中获取屏幕亮度值