121 lines
4.7 KiB
C#
Raw Normal View History

2025-09-24 19:24:19 +08:00
using System.Collections.Concurrent;
using UnityEngine;
public class OnlineAudio : MonoBehaviour
{
private AudioClip recording; // <20><><EFBFBD>ڴ洢¼<E6B4A2><C2BC><EFBFBD><EFBFBD> AudioClip <20><><EFBFBD><EFBFBD>
private int lastSample = 0; // <20><>һ<EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD>׷<EFBFBD><D7B7>¼<EFBFBD><C2BC><EFBFBD>ĵ<EFBFBD>ǰλ<C7B0><CEBB>
public static int wave_buffer_collectfrequency = 16000; // <20><><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD>Ϊ 16000 Hz
public static readonly ConcurrentQueue<byte[]> voicebuff = new ConcurrentQueue<byte[]>(); // ʹ<><CAB9> ConcurrentQueue <20>洢 byte[] <20><><EFBFBD>ݣ<EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD>̰߳<DFB3>ȫ
private int bufferLengthSeconds = 10; // <20><><EFBFBD><EFBFBD><E5BBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ϊ 10 <20><>
public bool hasAudio;
public void StartRec()
{
Debug.Log("<22><>ʼ¼<CABC><C2BC>"); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ʼ¼<CABC><C2BC>
// <20><><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD>
int buffnum = voicebuff.Count; // <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int i = 0; i < buffnum; i++)
voicebuff.TryDequeue(out byte[] buff); // <20>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD>
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>˷<EFBFBD><CBB7><EFBFBD><E8B1B8><EFBFBD><EFBFBD>ʼ¼<CABC><C2BC>
string microphoneName = Microphone.devices[0]; // <20><>ȡ<EFBFBD><C8A1>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>˷<EFBFBD><CBB7><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Debug.Log("<22><><EFBFBD>˷<EFBFBD><CBB7>豸"+microphoneName);
recording = Microphone.Start(microphoneName, true, bufferLengthSeconds, wave_buffer_collectfrequency);
// ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD>˷翪ʼ¼<CABC><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>true<75><65><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ϊ bufferLengthSeconds<64><73>1<EFBFBD><EFBFBD><EBA3A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ wave_buffer_collectfrequency<63><79>16000Hz<48><7A>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˷<EFBFBD><CBB7>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>
if (Microphone.IsRecording(microphoneName))
{
Debug.Log(<><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"); // <20><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
}
else
{
Debug.LogError("<22>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>"); // <20><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
}
}
public void StopRec()
{
// ֹͣ¼<D6B9><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ¼<C7B0><C2BC><EFBFBD>
if (Microphone.IsRecording(null)) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>˷<EFBFBD><CBB7><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>
{
Microphone.End(null); // ֹͣ¼<D6B9><C2BC>
}
Debug.Log(<><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ʾ¼<CABE><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
private void Update()
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>˷<EFBFBD><CBB7><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (Microphone.IsRecording(null) && recording != null)
{
int currentSample = Microphone.GetPosition(null); // <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD>˷<EFBFBD><CBB7><EFBFBD>¼<EFBFBD><C2BC>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>
// <20><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><E9BBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¿<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (currentSample > lastSample || currentSample < lastSample)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int samplesToProcess = (currentSample > lastSample) ? currentSample - lastSample : (recording.samples - lastSample + currentSample);
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B4A2>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float[] data = new float[samplesToProcess];
// <20><>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ε<EFBFBD>λ<EFBFBD>ÿ<EFBFBD>ʼ
recording.GetData(data, lastSample);
// <20><><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1> float[] <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ 16-bit PCM <20><>ʽ<EFBFBD><CABD> byte[] <20><><EFBFBD><EFBFBD>
byte[] byteData = ConvertFloatTo16BitPCM(data);
// <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> byte[] <20><><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
voicebuff.Enqueue(byteData);
// <20><><EFBFBD><EFBFBD> lastSample<6C><65>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
lastSample = currentSample;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ʾ<EBA3A8><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ񳬹<C7B7><F1B3ACB9><EFBFBD>ֵ<EFBFBD><D6B5>
//float[] samples = new float[recording.samples]; // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>洢PCM<43><4D><EFBFBD><EFBFBD>
//recording.GetData(samples, 0); // <20><><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>ȡPCM<43><4D><EFBFBD><EFBFBD>
//hasAudio = false;
//foreach (float sample in samples)
//{
// if (Mathf.Abs(sample) > 0.01f) // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>
// {
// hasAudio = true;
// break;
// }
//}
//Debug.Log(hasAudio ? "<22><><EFBFBD><EFBFBD><E2B5BD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>" : "û<>м<EFBFBD><D0BC><EFBFBD><E2B5BD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>");
}
}
// <20><> float[] <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ 16-bit PCM <20><>ʽ<EFBFBD><CABD> byte[] <20><><EFBFBD><EFBFBD>
public static byte[] ConvertFloatTo16BitPCM(float[] samples)
{
// <20><><EFBFBD><EFBFBD> byte[] <20><><EFBFBD><EFBFBD><E9A3AC>СΪ float <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊÿ<CEAA><C3BF> float <20><>Ҫ 2 <20><><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>ʾ
byte[] byteData = new byte[samples.Length * 2];
int byteIndex = 0; // <20><><EFBFBD><EFBFBD>׷<EFBFBD><D7B7> byte[] <20><><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>λ<EFBFBD><CEBB>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD> float <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
foreach (float sample in samples)
{
// <20><> float <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -1.0f <20><> 1.0f ֮<><EFBFBD><E4A3AC>ӳ<EFBFBD>䵽 16-bit <20><><EFBFBD><EFBFBD> (-32768 <20><> 32767)
short intSample = (short)(Mathf.Clamp(sample, -1.0f, 1.0f) * short.MaxValue);
// <20><> 16-bit <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ֽڣ<D6BD><DAA3><EFBFBD><EFBFBD><EFBFBD><E6B4A2> byte[] <20><>
byteData[byteIndex++] = (byte)(intSample & 0xFF); // <20><EFBFBD><E6B4A2><EFBFBD>ֽ<EFBFBD>
byteData[byteIndex++] = (byte)((intSample >> 8) & 0xFF); // <20><EFBFBD><E6B4A2><EFBFBD>ֽ<EFBFBD>
}
return byteData; // <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> byte[] <20><><EFBFBD><EFBFBD>
}
// <20>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public static byte[] Wavedata_Dequeue()
{
byte[] datas;
voicebuff.TryDequeue(out datas); // <20><><EFBFBD>ԴӶ<D4B4><D3B6><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1> byte[] <20><><EFBFBD><EFBFBD>
return datas; // <20><><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
}