unity学习日记:音频可视化

MP3或者WAV等音频文件里面储存的时数字信号,我们需要读取这些数据 据转化成频谱数据,这样就可以比较直观地使用了。unity为我们提供了AudioListener.GetSpectrumData来直接获取音频的频谱,为我们节省了转码的时间。

语法:public static void GetSpectrumData(float[] samples, int channel, FFTWindow window);

float[] samples:float类型的数组来存放取到的频谱数据,此数组长度必须是2的n次方,最小64,最大8192。

int channel:采样的声道,一般用0。

FFTWindow window:使用FFTWindow以减少bins/bands之间频率泄漏。注意,越复杂的窗口类型,质量越好,但减小速度。

例:

创建项目,在场景内创建一个空物体,位置为(0,0,0),改名为Audio Visualization,为其添加LineRenderer和udioSource组件。创建一个红色材质球,并 赋给LineRenderer。

创建一个cube,创建一个绿色材质球并赋值给cube,拖成预制体cube。编写脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AudioVisualization : MonoBehaviour 
{
    AudioSource audio;//声源
    float[] samples = new float[128];//存放频谱数据的数组长度
    LineRenderer linerenderer;//画线
    public GameObject cube;//cube预制体
    Transform[] cubeTransform;//cube预制体的位置
    Vector3 cubePos;//中间位置,用以对比cube位置与此帧的频谱数据
	// Use this for initialization
	void Start () 
    {
        GameObject tempCube;
        audio = GetComponent<AudioSource>();//获取声源组件
        linerenderer = GetComponent<LineRenderer>();//获取画线组件
        linerenderer.positionCount = samples.Length;//设定线段的片段数量
        cubeTransform = new Transform[samples.Length];//设定数组长度
        //将脚本所挂载的gameobject向左移动,使得生成的物体中心正对摄像机
        transform.position = new Vector3(-samples.Length * 0.5f, transform.position.y, transform.position.z);
        //生成cube,将其位置信息传入cubeTransform数组,并将其设置为脚本所挂载的gameobject的子物体
        for (int i = 0; i < samples.Length; i++)
        {
            tempCube=Instantiate(cube,new Vector3(transform.position.x+i,transform.position.y,transform.position.z),Quaternion.identity);
            cubeTransform[i] = tempCube.transform;
            cubeTransform[i].parent = transform;
        }
	}
	
	// Update is called once per frame
	void Update () 
    {
        //获取频谱
        audio.GetSpectrumData(samples, 0, FFTWindow.BlackmanHarris);
        //循环
        for (int i = 0; i < samples.Length; i++)
        {
            //根据频谱数据设置中间位置的的y的值,根据对应的cubeTransform的位置设置x、z的值
            //使用Mathf.Clamp将中间位置的的y限制在一定范围,避免过大
            //频谱时越向后越小的,为避免后面的数据变化不明显,故在扩大samples[i]时,乘以50+i * i*0.5f
            cubePos.Set(cubeTransform[i].position.x, Mathf.Clamp(samples[i] * ( 50+i * i*0.5f), 0, 100), cubeTransform[i].position.z);
            //画线,为使线不会与cube重合,故高度减一
            linerenderer.SetPosition(i, cubePos-Vector3.up);
            //当cube的y值小于中间位置cubePos的y值时,cube的位置变为cubePos的位置
            if (cubeTransform[i].position.y < cubePos.y)
            {
                cubeTransform[i].position = cubePos;
                
            }
            //当cube的y值大于中间位置cubePos的y值时,cube的位置慢慢向下降落
            else if (cubeTransform[i].position.y > cubePos.y)
            {
                cubeTransform[i].position -= new Vector3(0, 0.5f, 0);
            }
        }
	}
}
将脚本挂在到Audio Visualization上,并将预制体cube赋值给脚本。导入一个音频资源,并将音频资源赋值给audiosouce组件。

播放效果如下:








  • 13
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值