c++ - AudioOutputUnitStart 非常慢

标签 c++ ios core-audio

我有一个代码可以播放单声道音频事件(各种频率的短哔声)。 我创建了一个 AudioOutputUnit,在我需要播放音频时停止它。我启动它。当我播放了规定的时间后,我就停止了。

听起来很简单。

但是,AudioOutputUnitStart 在我的 iPhone 4S(使用 iOS 5.1)上通常需要 180 毫秒才能返回,这太长了。

这里是 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 后返回。如果我立即停止并立即开始,那么它只需要大约 5m,这是更容易接受的。

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

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

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

最佳答案

处理音频单元启动延迟的方法是在需要的时间之前提前启动音频单元,而不是停止它。相反,只需为短缓冲区配置 Audio Session ,然后用静音填充音频单元渲染回调缓冲区,直到用您想要的声音填充它们。然后在你的声音之后,返回到用静音而不是停止来填充缓冲区。

关于c++ - AudioOutputUnitStart 非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10141526/

相关文章:

ios - 屏幕更改后的默认 UIAccessibilityElement

ios - Swift 中的 UIPickerView 子类 : error optional value in viewForRow

iphone - 您如何在iPhone上以卡拉OK风格显示歌曲歌词?

c++ - 如何为 Visual Studio 2017 构建 CEF1

ios - 自动布局和 CGAffineTransform

ios - "Audio Queue Services"的好指南?

ios - 音频框架困惑

c++ - 输入输出流

c# - 在 C# 中序列化/编码简单对象以通过网络发送,供非托管 C++ 应用程序读取

c++ - 如果前一个字符相同则跳过数组中的一个字符