Skip to content

Instantly share code, notes, and snippets.

@Jesus-QC
Last active May 24, 2022 14:06
Show Gist options
  • Save Jesus-QC/04bc56dc49066d18231beaaf3ecdfb42 to your computer and use it in GitHub Desktop.
Save Jesus-QC/04bc56dc49066d18231beaaf3ecdfb42 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using AudioPlayer.API;
using Dissonance.Audio.Capture;
using NAudio.Wave;
using NLayer;
using UnityEngine;
using Game.Features;
namespace Game.Core.Components
{
// Streaming audio as a fake microphone.
// https://placeholder-software.co.uk/dissonance/docs/Tutorials/Custom-Microphone-Capture.html#step-4-file-streaming
public class CustomMpegMicrophone : MonoBehaviour, IMicrophoneCapture
{
public bool IsRecording { get; private set; }
public TimeSpan Latency { get; private set; }
public MpegFile File;
private readonly List<IMicrophoneSubscriber> _subscribers = new List<IMicrophoneSubscriber>();
private WaveFormat _format = new WaveFormat(44100, 1);
private readonly float[] _frame = new float[980];
private readonly byte[] _frameBytes = new byte[980 * 4];
private float _elapsedTime;
public WaveFormat StartCapture(string micName)
{
_format = new WaveFormat(File.SampleRate, 1);
IsRecording = true;
Latency = TimeSpan.Zero;
return _format;
}
public void StopCapture()
{
if (File == null)
return;
File.Dispose();
File = null;
}
public void Subscribe(IMicrophoneSubscriber listener) => _subscribers.Add(listener);
public bool Unsubscribe(IMicrophoneSubscriber listener) => _subscribers.Remove(listener);
public bool UpdateSubscribers()
{
_elapsedTime += Time.unscaledDeltaTime;
while (_elapsedTime > 0.02f)
{
_elapsedTime -= 0.02f;
// Read bytes from file
var readLength = File.ReadSamples(_frameBytes, 0, _frameBytes.Length);
// Zero the entire buffer so bits not written to will be silent
Array.Clear(_frame, 0, _frame.Length);
// Copy the bytes that were read into the audio buffer as floats
Buffer.BlockCopy(_frameBytes, 0, _frame, 0, readLength);
foreach (var subscriber in _subscribers)
subscriber.ReceiveMicrophoneData(new ArraySegment<float>(_frame), _format);
}
if (File.Position != File.Length)
return false;
if (AudioController.LoopMusic)
File.Position = 0;
else
AudioController.Stop();
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment