Net.Like.Xue.Tokyo/Assets/BITKit/Unity/Scripts/AudioClip/AudioClipUtils.cs

64 lines
2.0 KiB
C#

using System.IO;
using UnityEngine;
namespace Net.BITKit
{
public static class AudioClipUtils
{
public static byte[] AudioClipToWavBytes(AudioClip clip)
{
var samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
var wavData = ConvertToWav(samples, clip.channels, clip.frequency);
return wavData;
}
private static byte[] ConvertToWav(float[] samples, int channels, int sampleRate)
{
var stream = new MemoryStream();
var writer = new BinaryWriter(stream);
var byteRate = sampleRate * channels * 2;
// 写入 WAV 文件头
writer.Write(System.Text.Encoding.ASCII.GetBytes("RIFF"));
writer.Write(0); // placeholder for total file size
writer.Write(System.Text.Encoding.ASCII.GetBytes("WAVE"));
// fmt 块
writer.Write(System.Text.Encoding.ASCII.GetBytes("fmt "));
writer.Write(16); // PCM
writer.Write((short)1); // AudioFormat = PCM
writer.Write((short)channels);
writer.Write(sampleRate);
writer.Write(byteRate);
writer.Write((short)(channels * 2)); // Block align
writer.Write((short)16); // Bits per sample
// data 块
writer.Write(System.Text.Encoding.ASCII.GetBytes("data"));
writer.Write(0); // placeholder for data chunk size
// 写入样本
var sampleCount = samples.Length;
for (var i = 0; i < sampleCount; i++)
{
var intData = (short)(samples[i] * short.MaxValue);
writer.Write(intData);
}
// 回写文件长度
writer.Seek(4, SeekOrigin.Begin);
writer.Write((int)(stream.Length - 8)); // RIFF size
writer.Seek(40, SeekOrigin.Begin);
writer.Write((int)(stream.Length - 44)); // data chunk size
writer.Flush();
return stream.ToArray();
}
}
}