J'ai un code qui lit un événement audio mono (bips courts à diverses fréquences). Je crée un AudioOutputUnit, l'arrête et chaque fois que j'ai besoin de lire l'audio. Je le commence. Quand je l'ai joué pendant le temps requis, je l'arrête.AudioOutputUnitStart très lent
Sons assez simples.
Cependant, AudioOutputUnitStart prendra habituellement 180ms pour revenir sur mon iPhone 4S (avec iOS 5.1), c'est beaucoup trop.
Voici la création/initialisation du 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;
}
Pour commencer, je voudrais simplement appeler:
OSErr err = AudioOutputUnitStart(m_toneUnit);
Lorsque vous avez terminé:
OSErr err = AudioOutputUnitStop(m_toneUnit);
J'ai essayé diverses choses: rendant la propriété kAudioSessionProperty_PreferredHardwareIOBufferDuration t o une valeur très faible (comme 5ms) Réduire le framerate (essayé 48kHz, 44.1kHz, 8kHz)
Peu importe ce que je fais ... première fois que le AudioUnit est démarré, AudioOutputUnitStart retourne seulement après 160-180ms. Si je m'arrête et que je démarre tout de suite, cela ne prend que 5m, ce qui est beaucoup plus acceptable.
La latence dans mon application est assez importante, et 180ms est définitivement inacceptable.
Des suggestions? J'ai vu quelques personnes poser des questions similaires, mais ils n'ont généralement jamais eu de réponse.
J'espère que cette fois les choses seront différentes :)
Vous avez probablement déjà pensé à cela - mais l'ajout/suppression de renderCallback fonctionne-t-il ici? Aussi vu cela (bien que votre tampon est minuscule): http://stackoverflow.com/questions/5690460/objective-c-audiooutputunitstart-takes-a-long-time-to-start-possible-workaroun –
Je n'ai pas réellement pensé à supprimer le rappel; dans le rappel, l'onde sonore est réellement générée, de sorte que le tampon audio peut être minuscule. J'essaierai – jyavenard