- Home /
AudioClip Precise Timing and Delay
Hi, I'm trying to create sequence player that will play a series of notes a-g given in arrays. The problem is we need very precise timing to get this to work and sound properly. I've got something that works but there are still a few issues:
a slight delay between when the first audio clip in a sequence is played and the second. However, after that the 3rd and 4th all play without delay.
over time things seem to eventually skew away from the timing when played against a metronome track
The audio files are 48000 Hz MPEG files and the platform is iOS and Android
Thanks for any help in advance
This is the sequencer's update function:
void Update()
{
if (!currentlyPlaying) {
return;
}
//Get Music Time
float time = AudioManager.MusicTime();
Sequence sequence = sequences[sequenceIndex];
//For each player
for (int i = 0; i < sequence.tracks.Length; i++) {
SequenceTrack track = sequence.tracks[i];
//Apply notes from another track if the current track is empty. Ensures that all 4 tracks are always played.
//Have to check each track in case the players changed from the default instruments.
if (track.notes.Count <= 0 && !testGui) {
for (int k = 0; k < sequence.tracks.Length; k++) {
if (sequence.tracks[k].notes.Count > 0) {
track.notes = sequence.tracks[k].notes;
break;
}
}
}
//Skip this track if it is invalid or not filled with notes
if (track.notes.Count <= 0 || track.mapIndex < 0 || track.mapIndex >= sequenceMaps.Length) {
continue;
}
SequenceMap map = sequenceMaps[track.mapIndex];
//Find the current interval
SequenceTrackInterval interval = null;
for (int j = 0; j < map.intervals.Length; j++) {
if (time >= map.intervals[j].start && time < map.intervals[j].finish) {
interval = map.intervals[j];
break;
}
}
//Continue to next track if we didn't find a valid interval
if (interval == null) {
continue;
}
//Set first note at start of next interval if we're not inside the interval yet
if (track.noteTimer < interval.start) {
track.noteTimer = interval.start;
}
time = AudioManager.MusicTime();
//Get Next note time
float timeTillNextNote = track.noteTimer - time;
//Schedule next note to play if we're within a certain time interval of it
if (timeTillNextNote < 1.0f) {
//Get the next note for this track
string note = track.notes[track.noteCounter] as string;
//These calls eventually call the PlayNote function below
if (timeTillNextNote <= 0) {
AudioManager.PlayNoteUsingInstrument(track.instrument, note);
} else {
AudioManager.PlayNoteUsingInstrument(track.instrument, note, timeTillNextNote);
}
float noteInterval = AudioManager.InstrumentIntervalForNote(track.instrument, note);
track.noteTimer += noteInterval;
track.noteCounter = (track.noteCounter + 1) % track.notes.Count;
}
}
//Check if we've looped around or stopped playing
if (time < currentPlayTime || !AudioManager.IsPlaying()) {
currentlyPlaying = false;
AudioManager.PopMusic();
}
currentPlayTime = time;
}
//Delay given in seconds
static public void PlayNote(AudioClip clip, float delay)
{
ulong delayInSamples = (ulong)Mathf.RoundToInt(clip.frequency * delay);
AudioSource source = null;
//Get an unused audio source
if (sharedInstance.audioSourceQueue.Count > 0) {
source = sharedInstance.audioSourceQueue.Dequeue();
} else {
//Create a new source if there are no audio sources available
source = sharedInstance.gameObject.AddComponent<AudioSource>();
}
if (source.isPlaying) {
Debug.LogWarning("Playing on source that is already playing");
}
source.clip = clip;
source.Play(delayInSamples);
//Add source to IsPlaying Queue
sharedInstance.isPlayingQueue.Enqueue(source);
}
Answer by kramcomposer · Mar 08, 2013 at 08:08 AM
I've personally noticed to give your scene about 1-2 seconds to fully load up to play audio or you get the symptom your getting now. An easy way to do this is to do this:
private bool sceneNotStarted = true;
private void Start(){
invoke("sceneStarted",1f);
}
private void sceneStarted(){
sceneNotStarted = false;
}
private void Update(){
if(sceneNotStarted) return;
//Your Code Here.....
}
Your answer
Follow this Question
Related Questions
Music will not change when an event triggers it 3 Answers
Unity Unable to Reassign Audio Clip 1 Answer
Event at audio position? 1 Answer
Dynamic Backgroundmusic 1 Answer
Audio sync with explosions 1 Answer