• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
looping with start offset
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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

  • Follow-Ups:
    • Re: looping with start offset
      • From: Richard Dobson <email@hidden>
    • Re: looping with start offset
      • From: Aran Mulholland <email@hidden>
  • Prev by Date: Re: parameter name update
  • Next by Date: Re: Learning Core Audio Example 2.1
  • Previous by thread: Re: Learning Core Audio Example 2.1
  • Next by thread: Re: looping with start offset
  • Index(es):
    • Date
    • Thread