Skip to content

Instantly share code, notes, and snippets.

@kboek
Created July 30, 2017 12:57
Show Gist options
  • Save kboek/20476c2a03b5e9188edebaace74f9a07 to your computer and use it in GitHub Desktop.
Save kboek/20476c2a03b5e9188edebaace74f9a07 to your computer and use it in GitHub Desktop.
Record from Microphone with NAudio and send to IBM Watson Speech-To-Text
using NAudio.Wave;
using System;
using System.Net.WebSockets;
namespace Raskenlund
{
class Recorder
{
private WaveInEvent waveIn;
private WaveFormat format = new WaveFormat(16000, 16, 1);
private ClientWebSocket ws;
static ArraySegment<byte> openingMessage = new ArraySegment<byte>(Encoding.UTF8.GetBytes(
"{\"action\": \"start\", \"content-type\": \"audio/l16;rate=16000\", \"interim_results\": true, \"timestamps\": true }"
));
static ArraySegment<byte> closingMessage = new ArraySegment<byte>(Encoding.UTF8.GetBytes(
"{\"action\": \"stop\"}"
));
public void StartRecording()
{
waveIn = new WaveInEvent
{
BufferMilliseconds = 50,
DeviceNumber = 0,
WaveFormat = format
};
waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(WaveIn_DataAvailable);
waveIn.RecordingStopped += new EventHandler<StoppedEventArgs>(WaveIn_RecordingStopped);
waveIn.StartRecording();
ws = new ClientWebSocket();
ws.Options.Credentials = new NetworkCredential("username", "password");
await ws.ConnectAsync(new Uri("wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize"), CancellationToken.None);
Task.WaitAll(
HandleResults(ws),
ws.SendAsync(openingMessage, WebSocketMessageType.Text, true, CancellationToken.None)
);
}
public void StopRecording()
{
if (waveIn != null)
waveIn.StopRecording();
if (ws.State == WebSocketState.Open)
{
await ws.SendAsync(closingMessage, WebSocketMessageType.Text, true, CancellationToken.None);
ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close", CancellationToken.None).Wait();
}
}
private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
{
if (ws.State == WebSocketState.Open)
await ws.SendAsync(new ArraySegment<byte>(e.Buffer), WebSocketMessageType.Binary, true, CancellationToken.None);
}
private void WaveIn_RecordingStopped(object sender, StoppedEventArgs e)
{
if (waveIn != null)
waveIn.Dispose();
waveIn = null;
}
private async Task HandleResults(ClientWebSocket ws)
{
var buffer = new byte[1024];
while (true)
{
var segment = new ArraySegment<byte>(buffer);
var result = await ws.ReceiveAsync(segment, CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Close)
{
return;
}
int count = result.Count;
while (!result.EndOfMessage)
{
if (count >= buffer.Length)
{
await ws.CloseAsync(WebSocketCloseStatus.InvalidPayloadData, "That's too long", CancellationToken.None);
return;
}
segment = new ArraySegment<byte>(buffer, count, buffer.Length - count);
result = await ws.ReceiveAsync(segment, CancellationToken.None);
count += result.Count;
}
var message = Encoding.UTF8.GetString(buffer, 0, count);
Console.WriteLine(message);
}
}
}
}
@kboek
Copy link
Author

kboek commented Jul 30, 2017

Thanks to nfriedly for the sample code that helped me find the solution: https://gist.github.com/nfriedly/0240e862901474a9447a600e5795d500

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment