如何防止iPhone 3GS过滤低频(<150Hz)

Alb*_*ert 18 iphone core-audio audiounit

我正在开发iphone 3GS上的低音吉他音高检测应用程序.我发现使用RemoteIO无法获得低于150Hz的声音数据.然而,低音吉他可能会产生低于50hz的音调.根据报告"iPhone 4耳机输入频率响应",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));
Run Code Online (Sandbox Code Playgroud)

这是回调函数.

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;
}
Run Code Online (Sandbox Code Playgroud)

要找出根本原因,

  1. 我修改了我的回调函数,只是绕过输入数据输出.
  2. 使用Mac产生白噪声
  3. 使用iRig将信号从Mac的耳机重定向到运行我程序的iPhone3G.
  4. 使用iRig将iPhone的输出重定向回Mac.
  5. 在Mac上记录数据. 在此输入图像描述 输出数据频谱如下图所示. 在此输入图像描述

你可以看到150Hz的急剧下降.

为了确定问题是在输入侧还是输出侧,我改变了回调函数以忽略输入数据并输出白噪声.这是结果. 在此输入图像描述 很清楚,150赫兹没有下降.因此问题应该在输入端.

我认为这是硬件限制.但是,我在同一设备上尝试了"Amplitube"应用程序,关闭所有效果,输入白噪声并分析输出.它在150Hz时没有下降.这是结果.iPhone 3gs上的Amplitube频率响应 这意味着掉线问题不是硬件限制.软件必须采取某种方式来避免这个问题.

有人知道这个秘密吗?

谢谢.

P i*_*P i 0

有趣的问题。我不知道有任何这样的过滤器...您可以在远程 IO 单元上设置输入回调并获取浮点数流。

我还没有看到任何文档表明该浮动流已以某种方式进行了处理。

我写了一个音调检测器,它成功地拾取我的歌唱范围的低端音符(~80Hz)

也许发布代码——你在这个回调中做什么?