using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; public class AudioAnalyzer : MonoBehaviour { public AudioSource source; public AudioClip audioClip; // Assign your audio clip in the Inspector public LineRenderer lineRenderer; public LineRenderer lineRenderer2; public LineRenderer seeker; public float interval = 0.1f; // Interval in seconds to calculate RMS [SerializeField]public List snapshots = new List(); public bool getData = false; public bool updateJustChart = false; public Vector2 chartMultiplier1; public Vector2 chartMultiplier; public float zoomingYMult = 1f; public float cutoffLevel = 0.05f; public float accelCutoffLevel = 0.05f; public static AudioAnalyzer instance; void Awake(){ instance = this; } public void SetZoomingYMult(float val){ zoomingYMult = val; UpdateLine(); } private void OnValidate() { if(getData) { getData = false; updateData(); } if(updateJustChart) { UpdateLine(); } } public void updateData() { int sampleCount = audioClip.samples * audioClip.channels; float[] samples = new float[sampleCount]; // Extract the audio data bool result = audioClip.GetData(samples, 0); if (result) { snapshots.Clear(); // Number of samples per interval int samplesPerInterval = Mathf.FloorToInt(interval * audioClip.frequency * audioClip.channels); for (int i = 0; i < sampleCount; i += samplesPerInterval) { // Calculate RMS value for the current interval float rms = 0f; int intervalSampleCount = Mathf.Min(samplesPerInterval, sampleCount - i); for (int j = 0; j < intervalSampleCount; j++) { float sample = samples[i + j]; rms += sample * sample; } rms = Mathf.Sqrt(rms / intervalSampleCount); // Calculate the time for the current interval float time = (float)i / (audioClip.frequency * audioClip.channels); // Store the time and volume level in the dictionary //volumeLevels[time] = rms; AudioSnapshot snapshot = new AudioSnapshot() { time = time, loudness=rms }; snapshots.Add(snapshot); } } UpdateLine(); } public void UpdateLine() { lineRenderer.positionCount = snapshots.Count; lineRenderer2.positionCount = snapshots.Count; Vector3[] positions = new Vector3[lineRenderer.positionCount]; Vector3[] accelPositions = new Vector3[lineRenderer.positionCount]; for(int i =0; i < snapshots.Count; i++) { //positions[i] = new Vector3(snapshots[i].time * chartMultiplier.x, snapshots[i].loudness > cutoffLevel ? snapshots[i].loudness * chartMultiplier.y : 0); positions[i] = new Vector3(snapshots[i].time * chartMultiplier1.x, snapshots[i].loudness * chartMultiplier1.y * zoomingYMult); float accel = i < 1 ? 0 : (snapshots[i].loudness - snapshots[i - 1].loudness); accelPositions[i] = new Vector3(snapshots[i].time * chartMultiplier.x, (accel > accelCutoffLevel ? accelCutoffLevel : 0)* chartMultiplier.y * zoomingYMult); } lineRenderer.SetPositions(positions); lineRenderer2.SetPositions(accelPositions); seeker.positionCount = 2; } private void Start() { source.clip = audioClip; // source.Play(); } Vector3[] seekerPositions = new Vector3[] {Vector3.zero, Vector3.zero}; private void FixedUpdate() { chartMultiplier.x = zoomingYMult; chartMultiplier1.x = zoomingYMult; seekerPositions[1] = new Vector3(source.time * AudioAnalyzer.instance.zoomingYMult, 0); seeker.SetPositions(seekerPositions); } } [System.Serializable] public class AudioSnapshot { public float time; public float loudness; }