How do I get the current volume level (amplitude) of playing audio (not the set volume but how loud it is)

How do I get the current volume level (amplitude) of playing audio (not the set volume but how loud it is)?

There doesn’t seem to be an obvious function to get this value. I really just want a simple float value that I can set a mouth blend shape value to - so I can approximate talking, while a character speaks.

I know it might not look perfect but at least the loader the speech the more the mouth will open, and with most speech patterns the volume goes up and down and so will approximate the mouth opening and closing.

You can use AudioClip.GetData to get what you need. Just write a script like this:

using UnityEngine;

public class AudioSourceLoudnessTester : MonoBehaviour {

	public AudioSource audioSource;
	public float updateStep = 0.1f;
	public int sampleDataLength = 1024;

	private float currentUpdateTime = 0f;

	private float clipLoudness;
	private float[] clipSampleData;

	// Use this for initialization
	void Awake () {
	
		if (!audioSource) {
			Debug.LogError(GetType() + ".Awake: there was no audioSource set.");
		}
		clipSampleData = new float[sampleDataLength];

	}
	
	// Update is called once per frame
	void Update () {
	
		currentUpdateTime += Time.deltaTime;
		if (currentUpdateTime >= updateStep) {
			currentUpdateTime = 0f;
			audioSource.clip.GetData(clipSampleData, audioSource.timeSamples); //I read 1024 samples, which is about 80 ms on a 44khz stereo clip, beginning at the current sample position of the clip.
			clipLoudness = 0f;
			foreach (var sample in clipSampleData) {
				clipLoudness += Mathf.Abs(sample);
			}
			clipLoudness /= sampleDataLength; //clipLoudness is what you are looking for
		}

	}

}

I update the loudness value only once every 100ms to keep its CPU usage down, and make sure to declare the float for the sample data globally, since it could annoy the garbage collector, if you declare a huge array and destroy it again every update step.

Hi, I know this is an ancient thread, but is there a way to isolate the amplitude of the volume of different “stems” or frequency ranges with something like a low-pass filter that the user will never hear?

I slightly modified the script to edit the emission color on a material based on the current amplitude. Still, I would like to change different materials based on different instruments and avoid increasing filesize with different audio files.

Thanks,
Mark.

I used this :slight_smile:

Thanks

Do you know what happens if you have a sample size of 4 or 8 rather than 1024? Do the values match on average?

Hi I am having trouble trying to implement your code with an audio source with no clip attached with the AudioSource.GetOutputData(). but I keep getting errors? I have the audio coming from a live source and need to monitor the volume. @Chris_Entropy Thanks!