AudioOutputUnitStart非常慢

时间:2012-04-13 13:14:18

标签: c++ ios core-audio

我有一个播放单声道音频事件的代码(各种频率的短蜂鸣声)。 我创建一个AudioOutputUnit,停止它,每当我需要播放音频时。我开始吧当我在规定的时间内播放它时,我会停止它。

听起来很简单。

然而,AudioOutputUnitStart通常需要180ms才能在我的iPhone 4S(使用iOS 5.1)上返回,这太过分了。

这是AudioOutputUnit的创建/初始化

void createAOU()
{
    m_init = false;
    // find the default playback output unit
    AudioComponentDescription defaultOutputDescription;
    defaultOutputDescription.componentType = kAudioUnitType_Output;
    defaultOutputDescription.componentSubType = kAudioUnitSubType_RemoteIO;
    defaultOutputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
    defaultOutputDescription.componentFlags = 0;
    defaultOutputDescription.componentFlagsMask = 0;

    // Get the default playback output unit
    AudioComponent defaultOutput = AudioComponentFindNext(NULL, &defaultOutputDescription);
    if (defaultOutput == NULL)
        return;

    OSErr err = AudioComponentInstanceNew(defaultOutput, &m_toneUnit);
    if (err != noErr)
        return;

    // single channel, floating point, linear PCM
    AudioStreamBasicDescription streamFormat;
    streamFormat.mSampleRate = m_framerate;
    streamFormat.mFormatID = kAudioFormatLinearPCM;
    streamFormat.mFormatFlags =
    kLinearPCMFormatFlagIsFloat |
    kAudioFormatFlagsNativeEndian | kLinearPCMFormatFlagIsPacked;
    streamFormat.mBytesPerPacket = sizeof(float);
    streamFormat.mFramesPerPacket = 1;
    streamFormat.mBytesPerFrame = sizeof(float);
    streamFormat.mChannelsPerFrame = 1;
    streamFormat.mBitsPerChannel = sizeof(float) * 8;
    err = AudioUnitSetProperty (m_toneUnit,
                                kAudioUnitProperty_StreamFormat,
                                kAudioUnitScope_Input,
                                0,
                                &streamFormat,
                                sizeof(AudioStreamBasicDescription));
    if (err != noErr)
        return;

    // Attach callback to default output
    AURenderCallbackStruct input;
    input.inputProc = RenderTone;
    input.inputProcRefCon = this;
    err = AudioUnitSetProperty(m_toneUnit, 
                               kAudioUnitProperty_SetRenderCallback, 
                               kAudioUnitScope_Input,
                               0, 
                               &input, 
                               sizeof(input));
    if (err != noErr)
        return;

    float aBufferLength = 0.001; // In seconds
    AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, 
                            sizeof(aBufferLength), &aBufferLength);

    err = AudioUnitInitialize(m_toneUnit);
    if (err != noErr)
        return;
    reset();
    m_init = true;
}

要启动它,我只需要打电话:

OSErr err = AudioOutputUnitStart(m_toneUnit);

完成后:

OSErr err = AudioOutputUnitStop(m_toneUnit);

我尝试了各种各样的事情: 使kAudioSessionProperty_PreferredHardwareIOBufferDuration属性变为非常小的值(如5ms) 降低帧速率(尝试48kHz,44.1kHz,8kHz)

无论我做什么...... 第一次启动audiounit时,AudioOutputUnitStart仅在160-180ms后返回。如果我马上停下来开始它,那么它只需要大约5米就可以接受了。

我的应用程序的延迟非常重要,绝对不能接受180毫秒。

有什么建议吗? 我见过一些人提出类似的问题,但他们通常都没有得到答案。

我希望这次事情会有所不同:)

1 个答案:

答案 0 :(得分:2)

处理音频单元启动延迟的方法是在所需时间之前启动音频单元,而不是停止它。相反,只需为短缓冲区配置音频会话,然后用静音填充音频单元渲染回调缓冲区,直到用它们填充所需声音为止。听完声音后,回去用沉默填充缓冲区而不是停止。