Created
February 2, 2023 08:50
-
-
Save simonziegler/dbb10e287c889ad7d76b0fcc98a29ffb to your computer and use it in GitHub Desktop.
ASP.NET Speech Recognition Service
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 Microsoft.CognitiveServices.Speech; | |
namespace UtilityNamespace; | |
/// <summary> | |
/// A service interface to recognize speech. Intended to be used as a transient service. | |
/// </summary> | |
public interface ISpeechRecognizerService | |
{ | |
/// <summary> | |
/// A continuous speech recognition session. | |
/// </summary> | |
public interface ISession : IDisposable | |
{ | |
/// <summary> | |
/// Stops the session and returns the final speech recognition result. Also disposes of the session, so can only be called once and will throw an exception if called again. | |
/// </summary> | |
/// <returns></returns> | |
public Task<SpeechRecognitionResult> EndSession(); | |
} | |
/// <summary> | |
/// | |
/// </summary> | |
/// <param name="receiveRecognizingText">Action that recevies text that is in the process of being recognized</param> | |
/// <param name="receiveRecognizedText">Action that receives fully recognized/decoded text</param> | |
/// <returns></returns> | |
public Task<ISession> StartNewSession(Func<string, Task> receiveRecognizingText, Func<string, Task> receiveRecognizedText); | |
} |
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 Microsoft.CognitiveServices.Speech; | |
using Microsoft.Extensions.Configuration; | |
using System; | |
using System.Threading.Tasks; | |
using UtilityNamespace; | |
namespace AppNamespace; | |
/// <summary> | |
/// Implements <see cref="ISpeechRecognizerService"/> for UK English using Microsoft Azure speech recognition services. | |
/// </summary> | |
public class SpeechRecognizerService : ISpeechRecognizerService | |
{ | |
private class Session : ISpeechRecognizerService.ISession | |
{ | |
private SpeechRecognizer SpeechRecognizer { get; set; } | |
private SpeechRecognitionResult SpeechRecognitionResult { get; set; } | |
private TaskCompletionSource<int> StopRecognition { get; set; } | |
private bool Disposed { get; set; } | |
public static async Task<ISpeechRecognizerService.ISession> CreateSession(IConfiguration configuration, Func<string, Task> receiveRecognizingText, Func<string, Task> receiveRecognizedText) | |
{ | |
var speechConfig = SpeechConfig.FromSubscription(configuration["SpeechRecognition:SubscriptionKey"], configuration["SpeechRecognition:Region"]); | |
speechConfig.SpeechRecognitionLanguage = configuration["SpeechRecognition:Language"]; | |
speechConfig.EnableDictation(); | |
speechConfig.SetProfanity(ProfanityOption.Removed); | |
Session session = new() | |
{ | |
SpeechRecognizer = new(speechConfig), | |
StopRecognition = new(TaskCreationOptions.RunContinuationsAsynchronously), | |
}; | |
// Subscribes to events. | |
session.SpeechRecognizer.Recognizing += (s, e) => | |
{ | |
receiveRecognizingText(e.Result.Text); | |
}; | |
session.SpeechRecognizer.Recognized += (s, e) => | |
{ | |
receiveRecognizedText(e.Result.Text); | |
session.SpeechRecognitionResult = e.Result; | |
}; | |
session.SpeechRecognizer.Canceled += (s, e) => | |
{ | |
session.StopRecognition.TrySetResult(0); | |
}; | |
session.SpeechRecognizer.SessionStopped += (s, e) => | |
{ | |
session.StopRecognition.TrySetResult(0); | |
}; | |
// Starts continuous recognition. Uses StopContinuousRecognitionAsync() to stop recognition. | |
await session.SpeechRecognizer.StartContinuousRecognitionAsync().ConfigureAwait(false); | |
return session; | |
} | |
public async Task<SpeechRecognitionResult> EndSession() | |
{ | |
if (Disposed) | |
{ | |
throw new ObjectDisposedException(GetType().Name); | |
} | |
// Stops recognition. | |
await SpeechRecognizer.StopContinuousRecognitionAsync().ConfigureAwait(false); | |
// Waits for completion. | |
// Use Task.WaitAny to keep the task rooted. | |
Task.WaitAny(new[] { StopRecognition.Task }); | |
Dispose(); | |
return SpeechRecognitionResult; | |
} | |
protected virtual void Dispose(bool disposing) | |
{ | |
if (!Disposed) | |
{ | |
if (disposing) | |
{ | |
SpeechRecognizer.Dispose(); | |
} | |
Disposed = true; | |
} | |
} | |
public void Dispose() | |
{ | |
Dispose(disposing: true); | |
GC.SuppressFinalize(this); | |
} | |
} | |
private readonly IConfiguration _configuration; | |
public SpeechRecognizerService(IConfiguration configuration) | |
{ | |
_configuration = configuration; | |
} | |
public Task<ISpeechRecognizerService.ISession> StartNewSession(Func<string, Task> receiveRecognizingText, Func<string, Task> receiveRecognizedText) | |
{ | |
return Session.CreateSession(_configuration, receiveRecognizingText, receiveRecognizedText); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment