Unity AudioClip序列化及压缩

不废话直接上代码,扔项目里就能用

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

public static class Extension
{
    //CSDN、BiliBili 似乎有个人

    /// <summary>
    /// 序列化
    /// </summary>
    public static byte[] ToByteArray(this AudioClip audioClip)
    {
        List<byte> byteList = new List<byte>();

        //编码name
        byte[] nameByte = System.Text.Encoding.UTF8.GetBytes(audioClip.name);
        byte[] nameByteLength = BitConverter.GetBytes(nameByte.Length);
        byteList.AddRange(nameByteLength);                                      //4字节nameLength
        byteList.AddRange(nameByte);                                            //nameLength字节name

        //编码samples
        byte[] samplesByte = BitConverter.GetBytes(audioClip.samples);          //4字节sample
        byteList.AddRange(samplesByte);

        //编码channels
        byte[] channelsByte = BitConverter.GetBytes(audioClip.channels);        //4字节channels
        byteList.AddRange(channelsByte);

        //编码frequency
        byte[] frequencyByte = BitConverter.GetBytes(audioClip.frequency);      //4字节frequency
        byteList.AddRange(frequencyByte);

        //编码_3D
        byte[] _3DByte = BitConverter.GetBytes(audioClip.ambisonic);            //1字节_3D
        byteList.AddRange(_3DByte);

        //编码data
        int dataLength = audioClip.samples * audioClip.channels;

        float[] data = new float[dataLength];
        audioClip.GetData(data, 0);

        int dataByteLength = data.Length * 2;                                   //1个float转1个short,而1个short是2字节,这里相当于压缩了空间
        byte[] dataByteLengthByte = BitConverter.GetBytes(dataByteLength);      //4字节dataLength
        byteList.AddRange(dataByteLengthByte);

        foreach (float f in data)                                               //dataLength字节data
        {
            short temp = (short)(f * short.MaxValue);

            byte[] byteArrTemp = BitConverter.GetBytes(temp);

            byteList.AddRange(byteArrTemp);
        }

        return byteList.ToArray();
    }

    /// <summary>
    /// 反序列化
    /// </summary>
    public static AudioClip ParseAudioClip(byte[] byteArray, int startIndex, out int endIndex)
    {
        int offset = startIndex;

        //解码nameLength,4字节
        int nameLength = BitConverter.ToInt32(byteArray, offset);
        offset += 4;

        //解码name,nameLength字节
        string name = System.Text.Encoding.UTF8.GetString(byteArray, offset, nameLength);
        offset += nameLength;


        //解码samples,4字节
        int samples = BitConverter.ToInt32(byteArray, offset);
        offset += 4;

        //解码channels,4字节
        int channels = BitConverter.ToInt32(byteArray, offset);
        offset += 4;

        //解码frequency,4字节
        int frequency = BitConverter.ToInt32(byteArray, offset);
        offset += 4;

        //解码_3D,1字节
        bool _3D = BitConverter.ToBoolean(byteArray, offset);
        offset += 1;

        //解码dataLength,4字节
        int dataLength = BitConverter.ToInt32(byteArray, offset);
        offset += 4;

        float[] data = new float[dataLength / 2];
        //解码
        for (int i = 0; i < dataLength; i += 2)
        {
            short tempShort = BitConverter.ToInt16(byteArray, offset + i);

            data[i / 2] = (float)tempShort / short.MaxValue;
        }

        offset += dataLength;
        endIndex = offset;

        AudioClip ac = AudioClip.Create(name, samples, channels, frequency, false);
        ac.SetData(data, 0);

        return ac;
    }

    /// <summary>
    /// 多声道改单声道,并压缩为22050
    /// </summary>
    /// <param name="audioClip"></param>
    /// <returns></returns>
    public static AudioClip NormalizedClip(this AudioClip audioClip)
    {
        int newFrequency = 22050;

        if (audioClip.channels == 1 && audioClip.frequency == newFrequency) return audioClip;

        int dataLength = audioClip.samples * audioClip.channels;
        float[] data = new float[dataLength];
        audioClip.GetData(data, 0);

        //压缩比
        float rate = (float)audioClip.frequency * audioClip.channels / newFrequency;
        int newDataLength = (int)(dataLength / rate);

        float[] newData = new float[newDataLength];

        for (int i = 0; i < newData.Length; i++)
        {
            int sampleIndex = (int)(i * rate);

            float f = data[sampleIndex];

            newData[i] = f;
        }

        AudioClip newClip = AudioClip.Create(audioClip.name, newDataLength, 1, newFrequency, false);
        newClip.SetData(newData, 0);

        return newClip;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值