looping with start offset
looping with start offset
- Subject: looping with start offset
- From: Jack Nutting <email@hidden>
- Date: Mon, 21 May 2012 16:12:31 +0200
In my AudioUnit-based iOS app, I have several looping "tracks" that
the user can start and stop at will. Each track is being played with a
FilePlayer audio unit. At first I was simply muting each track's
output (or the mixer's input, I forget which) when the user turned a
track off, but with the number of tracks I have, this became a problem
on single-core devices: The system was spending so much time reading
the audio, even for files that weren't being played, that the main
thread was being starved and the animated display would have a
recurring stutter all the time.
The app has a few dozen audio loops, but at most 7 are being played
simultaneously, so I decided to really stop each track when not in use
by calling AudioUnitReset on it, and starting it each time by
reconfiguring the FilePlayer. In order to make everything sync up, I
need to calculate an offset to the spot where the track should start
playing, something like this:
if (!songIsPlaying) {
// Starting first looping track. Set base time to "now"
songIsPlaying = YES;
songStartTime = hostTime(); // save time for later
startFrame = 0;
} else {
// Starting an additional looping track. Figure out offset.
startSampleTime = hostTime() - songStartTime;
startFrame = startSampleTime * 0.5 / fileAudioFormat.mSampleRate;
}
Then I set up a region like this:
ScheduledAudioFileRegion rgn;
memset (&rgn.mTimeStamp, 0, sizeof(rgn.mTimeStamp));
rgn.mTimeStamp.mFlags = kAudioTimeStampSampleTimeValid;
rgn.mTimeStamp.mSampleTime = 0;
rgn.mCompletionProc = NULL;
rgn.mCompletionProcUserData = NULL;
rgn.mAudioFile = fileID;
rgn.mLoopCount = INT_MAX;
rgn.mStartFrame = startFrame;
rgn.mFramesToPlay = nPackets *
fileAudioFormat.mFramesPerPacket - startFrame;
That's pretty close to what I want, with one major problem: Each loop
restarts not at the beginning of the file, but at startFrame. That's
fine for the first loop of course, but what I really want is for the
FilePlayer to play the file starting at some random offset of my
choosing, then continue looping from the beginning, so that all loops
will be synchronized. I imagine that I can accomplish this by using
mCompletionProc and mCompletionProcUserData, but that seems like a
troublesome way to do it. Is there a simple way to make the FilePlayer
do what I have in mind?
--
// Jack Nutting
// email@hidden
// http://nuthole.com
// http://learncocoa.org
_______________________________________________
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