我正在 iphone 3GS 上开发一个低音吉他音高检测应用程序。我发现我无法使用 RemoteIO 获得低于 150Hz 的声音数据。然而,低音吉他可能会产生低于 50hz 的音调。根据报告《iPhone 4 Headset Input Frequency Response》,http://blog.faberacoustical.com/2010/iphone/iphone-4-audio-and-frequency-response-limitations/ 150以下有急剧下降赫兹。
这里展示了我如何设置 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 时没有下降。这是结果。
这意味着脱落问题不是硬件限制。软件必须有某种方法可以避免这个问题。
有谁知道其中的秘密?
谢谢。