我有一个播放单声道音频事件的代码(各种频率的短哔声)。我创建了一个 AudioOutputUnit,将其停止,并在我需要播放音频时停止。我启动它。当我播放了所需的时间时,我会停止它。
听起来很简单。
但是,在我的 iPhone 4S(使用 iOS 5.1)上,AudioOutputUnitStart 通常需要 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 属性设置为一个非常小的值(如 5 毫秒) 降低帧速率(尝试 48kHz、44.1kHz、8kHz)
不管我做什么......第一次启动音频单元时,AudioOutputUnitStart 仅在 160-180 毫秒后返回。如果我立即停止并启动它,那么它只需要大约 5m,这是可以接受的。
在我的应用程序中延迟是相当重要的,180ms 绝对是不可接受的。
有什么建议么?我见过一些人问过类似的问题,但他们通常没有得到答案。
我希望这次事情会有所不同:)