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); } }