Re: Basic AudioQueue Service issue
Re: Basic AudioQueue Service issue
- Subject: Re: Basic AudioQueue Service issue
- From: Craig Patchett <email@hidden>
- Date: Thu, 23 Oct 2008 07:39:51 -0700
[Tried to send this last night but had problems with message size for
some reason.]
OK, so what I'm trying to do is accomplish the following on the iPhone:
- Reuse an audio queue so I don't have the added latency of reopening
the associated file every time I want to play it.
- Have the ability to have multiple audio queues playing at the same
time.
- Be able to restart an audio queue that's currently playing from the
beginning.
- Not have any audio artifacts (mainly popping) when restarting a
currently playing queue.
My first attempt at doing all this was with the AudioQueuePlayer and
AudioQueueObject classes from the SpeakHere sample app. I also tried
using SoundEngine from the CrashLanding app, which I'll get to later.
First, here is the play method I'm using:
- (void) play {
if (buffers[0] == NULL)
[self setupAudioQueueBuffers];
else {
// Set the volume to 0 and allow enough time for it to take in order
to
// avoid a "pop" as the buffer restarts
[self setGain: 0.0];
AudioQueueSetParameter(queueObject, kAudioQueueParam_Volume, gain);
[NSThread sleepForTimeInterval:0.05 ];
// Stop the queue if necessary
if ([self isRunning])
[self stop];
// Reprime the buffers
[self setDonePlayingFile: NO];
startingPacketNumber = 0;
int bufferIndex;
for (bufferIndex = 0; bufferIndex < kNumberAudioDataBuffers; +
+bufferIndex)
playbackCallback(self, [self queueObject], buffers[bufferIndex]);
}
// Reset the volume and restart the queue
[self setGain: 1.0];
AudioQueueSetParameter(queueObject, kAudioQueueParam_Volume, gain);
AudioQueueStart(self.queueObject, NULL);
}
The stop method is now a simple call to AudioQueueStop, the call to
AudioFileClose has been moved to the dealloc method, and
audioPlayerShouldStopImmediately is set to YES.
This code comes the closest to working properly that I've come so far.
For one queue, in fact, it seems to work flawlessly with a single
queue (albeit for the slight delay thanks to the sleep). When multiple
queues (8) are playing (all with short 3-4 second sound files) and are
restarted sequentially fairly quickly the app hangs within a few
seconds on the Simulator and on the device gets stuck in a loop with
part of the last played sound repeating indefinitely. In addition
there are latency issues on both the simulator and the device in
moving from queue to queue.
This brings me to SoundEngine, which I switched to after getting
completely frustrated with AudioQueue. SoundEngine has no latency
issues , no problem with multiple queues, and provides sound restarts
for free with SoundEngine_StartEffect. What I can't figure out how to
work around, however, is the popping sound I get when I restart a
sound in the middle of playing. I've tried a variety of timers to
bring the volume down to 0 before restarting (including the
fadeOutSound timer from TouchFighter) but none seem to have any effect.
At this point, to be honest, I feel like the reduced latency of
SoundEngine is most likely to provide the results I need, but am stuck
on the restart sound artifacts. On the other hand, I have those licked
in AudioQueue but have unacceptable latency issues and am still
crashing.
Needless to say, I would really appreciate any help you (or anyone
else) can give me with this. If you need any more details, just let me
know.
Craig
On Oct 22, 2008, at 6:48 PM, Craig Patchett wrote:
That's fair...this is my first post to the list so I wasn't really
sure what was expected. I'll post later tonight with a complete
rundown of what I've tried and what's not working.
Craig
On Oct 22, 2008, at 6:02 PM, William Stewart wrote:
I understand your frustration.
However, we can't fix bugs if we are just going to get random
comments about "i've tried this and blah happens". I know that
sucks, but we aren't prescient.
A good procedure to follow is to have an example - lets say you
start with speak here or aqplay - and you modify it in some way to
do what you want it to do. it doesn't work. A simple post to
describe what you tried to do and why it didn't work is not a bad
starting point. If we get to the point that what we think you are
doing should work, then we would have you file a bug and attach
some code so that we can see the problem happening and then
understand it.
I really have no idea what to do with these kinds of complaints
though - I know it sounds obvious to you, but to me what you have
changed/done to do this is completely opaque.
Bill
On Oct 20, 2008, at 8:33 PM, Craig Patchett wrote:
I'm trying to do the same thing and am having all kinds of
problems. Would it be possible for someone to provide a code
solution or a summary of what changes need to be made in order to
replay a queue without reinitializing it? Specifically:
- How to restart a queue after it has finished playing
- How to restart a queue that is currently playing
It seems like it should be simple to do, and perhaps it is for
someone with a lot of experience with CoreAudio, but finding the
right combination of method calls is approaching black magic for
me! Specifically I've run into the following problems:
- No sound after the queue has played all the way through (like
Romain describes)
- The sound not playing properly the second time through (usually
with an echo of some sort)
- Various crashes and freezes that seem to be related to locking
issue
- A pop when the sound is restarted during playback
I've come up with various combinations of ideas that end up
resolving one or two of these problems but have yet to come up
with something that solves them all. I've spent enough time in
both the SpeakHere sample code and the AudioQueue guide sample
code that I understand what's going on in the code, but the behind-
the-scenes behavior of the various AudioQueue calls seems to be
what's giving me trouble.
I've spent more time than I care to admit trying to come up with a
solution to this and would really appreciate any help. At this
stage I'm even willing to put my money where my mouth is and offer
$100 for a working, coded solution.
Thanks.
Craig
On Oct 20, 2008, at 11:08 AM, Romain Pechayre wrote:
Hello,
I am new to CoreAudio Programming and I have a problem with an
AudioQueue. I use it to play a simple short sound but I need to
control the volume, that is why I don't use SystemSounds instead.
I am trying to play an audioqueue without having to initialize it
from scratch every time I use it. For example, I don't want to
open the associated file every time I play the sound.
To do so, I have tried to customize the playBackCallback function
from SpeakHere iPhone sample code. It is pretty much the same as
the one used in AudioQueue Services Programming guide. I have
just set mCurrentPacket to 0 every time I call the callback
function. It seems to work well because it reads the same number
of packets with audiofileReadPackets everytime I call it. The
problem is that the sound is actually played only when I call
AudioQueueStart for the first time.
To be more specific, I have a button that is supposed to play a
sound when I press it. It works when I press it for the first
time but it does not as of the second time. I have tried
debugging a number of parameters including everything I could in
the callback function, and the behavour seems to be the same
except that the sound is actully played only at the first attempt.
I was therefore wondering if is technically possible to play an
AudioQueue again and again without having to initialize it from
scratch ( which means calling
CFURLCreateFromFileSystemRepresentation and AudioQueueNewOutput ).
I hope the formulation of my question is not too bad and you will
be able to help me.
Kind regards
Romain Pechayre
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden