This repository has been archived on 2024-11-03. You can view files and clone it, but cannot push or open issues or pull requests.
snakeinabox/Assets/Scripts/Metro.cs
2020-07-09 11:41:01 -07:00

77 lines
No EOL
1.9 KiB
C#

using UnityEngine;
using System.Collections;
// The code example shows how to implement a metronome that procedurally generates the click sounds via the OnAudioFilterRead callback.
// While the game is paused or the suspended, this time will not be updated and sounds playing will be paused. Therefore developers of music scheduling routines do not have to do any rescheduling after the app is unpaused
[RequireComponent(typeof(AudioSource))]
public class Metro : MonoBehaviour
{
[Header("References")]
public Main main;
public bool tick;
public float gain = 0.5F;
public int signatureLo = 4;
private double nextTick = 0.0F;
private float amp = 0.0F;
private float phase = 0.0F;
private double sampleRate = 0.0F;
private bool running = false;
void Start()
{
double startTick = AudioSettings.dspTime;
sampleRate = AudioSettings.outputSampleRate;
nextTick = startTick * sampleRate;
running = true;
}
bool beat;
void Update()
{
if (beat)
{
main.Beat();
beat = false;
}
}
void OnAudioFilterRead(float[] data, int channels)
{
if (!running)
return;
gain = tick ? 0.25f : 0f;
double samplesPerTick = sampleRate * 60.0F / (double)main.BPM() * 4.0F / signatureLo;
double sample = AudioSettings.dspTime * sampleRate;
int dataLen = data.Length / channels;
int n = 0;
while (n < dataLen)
{
float x = gain * amp * Mathf.Sin(phase);
int i = 0;
while (i < channels)
{
data[n * channels + i] += x;
i++;
}
while (sample + n >= nextTick)
{
nextTick += samplesPerTick;
amp = 1.0F;
// if (++accent > signatureHi)
// {
// accent = 1;
// amp *= 2.0F;
// }
// Debug.Log("Tick: " + accent + "/" + signatureHi);
beat = true;
}
phase += amp * 0.3F;
amp *= 0.993F;
n++;
}
}
}