Last active
August 20, 2019 06:50
-
-
Save troy-lamerton/bb456504cc5c9271ecbbe22bf8f9300e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Dissonance.Audio.Capture; | |
using NAudio.Wave; | |
using UnityEngine; | |
/// <summary> | |
/// Microphone that connects to discord bot. It plays the audio it receives from the bot. | |
/// </summary> | |
public class UdpMicrophone : MonoBehaviour, IMicrophoneCapture { | |
private readonly WaveFormat formatFromDiscord = new WaveFormat(48000, 2); | |
private readonly List<IMicrophoneSubscriber> Listeners; | |
private readonly Queue<ArraySegment<float>> CapturedAudio; | |
private UdpUser client; | |
public UdpMicrophone() { | |
Listeners = new List<IMicrophoneSubscriber>(); | |
CapturedAudio = new Queue<ArraySegment<float>>(); | |
} | |
public bool IsRecording { get; private set; } | |
public TimeSpan Latency => TimeSpan.FromMilliseconds(10); | |
public WaveFormat StartCapture(string name) { | |
// todo: connect to discordbot's udp server | |
IsRecording = true; | |
ConnectToDiscordBot(); | |
return formatFromDiscord; | |
} | |
public void ConnectToDiscordBot() { | |
// open udp connection to the discord bot | |
// todo (possibly): use named pipe to communicate with bot process when a udp connection cant be made | |
Debug.Log("Connecting to discord bot's udp server..."); | |
client = UdpUser.ConnectTo("127.0.0.1", 9050); | |
Task.Factory.StartNew(async () => { | |
// connect to server wait for reply messages from server and send | |
Debug.Log("Sending hello to udp server"); | |
client.SendString("I am unity"); | |
try { | |
while (true) { | |
// wait for data from discord | |
var received = await client.Receive(); | |
byte[] data = received.Data; | |
if (data.Length < 10) { | |
Debug.Log($"Server says: {Encoding.ASCII.GetString(data)}"); | |
continue; | |
} | |
Debug.Log($"Got {data.Length} bytes"); | |
// create a float array and copy the bytes into it | |
var voiceData = new float[data.Length / 4]; | |
Buffer.BlockCopy(data, 0, voiceData, 0, data.Length); | |
// voiceData is ready for dissonance | |
CapturedAudio.Enqueue(new ArraySegment<float>(voiceData)); | |
} | |
} catch (Exception ex) { | |
Debug.LogException(ex); | |
} | |
}); | |
} | |
public void StopCapture() { | |
IsRecording = false; | |
} | |
public void Subscribe(IMicrophoneSubscriber listener) { | |
Listeners.Add(listener); | |
} | |
public bool Unsubscribe(IMicrophoneSubscriber listener) { | |
return Listeners.Remove(listener); | |
} | |
public bool UpdateSubscribers() { | |
if (CapturedAudio.Count == 0) return false; | |
var audioSample = CapturedAudio.Dequeue(); | |
foreach (var subscriber in Listeners) { | |
subscriber.ReceiveMicrophoneData(audioSample, formatFromDiscord); | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment