Unity Web Player | audio_timing
[System.Serializable]
public class Instrument {
public AudioClip sound;
public double freq = 1, offset = 0;
public float amp = 0.6f;
public bool mute = true;
private double nextTime;
private double tempo_spb;
private AudioSource[] audio;
private int audioIndex = 0;
public void Init(GameObject gameObject, double startTime, double tempo_spb) {
this.tempo_spb = tempo_spb;
nextTime = startTime + offset * tempo_spb;
// double buffering two AudioSources enable PlayScheduled without clipping old sound
audio = new AudioSource[2];
for (int n = 0; n < 2; ++n) {
audio[n] = gameObject.AddComponent<AudioSource>();
audio[n].clip = sound;
audio[n].volume = 0f;
}
}
public void Update(double time, double bufferTime) {
audio[audioIndex].volume = amp * (mute ? 0f : 1f);
if (time + bufferTime > nextTime) {
audioIndex = (audioIndex + 1) % 2;
audio[audioIndex].PlayScheduled(nextTime);
nextTime += freq * tempo_spb;
}
}
}
public class Sequencer : MonoBehaviour {
public double tempo_bpm = 140;
public Instrument[] loops;
public double bufferTime = 0.2;
private double tempo_spb;
void Start () {
tempo_spb = 60.0 / (tempo_bpm * 4);
double startTime = AudioSettings.dspTime + bufferTime;
for (int n = 0, c = loops.Length; n < c; ++n)
loops[n].Init(gameObject, startTime, tempo_spb);
}
void Update () {
for (int n = 0, c = loops.Length; n < c; ++n)
loops[n].Update(AudioSettings.dspTime, bufferTime);
}
}