您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
93 行
3.0 KiB
93 行
3.0 KiB
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
using Buffer = System.Buffer;
|
|
|
|
namespace AxelF {
|
|
|
|
public sealed class RecordToFile : MonoBehaviour {
|
|
object _locker = 0;
|
|
Queue<byte[]> _freed = new Queue<byte[]>(8);
|
|
Queue<byte[]> _inuse = new Queue<byte[]>(8);
|
|
List<byte[]> _proc = new List<byte[]>(8);
|
|
BinaryWriter _writer;
|
|
bool _recording;
|
|
|
|
void OnDestroy() {
|
|
StopRecording();
|
|
}
|
|
|
|
public void StartRecording(string path) {
|
|
StopRecording();
|
|
if (!path.EndsWith(".wav"))
|
|
path += ".wav";
|
|
lock (_locker) {
|
|
_writer = new BinaryWriter(new FileStream(path, FileMode.Create));
|
|
for (int i = 0; i < 44; ++i)
|
|
_writer.Write((byte) 0x00);
|
|
_recording = true;
|
|
}
|
|
}
|
|
|
|
public int StopRecording() {
|
|
int len = 0;
|
|
if (_recording)
|
|
lock (_locker) {
|
|
len = (int) _writer.BaseStream.Length;
|
|
_recording = false;
|
|
|
|
short format = 3;
|
|
short channels = 2;
|
|
int sampleRate = AudioSettings.outputSampleRate;
|
|
int byteRate = sampleRate * sizeof(float) * channels;
|
|
short blockAlign = (short) (sizeof(float) * channels);
|
|
short bitsPerSample = (short) (sizeof(float) * 8);
|
|
_writer.Seek(0, SeekOrigin.Begin);
|
|
_writer.Write(Encoding.ASCII.GetBytes("RIFF"));
|
|
_writer.Write((int) (_writer.BaseStream.Length - 8));
|
|
_writer.Write(Encoding.ASCII.GetBytes("WAVE"));
|
|
_writer.Write(Encoding.ASCII.GetBytes("fmt "));
|
|
_writer.Write((int) 16);
|
|
_writer.Write(format);
|
|
_writer.Write(channels);
|
|
_writer.Write(sampleRate);
|
|
_writer.Write(byteRate);
|
|
_writer.Write(blockAlign);
|
|
_writer.Write(bitsPerSample);
|
|
_writer.Write(Encoding.ASCII.GetBytes("data"));
|
|
_writer.Write((int) (_writer.BaseStream.Length - 44));
|
|
_writer.Close();
|
|
}
|
|
return len;
|
|
}
|
|
|
|
void Update() {
|
|
if (_recording) {
|
|
lock (_locker)
|
|
while (_inuse.Count > 0)
|
|
_proc.Add(_inuse.Dequeue());
|
|
foreach (var i in _proc)
|
|
_writer.Write(i);
|
|
lock (_locker)
|
|
foreach (var i in _proc)
|
|
_freed.Enqueue(i);
|
|
_proc.Clear();
|
|
}
|
|
}
|
|
|
|
void OnAudioFilterRead(float[] data, int channels) {
|
|
lock (_locker)
|
|
if (_recording) {
|
|
var buf = _freed.Count > 0 ? _freed.Dequeue() : null;
|
|
if (buf == null || buf.Length != data.Length * sizeof(float))
|
|
buf = new byte[data.Length * sizeof(float)];
|
|
Buffer.BlockCopy(data, 0, buf, 0, buf.Length);
|
|
_inuse.Enqueue(buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
} // AxelF
|
|
|