Re: looping with start offset
Re: looping with start offset
- Subject: Re: looping with start offset
- From: Aran Mulholland <email@hidden>
- Date: Tue, 22 May 2012 10:00:22 +1000
The scheduledAudioFileRegion has an mTimeStamp property. I'm pretty
sure that is possible to schedule multiple regions to play. So when
starting from the middle of a loop you could schedule two regions, one
that plays from the current track position until the end of the loop
and another to play at the end time of the first region that plays the
whole region and loops it.
From my reading of the docs (aka AudioUnitProperties.h) the
mCompletionProc is "called when it has been completely scheduled for
reading from disk" (not when the region has completed playing) - so I
don't think that will give you what you need.
On Tue, May 22, 2012 at 12:12 AM, Jack Nutting <email@hidden> wrote:
> 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
_______________________________________________
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