如何防止 iPhone 3GS 过滤低频(<150Hz)
Posted
技术标签:
【中文标题】如何防止 iPhone 3GS 过滤低频(<150Hz)【英文标题】:How to prevent iPhone 3GS from filtering low frequencies ( < 150Hz ) 【发布时间】:2011-10-08 09:17:33 【问题描述】:我正在 iphone 3GS 上开发一个低音吉他音高检测应用程序。 我发现我无法使用 RemoteIO 获得低于 150Hz 的声音数据。 然而,低音吉他可能会产生低于 50hz 的音调。 根据报告《iPhone 4 耳机输入频率响应》,http://blog.faberacoustical.com/2010/iphone/iphone-4-audio-and-frequency-response-limitations/ 低于 150 Hz 时急剧下降。
这里展示了我如何设置 AudioUnit。
// set audio unit
// create AudioUnit
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
OSAssert(AudioComponentInstanceNew(comp, &m_AudioUnit));
//enable input on the remote I/O unit (output is default enabled, but input is not)
UInt32 one = 1;
OSAssert(AudioUnitSetProperty(m_AudioUnit, kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input, 1, &one, sizeof(one)));
//set render callback function
AURenderCallbackStruct callbackInfo;
callbackInfo.inputProc=staticPerformThru;
callbackInfo.inputProcRefCon=this;
OSAssert(AudioUnitSetProperty(m_AudioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0, &callbackInfo, sizeof(callbackInfo)));
//set in/output format
CAStreamBasicDescription outFormat;
outFormat.SetAUCanonical(channels, false);
outFormat.mSampleRate = sampleRate;
OSAssert(AudioUnitSetProperty(m_AudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outFormat, sizeof(outFormat)));
OSAssert(AudioUnitSetProperty(m_AudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &outFormat, sizeof(outFormat)));
//Initialize remote I/O unit
OSStatus r=AudioUnitInitialize(m_AudioUnit);
OSAssert(r);
//start audio output
OSAssert(AudioOutputUnitStart(m_AudioUnit));
这是回调函数。
OSStatus AudioThruWorker::staticPerformThru(
void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
AudioUnitRender(((AudioThruWorker*)inRefCon)->m_AudioUnit, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData);
//Detect pitch here...
return 0;
要找出根本原因,
-
我修改了我的回调函数以绕过输入数据输出。
使用 Mac 生成白噪声
使用 iRig 将信号从 Mac 耳机重定向到正在运行我的程序的 iPhone3Gs。
使用 iRig 将 iPhone 的输出重定向回 Mac。
在 Mac 上记录数据。
输出数据频谱如下图所示。
您可以在 150Hz 处看到急剧下降。
为了确定问题出在输入端还是输出端,我将回调函数更改为忽略输入数据并输出白噪声。这是结果。 非常清楚,在 150 Hz 时没有下降。因此问题应该在输入端。
我认为这是硬件限制。 但是我在同一台设备上尝试了应用程序“Amplitube”,关闭所有效果,输入白噪声并分析输出。它在 150Hz 时没有下降。这是结果。 这意味着脱落问题不是硬件限制。软件必须有某种方法可以避免该问题。
有人知道这个秘密吗?
谢谢。
【问题讨论】:
你找到问题了吗?我很好奇发生了什么。 抱歉还没有。我猜这是由 ios 4.x 限制引起的。我知道 iOS 5 有一个“测量模式”。但是我还没有测试过。 【参考方案1】:嗯,它是一部电话,据说是一种针对语音进行了优化的设备。并且针对语音进行了优化的设备通常具有某种 LF 截止滤波器,以避免隆隆声和失真。
这个滤波器可能在手机的输入端,这就是为什么你可以生成和输出更广泛的频率,它可能是一个硬件/离散元件滤波器,因为它们很容易创建,只使用几个组件并且将实时工作,不会对处理造成任何压力。
我认为在软件中削减低点没有意义,我知道我不会这样做,好吧,对于 DAW 应用程序你可以做到,但对于经过优化以过滤低点的设备......
考虑到 amplitube 开发人员可能已经意识到这个问题并添加了额外的低提升来尝试弥补硬件限制?
另一方面,很有可能根据使用场景选择不同的“信号路径”,也许有一些操作系统处理应用程序可以触摸说“嘿,我不是声音,不要剪我的lows" - 如果是这样,这个特性应该在 api 描述中的某个地方。
【讨论】:
【参考方案2】:有趣的问题。我不知道有任何此类过滤器...您可以在远程 IO 单元上设置输入回调并获取浮点流。
我还没有看到任何文档表明这个浮点流已经以某种方式处理过。
我编写了一个音高检测器,它成功地在我的歌唱范围的低端(~80Hz)拾取音符
也许是邮政编码——你在这个回调中做什么?
【讨论】:
我将白噪声发送到 iPhone 3GS,然后记录我的程序和放大器的输出。我的程序只创建一个 RemoteIO 音频单元并将输入重定向到输出。这是比较图:link 看来我的输出从 250 hz 下降了...... amplitube 更平坦 '哎呀......这里没什么可看的。' Picasa 说 抱歉,忘记公开了。你能试试这个link【参考方案3】:我能否建议您重新提出这个问题,并使用适当的标题(可能类似于“如何防止 iPhone 过滤低频(
你甚至没有说明你想要完成什么。
您似乎是该网站的新手,而且这似乎是一个非常有趣的问题。
但你一点都不清楚。
首先,这是记录或回放或两者兼有的问题?
现在,您在实验中到底在做什么?西方的科学方法……把它摆出来。
您在 remoteIO 渲染回调中生成静态?不,听起来您正在使用直通,您说您正在将白噪声放入 iPhone。你是如何设置你的音频单元的?
所以白噪声直接进入 iPhone,然后……现在该图代表什么? iPhone输出的FFT /光谱分析?你是怎么做到的?你要把它输入到一些 OSX 绘图软件中,这些软件可以从行中获取输入?
另外,您可以缩小范围。如果您确实将声音直接通过设备,则您不知道过滤发生在哪里。据您所知,产生白噪声的设备以及绘制 iPhone 输出图表的设备中可能会发生过滤。
如何从远程 I/O 渲染回调中生成白噪声?
然后在外部生成它并分析来自此回调的数据——您可以执行 FFT。
不管怎样,输入不同频率的正弦波不是更好吗?
【讨论】:
如果您确实问这是一个单独的问题,请通过评论从此处链接到它以上是关于如何防止 iPhone 3GS 过滤低频(<150Hz)的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 UIImagePickerController 类只显示 iPhone 3GS 的录像机
如何通过区域监控支持 iPhone 3GS 和 iPod Touch