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(); } } }