16块的音频可视化,参考了https://blog.csdn.net/noEnoughChief/article/details/82984635
效果:
第一种:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(AudioSource))]
public class AudioVisable : MonoBehaviour {
AudioSource audioSource;
float[] samples = new float[1024];//每个采样约20Hz
public static float[] freqBand = new float[16];
int[] sampleCount = {1,2,4,8,10,12,15,17,20,22,25,27,30,70,100,250,500,1000};//区块之间的分割数
public static float[] bandBuffer = new float[16];//缓冲区以减缓过于跳跃的变化
float[] bufferDecrease = new float[16];//柱子的下降速度
float[] freqBandHighest = new float[16];
public static float[] audioBandBuffer = new float[16];
void Start () {
audioSource = GetComponent<AudioSource>();
}
void CreateAudioBands()
{
for (int i = 0; i < 16; i++)
{
if (freqBand[i] > freqBandHighest[i])
{
freqBandHighest[i] = freqBand[i];
}
audioBandBuffer[i] = (bandBuffer[i]/freqBandHighest[i]);
}
}
void Update () {
GetSpectrumAduioSource();
MakeFrequencyBands();
Buffer();
CreateAudioBands();
Debug.Log(freqBand[14]);
}
void GetSpectrumAduioSource()
{
audioSource.GetSpectrumData(samples, 0, FFTWindow.Hanning);
}
void Buffer()
{
for (int g = 0; g < 16; g++)
{
if (freqBand[g] > bandBuffer[g])//升高:高于缓冲器中的高度时
{
bandBuffer[g] = freqBand[g];
bufferDecrease[g] = 0.005f;
}
if (freqBand[g] < bandBuffer[g])//低于:低于缓冲器中的高度时
{
bandBuffer[g] -= bufferDecrease[g];
bufferDecrease[g] *= 1.2f;//每一帧以0.005f * 1.2f 的速度下降
}
}
}
void MakeFrequencyBands()
{
int count = 0;
for (int i = 0; i < 16; i++)//16个块划分
{
float average = 0; //每计算一个band清空一次average
for (int j = 0; j < sampleCount[i]; j++)
{
// average += samples[count]*(count+1);
average += samples[count]*count;
count++;
}
average /= count;
freqBand[i] = average * 10;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParamCube : MonoBehaviour {
public int band;
public float StartScale, MaxScale;
void Start () {
// material = GetComponent().materials[0];
}
// Update is called once per frame
void Update ()
{
transform.localScale = new Vector3(transform.localScale.x, (AudioVisable.freqBand[band]) * MaxScale + StartScale, transform.localScale.z);
}
}
第二种:波动随声音变化明显
由于Buffer函数的存在,在Android上显示效果不好,波动不明显。故进行了修改,在ParamCube里又添加了MaxHeight控制长方形的最大高度。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(AudioSource))]
public class AudioVisable : MonoBehaviour {
AudioSource audioSource;
float[] samples = new float[1024];//每个采样约20Hz
public static float[] freqBand = new float[16];
int[] sampleCount = {1,2,4,8,10,12,15,17,20,22,25,27,30,70,100,250,500,1000};//区块之间的分割数
public static float[] bandBuffer = new float[16];//缓冲区以减缓过于跳跃的变化
float[] bufferDecrease = new float[16];//柱子的下降速度
float[] freqBandHighest = new float[16];
public static float[] audioBandBuffer = new float[16];
void Start () {
audioSource = GetComponent<AudioSource>();
}
void CreateAudioBands()
{
for (int i = 0; i < 16; i++)
{
if (freqBand[i] > freqBandHighest[i])
{
freqBandHighest[i] = freqBand[i];
}
audioBandBuffer[i] = (bandBuffer[i]/freqBandHighest[i]);
}
}
void Update () {
GetSpectrumAduioSource();
MakeFrequencyBands();
Buffer();
CreateAudioBands();
Debug.Log(freqBand[14]);
}
void GetSpectrumAduioSource()
{
audioSource.GetSpectrumData(samples, 0, FFTWindow.Hanning);
}
void Buffer()//在安卓上效果不好
{
for (int g = 0; g < 16; g++)
{
if (freqBand[g] > bandBuffer[g])//升高:高于缓冲器中的高度时
{
bandBuffer[g] = freqBand[g];
// bufferDecrease[g] = 0.005f;
}
// if (freqBand[g] < bandBuffer[g])//低于:低于缓冲器中的高度时
// {
// bandBuffer[g] -= bufferDecrease[g];
// bufferDecrease[g] *= 1.2f;//每一帧以0.005f * 1.2f 的速度下降
// }
}
}
void MakeFrequencyBands()
{
int count = 0;
for (int i = 0; i < 16; i++)//16个块划分
{
float average = 0; //每计算一个band清空一次average
for (int j = 0; j < sampleCount[i]; j++)
{
// average += samples[count]*(count+1);
average += samples[count]*count;
count++;
}
average /= count;
freqBand[i] = average * 10;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParamCube : MonoBehaviour {
public int band;
public float StartScale, MaxScale;
public float MaxHeight;
void Start () {
// material = GetComponent().materials[0];
}
// Update is called once per frame
void Update ()
{
if(AudioVisable.freqBand[band] > MaxHeight)
{
AudioVisable.freqBand[band] = MaxHeight;
}
transform.localScale = new Vector3(transform.localScale.x, (AudioVisable.freqBand[band]) * MaxScale + StartScale, transform.localScale.z);
}
}
大家可以比较使用。