/// <summary> /// Establishes socket connected with the server /// </summary> /// <returns>Whether the socket can attempt to connect. Usually returns true when the service has not been authenticated</returns> public bool Connect() { if (Status == BingStatus.Idle || !Auth.IsValid()) { TryLogError("Could not connect. Not authorized"); return(false); } m_Socket.CustomHeaders = new Dictionary <string, string> { { "X-ConnectionId", BingUtils.GetNewRequestID() }, { "Authorization", "Bearer " + Auth.Token } }; TryLog("Connecting..."); Status = BingStatus.Connecting; m_Socket.ConnectAsync( () => { TryLog("Connected"); Status = BingStatus.Connected; }, exception => { TryLogError("Could not connect: " + exception); Status = BingStatus.Authenticated; } ); return(true); }
void OnSocketMessage(object sender, MessageEventArgs e) { var parser = new MessageParser(e.Data); var message = parser.GetObject(); // All events are fired from the main thread Dispatcher.Enqueue(() => { OnGetMessage.TryInvoke(message); switch (parser.Path.ToLower()) { case "turn.start": OnTurnStart.TryInvoke(message as TurnStartMessage); break; case "turn.end": m_Socket.Send(BingUtils.TurnEndAcknowledgement()); m_Buffer = new byte[0]; OnTurnEnd.TryInvoke(message as TurnEndMessage); Status = BingStatus.Disconnecting; m_Socket.CloseAsync(() => { Connect(); }); break; case "speech.enddetected": OnSpeechEndDetected.TryInvoke(message as SpeechEndDetectedMessage); break; case "speech.phrase": OnSpeechPhrase.TryInvoke(message as SpeechPhraseMessage); break; case "speech.hypothesis": OnSpeechHypothesis.TryInvoke(message as SpeechHypothesisMessage); break; case "speech.startdetected": OnSpeechStartDetected.TryInvoke(message as SpeechStartDetectedMessage); break; case "speech.fragment": OnSpeechFragment.TryInvoke(message as SpeechFragmentMessage); break; } }); }
/// <summary> /// Adds the audio sample to the packet for streaming. /// </summary> /// <param name="sample">The audio sample to be streamed</param> /// <returns>True if this frame lead to completion of a packet that got sent</returns> public bool Stream(byte[] sample) { if (sample.Length == 0) { return(false); } if (Status < BingStatus.Connected) { return(false); } if (Status == BingStatus.Connected) { Status = BingStatus.Streaming; // Before we stream the audio, we must once send the speechConfig var config = BingUtils.GetConfig(m_RequestId); m_Socket.Send(config); } var freeBytes = 8192 - m_Header.Length; m_Buffer = m_Buffer.Concat(sample).ToArray(); // If we can not add more to the buffer if (m_Buffer.Length + sample.Length < freeBytes) { return(true); } // We require 8192 bytes to data. After adding header and audio data, we may still have some bytes left // We fill them up with empty/blank bytes and send via the socket. The blank is small enough that the service will // not think of it as microphone silence var blankLen = 8192 - m_Header.Length - m_Buffer.Length; var packet = m_Header.Concat(m_Buffer).Concat(new byte[blankLen]).ToArray(); try { m_Socket.Send(packet); } catch { } m_Buffer = new byte[0]; return(true); }
/// <summary> /// Request authentication so that the client can communicate with the server /// </summary> /// <param name="key">The Bing Speech to Text API key</param> /// <param name="callback">Bool callback for whether the authentication was successful</param> public void Authenticate(string key, Action <string> onSuccess, Action <Exception> onFailure) { TryLog("Authenticating"); Auth = new BingAuthorization(key); Status = BingStatus.Authenticating; Auth.FetchToken( token => { TryLog("Authorized: " + token); Status = BingStatus.Authenticated; m_RequestId = BingUtils.GetNewRequestID(); m_Header = BingUtils.GetHeader(m_RequestId); onSuccess.TryInvoke(token); }, exception => { TryLogError(exception); Status = BingStatus.Idle; onFailure.TryInvoke(exception); } ); }