Voici un code pour utiliser AudioQueue, que j'ai modifié à partir de l'exemple SpeakHere. Je genre de collais les bonnes parties, donc il peut y avoir quelque chose ballants ici ou là, mais cela devrait être un bon point de départ si vous souhaitez utiliser cette approche:
AudioStreamBasicDescription format;
memset(&format, 0, sizeof(format));
format.mSampleRate = 44100;
format.mFormatID = kAudioFormatLinearPCM;
format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
format.mChannelsPerFrame = 1;
format.mBitsPerChannel = 16;
format.mBytesPerFrame = (format.mBitsPerChannel/8) * format.mChannelsPerFrame;
format.mFramesPerPacket = 1;
format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket;
AudioQueueRef queue;
AudioQueueNewOutput(&format,
AQPlayer::AQOutputCallback,
this, // opaque reference to whatever you like
CFRunLoopGetCurrent(),
kCFRunLoopCommonModes,
0,
&queue);
const int bufferSize = 0xA000; // 48K - around 1/2 sec of 44kHz 16 bit mono PCM
for (int i = 0; i < kNumberBuffers; ++i)
AudioQueueAllocateBufferWithPacketDescriptions(queue, bufferSize, 0, &mBuffers[i]);
AudioQueueSetParameter(queue, kAudioQueueParam_Volume, 1.0);
UInt32 category = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);
AudioSessionSetActive(true);
// prime the queue with some data before starting
for (int i = 0; i < kNumberBuffers; ++i)
OutputCallback(queue, mBuffers[i]);
AudioQueueStart(queue, NULL);
Le code fait référence ci-dessus pour ce rappel de sortie. Chaque fois que ce rappel s'exécute, remplissez le tampon transmis avec votre audio généré. Ici, je le remplis de bruit aléatoire.
void OutputCallback(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer) {
// Fill
//AQPlayer* that = (AQPlayer*) inUserData;
inCompleteAQBuffer->mAudioDataByteSize = next->mAudioDataBytesCapacity;
for (int i = 0; i < inCompleteAQBuffer->mAudioDataByteSize; ++i)
next->mAudioData[i] = rand();
AudioQueueEnqueueBuffer(queue, inCompleteAQBuffer, 0, NULL);
}
Grumdrig, pourriez-vous développer votre réponse? J'ai du mal à assembler les pièces. Vous semblez utiliser des variables locales d'une fonction dans l'autre comme s'il s'agissait de variables membres d'un objet plus grand (par exemple. 'Queue'). Aussi, je ne sais pas si 'AQPlayer :: AQOutputCallback' et votre exemple' OutputCallback' sont supposés être la même fonction/méthode. Enfin, de quoi et d'où provient l'objet 'next' dans votre exemple de méthode de rappel? J'apprécierais grandement tout aperçu supplémentaire/code révisé que vous pourriez fournir. –
Peu importe, je l'ai compris. http://stackoverflow.com/questions/2270218/playing-audio-on-the-iphone-decoded-by-third-party-library/2274549#2274549 –