Skip to content

Instantly share code, notes, and snippets.

@guillefix
Created May 2, 2023 20:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guillefix/a530f2feb8797507ae90437f264a5bf9 to your computer and use it in GitHub Desktop.
Save guillefix/a530f2feb8797507ae90437f264a5bf9 to your computer and use it in GitHub Desktop.
[RequireComponent(typeof(AudioSource))]
public class OpusPlayer : MonoBehaviour
{
private UDPReceiver receiver;
private AudioSource audioSource;
public int sampleRate = 48000;
public int channels = 2;
public int frameSize = 960;
public int bufferLengthInSeconds = 2;
private OpusDecoder decoder;
private float[] audioBuffer;
private int bufferWritePosition = 0;
private int bufferReadPosition = 0;
private bool bufferReady = false;
//AudioRecorderWav audioRecorder;
private object bufferLock = new object();
AudioClip audioClip;
public void StartPlaying(UDPReceiver receiver, AudioSource audioSource)
{
this.receiver = receiver;
this.audioSource = audioSource;
decoder = OpusDecoder.Create(sampleRate, channels);
//audioSource = GetComponent<AudioSource>();
//audioBuffer = new float[sampleRate * channels * bufferLengthInSeconds];
int audioClipLength = sampleRate * channels * bufferLengthInSeconds;
//audioClip = AudioClip.Create("OpusAudio", audioClipLength, channels, sampleRate, false);
//audioSource.clip = audioClip;
audioBuffer = new float[audioClipLength];
//audioRecorder = new AudioRecorderWav("awa.wav", frameSize, 1, sampleRate, channels);
//audioRecorder.StartWriting();
if (receiver != null)
{
receiver.onDataReceived += OnDataReceived;
}
audioSource.Play();
}
public void OnDataReceived(byte[] data)
{
Debug.Log("OnDataReceived " + data.Length);
float[] outputBuffer = new float[frameSize * channels];
if (decoder == null) return;
int decodedSamples = decoder.Decode(data, 0, data.Length, outputBuffer, 0, outputBuffer.Length);
//audioRecorder.ConvertAndWrite(outputBuffer);
Debug.Log("Decoded data");
lock (bufferLock)
{
for (int i = 0; i < decodedSamples; i++)
{
//audioBuffer[bufferWritePosition] = outputBuffer[i] / (float)Int16.MaxValue;
audioBuffer[bufferWritePosition] = outputBuffer[i];
bufferWritePosition = (bufferWritePosition + 1) % audioBuffer.Length;
//if (bufferWritePosition == bufferReadPosition) bufferReadPosition = bufferWritePosition + 1;
}
Debug.Log("Wrote data");
if (!bufferReady && bufferWritePosition >= frameSize * channels)
{
bufferReady = true;
}
}
}
//void Update()
//{
// if (!bufferReady) return;
// lock (bufferLock)
// {
// audioClip.SetData(audioBuffer, 0);
// if (!audioSource.isPlaying)
// audioSource.Play();
// }
//}
void OnAudioFilterRead(float[] data, int channels)
{
if (!bufferReady) return;
if (channels != this.channels) return;
lock (bufferLock)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = audioBuffer[bufferReadPosition];
bufferReadPosition = (bufferReadPosition + 1) % audioBuffer.Length;
}
}
}
private void OnDestroy()
{
//audioRecorder.WriteHeader();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment