Since music plays such an important roll in Ephemerid, a custom system was written for handling audio in Unity. It has been through several iterations, and I thought it would be helpful to share the current state of its implementation here. If you’re doing anything with either musical timing or looping in Unity, you may find some helpful information below.
Note: Ephemerid is being developed in Unity 3.5.X. Most of the techniques below are still relevant in 4.X, but I will try to specify anywhere there have been changes/improvements in 4.X.
Audio Manager
Before doing anything else, if your project depends on music timing, then it’s a good idea to set the “DSPBuffer Size”. In Unity, go to Edit->Project Settings->Audio, and change DPSBuffer Size to “Best Latency”
With this set, Unity will choose the smallest appropriate DSP buffer size depending on the build target. This means that the actual chunks of audio sent to the DSP will be smaller, and you will get more fine-grained feedback from audioSource.time
Music Timing and Tweening
The tweening system in Ephemerid was written from the start with the intention of being driven by music. When a Tween is created, it looks for a default “Stepper” class, and adds itself to it. The Stepper class provides timings to its tweens. In almost all Ephemerid scenes the concrete Stepper class is a MusicStepper.
MusicStepper
MusicStepper is a fairly simple class that acts as a director of all audio tracks (handled by AudioPlayer described below) in the scene. These are the key jobs of MusicStepper:
If audio is playing, it uses that timing
When a track completes, it progresses to the next track
If there is no audio playing, it calculates the timing based on a specified BPM and Unity’s deltaTime
AudioPlayer
This is where it gets interesting. AudioPlayer provides the delta times to a MusicStepper. There are several ways to do rhythm timing in Unity:
Option 1.
Calculate the beats passed by using Unity’s deltaTime and a specified BPM (which is converted to beatsPerSecond at creation)
beatDelta = Time.deltaTime * beatsPerSecond
Option 2.
Monitor the current AudioSource’s time, and calculate the delta beats based strictly on how it changes. The “time” property of AudioSource is used to get audioTime and previousAudioTime. †
beatDelta = (audioTime - previousAudioTime) * beatsPerSecond
Option 3.
A combination of 1 and 2. Use 1 as long as it doesn’t deviate too far from the audio timing. When it deviates, account for the error.
Ephemerid uses method 3 in order to avoid things like timing differences from the particle system, but the method used should be chosen based on your specific project needs.
In the next update to this article, I’ll go into further detail on how AudioPlayer handles looping and defining events at specific beats in a song.
† In Unity 4.X, you can get the actual DSP time from AudioSettings.dspTime. While I haven’t had a chance to experiment, this is probably better than AudioSource.time for calculating beats passed.
Thanks! We’ve actually talked with some folks at Sony in the past about Vita possibilities. Now that Unity will formally support it, we can think about it more seriously. We’d love to be on Vita and PC, it’s just a matter of doing what we can as a two person team.
Haven’t heard back from Sony yet about getting them a copy of our demo. It’s a bit of a strange time with Sony, as you could imagine. They’re busy with PS4 stuff, and while it seems they’re reaching out to indies more than ever, that also means it may be a little harder to grab their attention. We’ll see.
Hi everyone. Cool news: Ephemerid is about 85% complete, and we’re starting our “open” beta phase.
We’re using TestFlight, which is the defacto method for testing iOS games. If you have an iPad 2 or newer (3/4/mini) and would like to try it out, sign up here