Created
July 30, 2017 12:57
-
-
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
This file contains hidden or 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 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); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks to nfriedly for the sample code that helped me find the solution: https://gist.github.com/nfriedly/0240e862901474a9447a600e5795d500