64 lines
2.0 KiB
C#
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();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|