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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (78)

我正在开发iphone 3GS上的低音吉他音高检测应用程序。我发现用RemoteIO无法获得低于150Hz的声音数据。不过低音吉他可能会产生低于50赫兹的音调。根据报告“iPhone 4耳机输入频率响应”有一个大大下降到低于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;
}

为了找出根本原因,

  1. 我修改了我的回调函数,将输入数据绕过输出。
  2. 使用Mac产生白色噪音
  3. 使用iRig将Mac耳机的信号重定向到运行我的程序的iPhone3G。
  4. 使用iRig将iPhone的输出重定向回Mac。
  5. 在Mac上记录数据。

输出数据频谱如下图所示。

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

为了确定问题出在输入侧还是输出侧,我改变了回调函数以忽略输入数据并输出白噪声。结果如下。

非常清楚,在150赫兹没有下降。因此,问题应该在输入端。

我认为这是一个硬件限制。但是我在同一台设备上试用过应用程序“Amplitube”,关闭所有效果,输入白噪声并分析输出。它在150赫兹没有下降。结果如下。

这意味着退出问题不是硬件限制。软件必须采取一些方法来避免这个问题。

有人知道这个问题吗?

提问于
用户回答回答于

你可以在远程IO单元上设置一个输入回调并获得一个浮动流。

我还没有看到这个浮点流在某种程度上已经被处理过的任何文档。

我已经写了一个音高探测器,它可以在我的歌唱范围的低端(〜80Hz)成功地拾取音符,

用户回答回答于

电话即一种为言语而优化的设备。并且针对语音优化的设备通常具有某种LF滤波器以避免失真和失真。

这个滤波器可能在手机的输入端,这就是为什么你可以产生和输出更宽的频率范围,它可能是一个硬件/分离元素滤波器,因为这些滤波器只需使用少量的组件就可以很容易地创建并且可以工作实时没有任何处理压力。

我认为在软件中削减低点是不合理的

考虑到Amplitube开发者可能已经意识到这个问题,并且增加了额外的低提升,试图弥补硬件限制?

扫码关注云+社区

领取腾讯云代金券