Callback at certain times during audio playback - iphone

Is it possible to play an audio file from the user's ipod library and have a callback occur whenever the player reaches a certain time point ? I need it to be very accurate, so simply using methods like currentPlaybackTime might not be enough because float equality is inaccurate. I could use the A - B < Epsilon float check, but is there a better, more accurate way of achieving this?

If you can target iOS 4.0 or hight, try using AVPlayer. Then you will be able to use
- (id)addBoundaryTimeObserverForTimes:(NSArray *)times queue:(dispatch_queue_t)queue usingBlock:(void (^)(void))block
which takes an array of NSValues for CMTimes and will run the contents of the block each time one of the boundary times is hit. (Beware of some behavior like, if you pause the audio file inside of the block, the callback will fire again when you unpause it).
Since CMTime is not a float, I think this will be more accurate than checking for the currentTime repeatedly.

Related

Unity: Draw frames as fast as it can

I'm trying to create video in Unity game using AVPro. I use Update function to save frame. targetFrameRate matches video frame rate, so it takes 1 minutes to generate video with 1 minute length.
Is it possible to speed up this process? I tried to use timeScale, but video is length is also dependent on that.
You can use Time.captureFramerate = framerate
From the documentation https://docs.unity3d.com/ScriptReference/Time-captureFramerate.html.
If this property has a non-zero value then frame update will occur at
an interval of (1.0 / captureFramerate) regardless of real time and
the time required to render a frame.
To be able to use this method your code must support it with proper use of Time.deltaTime or a corresponding way.

How Do I set multiple File Player Audio Units to start at the same time?

Right now I have a loop that loops through an array of file player audio units and tells them what position in the audio file to start playing. (this works) In this same loop I have the following code to tell the units when to start playing (-1 makes them play in the next render cycle). The problem is that they are not starting at the same time because the first track starts playing before i have had a chance to tell the third track to play. What I want to say is "track one, you play in exactly 5 cycles, Track 2 you play in exactly 4 cycles, Track 3 you play in exactly 3 cycles... etc. that way they play at the same time. Is this the right approach? If so, what value do you set for startTime.mSampleTime ? I have not found any documentation that tells me how to do this. Thanks
// tell the file player AU when to start playing (-1 sample time means next render cycle)
AudioTimeStamp startTime;
memset (&startTime, 0, sizeof(startTime));
startTime.mFlags = kAudioTimeStampSampleTimeValid;
startTime.mSampleTime = -1;
AudioUnitSetProperty(fileUnitArray[mycount], kAudioUnitProperty_ScheduleStartTimeStamp, kAudioUnitScope_Global, 0, &startTime, sizeof(startTime));
I was not able to track down any information on setting mSampleTime to any other value then -1 (i.e start on the next cycle) but I was able to work around the problem. Instead of keeping the AUGraph running, using AudioUnitReset to reset the file player audio unit and then using the code above to restart the file players, I store the current file player play-head position, stop the AUGraph completely, reinitialize the AUGraph with the current play-head position instead of telling it to start at position zero, and then restart the AUGRAPH.
What you need to do is schedule the playback of the audio files from the render thread.
You load the files on a different thread but you tell the files to play in the next render cycle from the render thread. This way all of your files wil start at the same time.

iPhone/iPad sound playback with setCurrentTimeFunction. Non AVAudioPlayer

I've recently been trying to incorporate an intensive sound management class, where sound playback precision is a must.
What I'm looking for is the option to load a sound, set the playback starting position (or playhead), play for a certain time, pause the sound, set the 'playhead' position to a new interval and resume playback again. (with dynamic intervals).
I've tried using AVAudioPlayer for that matter - but it seems it's just too slow. The performance is just not what you expect, it lags when calling pause and setCurrentTime:.
It's the easiest library to use and the only one with stated setCurrentTime: function.
I come here asking for your help, a recommendation for a decent open-source SoundEngine that can handle interval setting (playhead movement) with low latency, or reference to where it is stated that OpenAL or AudioUnit tools can handle playback position setting.
Thank you in advance,
~ Natanavra.
It would be worth your time to check out the openAL programmer's guide that comes with the SDK. Its got all sorts of goodies!
From that:
Under source: Each source generated by alGenSources has properties which can be set or retrieved.
The alSource[f, 3f, fv, i] and alGetSource[f, 3f, fv, i] families of functions can be used to set or retrieve the following source properties:
...
AL_SEC_OFFSET f, fv, i, iv the playback position, expressed in seconds
AL_SAMPLE_OFFSET f, fv, i, iv the playback position, expressed in samples
AL_BYTE_OFFSET f, fv, i, iv the playback position, expressed in bytes
So you can get the playback position in seconds and divide by 60 to get your normalized time.
float pos = 0; alGetSourcef( sourceID, AL_SEC_OFFSET, &pos );
float normalizedPos = pos / 60.0f;
OpenAL definitely has the capabilities to playback sound pause whatever you like. remember OpenAL is often used in games as it delivers sound playback with low latency and on demand playback. You have a lot of control over the sound. compared to the AVAudioPlayer class.
Hope this helps
Do reply
Pk

MPMoviePlayerController: key frame issue

I have a MPMoviePlayerController in my project.
Documentation says that next call:
moviePlayer.initialPlaybackTime = time;
starts at the closest key frame prior to the provided time.
Is it possible to start playing video from the specified time (not from the nearest key frame)?
No, it really isn't. Temporally compressed video streams can only generally start playback on a keyframe, as inter-frames depend on the keyframe for rendering. If seekability is important to you, consider making files with smaller keyframe intervals.

iPhone/iPodTouch. What are my options for syncing movement to a soundtrack?

What are the best strategies for syncing music to object movement? The app I envision would have an underlying soundtrack with characters animating in time to the music. What I'm after is a strategy for having the soundtrack periodic send a message to an object, objects, triggering it to commence it's scripted movement.
Thanks,
Doug
FMOD Ex should allow this sort of thing. It's not built-in, but it's relatively cheap.
The point is writing the object movement code so that it can use external clock signal. You can for example write the movement update method so that it takes a time delta:
- (void) updateMovementBy: (double) seconds {…}
In each loop you’ll poll the soundtrack player for current playback time, compute time delta from the last iteration and update the model. But of course a lot depends on what exactly you want to do in response to the music.