AudioOutputUnitStart is very slow

I have a code that plays a monophonic event (short beeps at different frequencies). I create an AudioOutputUnit, stop it and whenever I need to play audio. I start. When I played it for the required time, I stop it.

Sounds simple enough.

However, AudioOutputUnitStart will usually take 180 ms to return to my iPhone 4S (with iOS 5.1), which is too much.

Here is the creation / initialization of 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; } 

To get started, I just call:

 OSErr err = AudioOutputUnitStart(m_toneUnit); 

When done:

 OSErr err = AudioOutputUnitStop(m_toneUnit); 

I tried different things: what makes the kAudioSessionProperty_PreferredHardwareIOBufferDuration property very small (e.g. 5 ms) Decrease the frame rate (try 48 kHz, 44.1 kHz, 8 kHz)

No matter what I do ... When I first start an audio unit, AudioOutputUnitStart returns only after 160-180 ms. If I stop and start right away, then it will only take about 5 m, which is much more acceptable.

The delay in my application is quite important, and 180 ms is definitely not acceptable.

Any suggestions? I saw several people ask similar questions, but usually they didn’t have an answer.

I hope this time everything will be different :)

+2
source share
1 answer

A way to deal with the delay in starting the Audio Unit is to start the Audio Unit earlier than necessary, rather than stopping it. Instead, simply set up an audio session for short buffers, and then fill the sound block with a silence callback buffer until it fills them with the desired sound. Then, after your sound, return to filling the buffers with silence, not stopping.

+2
source

Source: https://habr.com/ru/post/1415053/


All Articles