public WakeWordConfiguration(string path) { if (path == null) { path = string.Empty; } this.Path = path; try { var fileInfo = new FileInfo(path); this.Name = System.IO.Path.GetFileNameWithoutExtension(fileInfo.Name); this.Name = this.Name.Replace('_', ' '); var textInfo = new CultureInfo("en-US").TextInfo; this.Name = textInfo.ToTitleCase(this.Name); this.WakeWordModel = KeywordRecognitionModel.FromFile(path); this.IsValid = true; } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) { Debug.WriteLine($"Bad path to WakeWordConfiguration: {ex.Message}"); this.IsValid = false; this.Name = string.Empty; } #pragma warning restore CA1031 // Do not catch general exception types }
public static async Task KeywordRecognizer() { Console.WriteLine("say something ..."); using (var audioInput = AudioConfig.FromDefaultMicrophoneInput()) { using (var recognizer = new KeywordRecognizer(audioInput)) { var model = KeywordRecognitionModel.FromFile("YourKeywordModelFilename."); var result = await recognizer.RecognizeOnceAsync(model).ConfigureAwait(false); Console.WriteLine($"got result reason as {result.Reason}"); if (result.Reason == ResultReason.RecognizedKeyword) { var stream = AudioDataStream.FromResult(result); await Task.Delay(2000); stream.DetachInput(); await stream.SaveToWaveFileAsync("AudioFromRecognizedKeyword.wav"); } else { Console.WriteLine($"got result reason as {result.Reason}. You can't get audio when no keyword is recognized."); } } } }
private async void OnRecognitionButtonClicked(object sender, EventArgs e) { bool locationAccessGranted = await DependencyService.Get <ILocationService>().GetPermissionsAsync(); if (!locationAccessGranted) { UpdateUI("Please give location access."); } if (_recognizer == null) { _recognizer = new KeywordRecognizer(AudioConfig.FromDefaultMicrophoneInput()); } if (_model == null) { var kwsModelDir = DependencyService.Get <IFileSystemService>().GetWakeWordModelPath(kwsModelFile); _model = KeywordRecognitionModel.FromFile(kwsModelDir); } UpdateUI("Say wakeword to start recording speech."); _result = await _recognizer.RecognizeOnceAsync(_model).ConfigureAwait(false); var locationResult = await DependencyService.Get <ILocationService>().GetCurrentGPSCoordinatesAsync(); string message = $"Detected keyword at TIME: {DateTime.Now} and LOCATION: {locationResult}"; UpdateUI(message); // UpdateUI("Got a keyword, now you can keep talking..."); // await DoSpeechRecognition().ConfigureAwait(false); }
private async Task InitializeKeywordModel() { const string keywordFilePath = "ms-appx:///Keyword/kws.table"; var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(keywordFilePath)); this.model = KeywordRecognitionModel.FromFile(file.Path); }
////////////////////////////////////////////////////////////// LISTENING COMMANDS //////////////////////////////////////////////////////////////////////////////////// public static async Task RecognizeSpeechAsync() { Console.Clear(); Console.WriteLine("Please Say 'Hey Rosita' to begin"); var keywordModel = KeywordRecognitionModel.FromFile("C:\\Users\\Johnny\\Documents\\GitHub\\Rosita\\Rosita\\827f85af-e8cd-44ad-8d48-1963414c3bde.table"); using var audioConfig10 = AudioConfig.FromDefaultMicrophoneInput(); using var keywordRecognizer = new KeywordRecognizer(audioConfig10); KeywordRecognitionResult keyresult = await keywordRecognizer.RecognizeOnceAsync(keywordModel); var config = SpeechConfig.FromSubscription( "aabb8086039843e7b4339dd4928f2de1", "eastus"); using var audioConfig = AudioConfig.FromDefaultMicrophoneInput(); using var recognizer = new SpeechRecognizer(config, audioConfig); Console.WriteLine("Say something..."); var result = await recognizer.RecognizeOnceAsync(); string command = result.Text; switch (result.Reason) { case ResultReason.RecognizedSpeech: Console.WriteLine($"RECOGNIZED: Text={result.Text}"); break; case ResultReason.NoMatch: Console.WriteLine($"NOMATCH: Speech could not be recognized."); break; case ResultReason.Canceled: var cancellation = CancellationDetails.FromResult(result); Console.WriteLine($"CANCELED: Reason={cancellation.Reason}"); if (cancellation.Reason == CancellationReason.Error) { Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}"); Console.WriteLine($"CANCELED: ErrorDetails={cancellation.ErrorDetails}"); Console.WriteLine($"CANCELED: Did you update the subscription info?"); } break; } ////////////////////////////////////////////////////////////// LISTENING COMMANDS END ///////////////////////////////////////////////////////////////////////// /// /// /// ///////////////////////////////////////////////////////////////////// LINK TO KEY PHRASES //////////////////////////////////////////////////////////////////////////// await Speech.TalkingAsync(command.ToLower()); ///////////////////////////////////////////////////////////////////// LINK TO KEY PHRASES END //////////////////////////////////////////////////////////////////////////// }
/// <summary> /// Gets the kws.table file and sets the KeywordRecognitionModel /// </summary> /// <returns>Task</returns> private async Task SetReognitionModel() { string fileName = "kws.table"; StorageFile sFile = null; try { sFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"Listener\Resources\" + fileName); } catch (Exception e) { Console.WriteLine($"{e.Message} \n{e.StackTrace}"); throw; } string path = sFile.Path; KwsModel = KeywordRecognitionModel.FromFile(path); }
private async Task InitializeSpeechConnectorAsync() { audioConfig = AudioConfig.FromDefaultMicrophoneInput(); var config = CustomCommandsConfig.FromSubscription(Constants.CustomCommandsAppId, Constants.SubscriptionKey, Constants.Region); config.Language = Constants.Language; // Create a new Dialog Service Connector for the above configuration and register to receive events connector = new DialogServiceConnector(config, audioConfig); connector.ActivityReceived += Connector_ActivityReceived; connector.Recognizing += Connector_Recognizing; connector.Recognized += Connector_Recognized; connector.Canceled += Connector_Canceled; connector.SessionStarted += Connector_SessionStarted; connector.SessionStopped += Connector_SessionStopped; // Open a connection to Direct Line Speech channel await connector.ConnectAsync(); var keywordRecognitionModel = KeywordRecognitionModel.FromFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Computer.table")); _ = connector.StartKeywordRecognitionAsync(keywordRecognitionModel); }
private async void OnRecognitionButtonWithKeywordClicked(object sender, EventArgs args) { try { // Creates an instance of a speech config with specified subscription key and service region. // Replace with your own subscription key and service region (e.g., "westus"). var config = SpeechConfig.FromSubscription("YourSubscriptionKey", "YourRegion"); kwsModelDir = DependencyService.Get <IAssetService>().GetAssetPath(kwsModelFile); var model = KeywordRecognitionModel.FromFile(kwsModelDir); // The phrase your keyword recognition model triggers on. var keyword = "Computer"; var stopRecognition = new TaskCompletionSource <int>(); var resultStr = ""; // Creates a speech recognizer using microphone as audio input. using (var recognizer = new SpeechRecognizer(config)) { // Subscribes to events. recognizer.Recognized += (s, e) => { if (e.Result.Reason == ResultReason.RecognizedKeyword) { resultStr = $"RECOGNIZED KEYWORD: '{e.Result.Text}'"; } else if (e.Result.Reason == ResultReason.RecognizedSpeech) { resultStr = $"RECOGNIZED: '{e.Result.Text}'"; } else if (e.Result.Reason == ResultReason.NoMatch) { resultStr = "NOMATCH: Speech could not be recognized."; } Debug.WriteLine(resultStr); UpdateUI(resultStr); }; recognizer.Canceled += (s, e) => { var cancellation = CancellationDetails.FromResult(e.Result); resultStr = $"CANCELED: Reason={cancellation.Reason} ErrorDetails={cancellation.ErrorDetails}"; if (cancellation.Reason == CancellationReason.Error) { UpdateUI(resultStr); } Debug.WriteLine(resultStr); stopRecognition.TrySetResult(0); }; recognizer.SessionStarted += (s, e) => { Debug.WriteLine("\nSession started event."); }; recognizer.SessionStopped += (s, e) => { Debug.WriteLine("\nSession stopped event."); Debug.WriteLine("\nStop recognition."); stopRecognition.TrySetResult(0); }; Debug.WriteLine($"Say something starting with the keyword '{keyword}' followed by whatever you want..."); // Starts continuous recognition using the keyword model. Use StopKeywordRecognitionAsync() to stop recognition. await recognizer.StartKeywordRecognitionAsync(model).ConfigureAwait(false); // Waits for a single successful keyword-triggered speech recognition (or error). // Use Task.WaitAny to keep the task rooted. Task.WaitAny(new[] { stopRecognition.Task }); await recognizer.StopKeywordRecognitionAsync().ConfigureAwait(false); } } catch (Exception ex) { UpdateUI("Exception: " + ex.ToString()); } }
public async void ButtonClick() { try { lock (threadLocker) { waitingForReco = true; } // Creates an instance of a speech config with specified subscription key and service region. // Replace with your own subscription key and service region (e.g., "westus"). var config = SpeechConfig.FromSubscription("YourSubscriptionKey", "YourServiceRegion"); #if PLATFORM_ANDROID kwsModelDir = Application.persistentDataPath + Path.DirectorySeparatorChar + kwsModelFile; #else kwsModelDir = Application.streamingAssetsPath + Path.DirectorySeparatorChar + kwsModelFile; #endif UnityEngine.Debug.Log(kwsModelDir); var model = KeywordRecognitionModel.FromFile(kwsModelDir); var stopRecognition = new TaskCompletionSource <int>(); var resultStr = ""; // Creates a speech recognizer using microphone as audio input. using (var recognizer = new SpeechRecognizer(config)) { // Subscribes to events. recognizer.Recognized += (s, e) => { if (e.Result.Reason == ResultReason.RecognizedKeyword) { resultStr = $"RECOGNIZED KEYWORD: '{e.Result.Text}'"; } else if (e.Result.Reason == ResultReason.RecognizedSpeech) { resultStr = $"RECOGNIZED: '{e.Result.Text}'"; } else if (e.Result.Reason == ResultReason.NoMatch) { resultStr = "NOMATCH: Speech could not be recognized."; } UnityEngine.Debug.Log(resultStr); lock (threadLocker) { message = resultStr; } }; recognizer.Canceled += (s, e) => { var cancellation = CancellationDetails.FromResult(e.Result); resultStr = $"CANCELED: Reason={cancellation.Reason} ErrorDetails={cancellation.ErrorDetails}"; if (cancellation.Reason == CancellationReason.Error) { lock (threadLocker) { message = resultStr; } } UnityEngine.Debug.Log(resultStr); stopRecognition.TrySetResult(0); }; recognizer.SessionStarted += (s, e) => { UnityEngine.Debug.Log("\nSession started event."); }; recognizer.SessionStopped += (s, e) => { UnityEngine.Debug.Log("\nSession stopped event."); UnityEngine.Debug.Log("\nStop recognition."); stopRecognition.TrySetResult(0); }; UnityEngine.Debug.Log($"Say something starting with the keyword '{keyword}' followed by whatever you want..."); // Starts continuous recognition using the keyword model. Use StopKeywordRecognitionAsync() to stop recognition. await recognizer.StartKeywordRecognitionAsync(model).ConfigureAwait(false); // Waits for a single successful keyword-triggered speech recognition (or error). // Use Task.WaitAny to keep the task rooted. Task.WaitAny(new[] { stopRecognition.Task }); await recognizer.StopKeywordRecognitionAsync().ConfigureAwait(false); lock (threadLocker) { waitingForReco = false; } } } catch (Exception ex) { lock (threadLocker) { message = "Exception: " + ex.ToString(); waitingForReco = false; } } }
// Continuous speech recognition with keyword spotting. public static async Task ContinuousRecognitionWithKeywordSpottingAsync() { // Creates an instance of a speech config with specified subscription key and service region. // Replace with your own subscription key and service region (e.g., "westus"). var config = SpeechConfig.FromSubscription("YourSubscriptionKey", "YourServiceRegion"); // Creates an instance of a keyword recognition model. Update this to // point to the location of your keyword recognition model. var model = KeywordRecognitionModel.FromFile("YourKeywordRecognitionModelFile.table"); // The phrase your keyword recognition model triggers on. var keyword = "YourKeyword"; var stopRecognition = new TaskCompletionSource <int>(); // Creates a speech recognizer using microphone as audio input. using (var recognizer = new SpeechRecognizer(config)) { // Subscribes to events. recognizer.Recognizing += (s, e) => { if (e.Result.Reason == ResultReason.RecognizingKeyword) { Console.WriteLine($"RECOGNIZING KEYWORD: Text={e.Result.Text}"); } else if (e.Result.Reason == ResultReason.RecognizingSpeech) { Console.WriteLine($"RECOGNIZING: Text={e.Result.Text}"); } }; recognizer.Recognized += (s, e) => { if (e.Result.Reason == ResultReason.RecognizedKeyword) { Console.WriteLine($"RECOGNIZED KEYWORD: Text={e.Result.Text}"); } else if (e.Result.Reason == ResultReason.RecognizedSpeech) { Console.WriteLine($"RECOGNIZED: Text={e.Result.Text}"); } else if (e.Result.Reason == ResultReason.NoMatch) { Console.WriteLine("NOMATCH: Speech could not be recognized."); } }; recognizer.Canceled += (s, e) => { Console.WriteLine($"CANCELED: Reason={e.Reason}"); if (e.Reason == CancellationReason.Error) { Console.WriteLine($"CANCELED: ErrorCode={e.ErrorCode}"); Console.WriteLine($"CANCELED: ErrorDetails={e.ErrorDetails}"); Console.WriteLine($"CANCELED: Did you update the subscription info?"); } stopRecognition.TrySetResult(0); }; recognizer.SessionStarted += (s, e) => { Console.WriteLine("\n Session started event."); }; recognizer.SessionStopped += (s, e) => { Console.WriteLine("\n Session stopped event."); Console.WriteLine("\nStop recognition."); stopRecognition.TrySetResult(0); }; // Starts recognizing. Console.WriteLine($"Say something starting with the keyword '{keyword}' followed by whatever you want..."); // Starts continuous recognition using the keyword model. Use // StopKeywordRecognitionAsync() to stop recognition. await recognizer.StartKeywordRecognitionAsync(model).ConfigureAwait(false); // Waits for a single successful keyword-triggered speech recognition (or error). // Use Task.WaitAny to keep the task rooted. Task.WaitAny(new[] { stopRecognition.Task }); // Stops recognition. await recognizer.StopKeywordRecognitionAsync().ConfigureAwait(false); } }
/// <summary> /// Sets up the initial state needed for Direct Line Speech, including creation of the /// underlying DialogServiceConnector and wiring of its events. /// </summary> /// <param name="keywordFile"> The keyword file to be loaded as part of initialization.</param> /// <returns> A task that completes once initialization is complete. </returns> public Task InitializeAsync(StorageFile keywordFile) { Contract.Requires(keywordFile != null); var configRefreshRequired = this.TryRefreshConfigValues(); var refreshConnector = configRefreshRequired || (this.keywordFilePath != keywordFile.Path); if (LocalSettingsHelper.SetProperty != null) { this.enableKwsLogging = true; } if (this.enableKwsLogging) { refreshConnector = true; this.enableKwsLogging = false; } if (refreshConnector) { var newConnectorConfiguration = this.CreateConfiguration(); this.ConfirmationModel = KeywordRecognitionModel.FromFile(keywordFile.Path); this.keywordFilePath = keywordFile.Path; this.ConnectorConfiguration = newConnectorConfiguration; this.connectorInputStream = AudioInputStream.CreatePushStream(); this.connector?.Dispose(); this.connector = new DialogServiceConnector( this.ConnectorConfiguration, AudioConfig.FromStreamInput(this.connectorInputStream)); this.connector.SessionStarted += (s, e) => this.SessionStarted?.Invoke(e.SessionId); this.connector.SessionStopped += (s, e) => this.SessionStopped?.Invoke(e.SessionId); this.connector.Recognizing += (s, e) => { switch (e.Result.Reason) { case ResultReason.RecognizingKeyword: this.logger.Log(LogMessageLevel.SignalDetection, $"Local model recognized keyword \"{e.Result.Text}\""); this.KeywordRecognizing?.Invoke(e.Result.Text); this.secondStageConfirmed = true; break; case ResultReason.RecognizingSpeech: this.logger.Log(LogMessageLevel.SignalDetection, $"Recognized speech in progress: \"{e.Result.Text}\""); this.SpeechRecognizing?.Invoke(e.Result.Text); break; default: throw new InvalidOperationException(); } }; this.connector.Recognized += (s, e) => { KwsPerformanceLogger.KwsEventFireTime = TimeSpan.FromTicks(DateTime.Now.Ticks); switch (e.Result.Reason) { case ResultReason.RecognizedKeyword: var thirdStageStartTime = KwsPerformanceLogger.KwsStartTime.Ticks; thirdStageStartTime = DateTime.Now.Ticks; this.logger.Log(LogMessageLevel.SignalDetection, $"Cloud model recognized keyword \"{e.Result.Text}\""); this.KeywordRecognized?.Invoke(e.Result.Text); this.kwsPerformanceLogger.LogSignalReceived("SWKWS", "A", "3", KwsPerformanceLogger.KwsEventFireTime.Ticks, thirdStageStartTime, DateTime.Now.Ticks); this.secondStageConfirmed = false; break; case ResultReason.RecognizedSpeech: this.logger.Log(LogMessageLevel.SignalDetection, $"Recognized final speech: \"{e.Result.Text}\""); this.SpeechRecognized?.Invoke(e.Result.Text); break; case ResultReason.NoMatch: // If a KeywordRecognized handler is available, this is a final stage // keyword verification rejection. this.logger.Log(LogMessageLevel.SignalDetection, $"Cloud model rejected keyword"); if (this.secondStageConfirmed) { var thirdStageStartTimeRejected = KwsPerformanceLogger.KwsStartTime.Ticks; thirdStageStartTimeRejected = DateTime.Now.Ticks; this.kwsPerformanceLogger.LogSignalReceived("SWKWS", "R", "3", KwsPerformanceLogger.KwsEventFireTime.Ticks, thirdStageStartTimeRejected, DateTime.Now.Ticks); this.secondStageConfirmed = false; } this.KeywordRecognized?.Invoke(null); break; default: throw new InvalidOperationException(); } }; this.connector.Canceled += (s, e) => { var code = (int)e.ErrorCode; var message = $"{e.Reason.ToString()}: {e.ErrorDetails}"; this.ErrorReceived?.Invoke(new DialogErrorInformation(code, message)); }; this.connector.ActivityReceived += (s, e) => { // Note: the contract of when to end a turn is unique to your dialog system. In this sample, // it's assumed that receiving a message activity without audio marks the end of a turn. Your // dialog system may have a different contract! var wrapper = new ActivityWrapper(e.Activity); if (wrapper.Type == ActivityWrapper.ActivityType.Event) { if (!this.startEventReceived) { this.startEventReceived = true; return; } else { this.startEventReceived = false; } } var payload = new DialogResponse( messageBody: e.Activity, messageMedia: e.HasAudio ? new DirectLineSpeechAudioOutputStream(e.Audio, LocalSettingsHelper.OutputFormat) : null, shouldEndTurn: (e.Audio == null && wrapper.Type == ActivityWrapper.ActivityType.Message) || wrapper.Type == ActivityWrapper.ActivityType.Event, shouldStartNewTurn: wrapper.InputHint == ActivityWrapper.InputHintType.ExpectingInput); this.DialogResponseReceived?.Invoke(payload); }; } return(Task.FromResult(0)); }
/// <summary> /// Initializes the connection to the Bot. /// </summary> /// <param name="settings">Application settings object, built from the input JSON file supplied as run-time argument.</param> public void InitConnector(AppSettings settings) { DialogServiceConfig config; this.BotReplyList = new List <BotReply>(); this.stopWatch = new Stopwatch(); this.appsettings = settings; if (!string.IsNullOrWhiteSpace(this.appsettings.CustomCommandsAppId)) { // NOTE: Custom commands is a preview Azure Service. // Set the custom commands configuration object based on three items: // - The Custom commands application ID // - Cognitive services speech subscription key. // - The Azure region of the subscription key(e.g. "westus"). config = CustomCommandsConfig.FromSubscription(this.appsettings.CustomCommandsAppId, this.appsettings.SpeechSubscriptionKey, this.appsettings.SpeechRegion); } else { // Set the bot framework configuration object based on two items: // - Cognitive services speech subscription key. It is needed for billing and is tied to the bot registration. // - The Azure region of the subscription key(e.g. "westus"). config = BotFrameworkConfig.FromSubscription(this.appsettings.SpeechSubscriptionKey, this.appsettings.SpeechRegion); } if (this.appsettings.SpeechSDKLogEnabled) { // Speech SDK has verbose logging to local file, which may be useful when reporting issues. config.SetProperty(PropertyId.Speech_LogFilename, $"{this.appsettings.OutputFolder}SpeechSDKLog-{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss", CultureInfo.CurrentCulture)}.log"); } if (!string.IsNullOrWhiteSpace(this.appsettings.SRLanguage)) { // Set the speech recognition language. If not set, the default is "en-us". config.Language = this.appsettings.SRLanguage; } if (!string.IsNullOrWhiteSpace(this.appsettings.CustomSREndpointId)) { // Set your custom speech end-point id here, as given to you by the speech portal https://speech.microsoft.com/portal. // Otherwise the standard speech end-point will be used. config.SetServiceProperty("cid", this.appsettings.CustomSREndpointId, ServicePropertyChannel.UriQueryParameter); // Custom Speech does not support cloud Keyword Verification at the moment. If this is not done, there will be an error // from the service and connection will close. Remove line below when supported. config.SetProperty("KeywordConfig_EnableKeywordVerification", "false"); } if (!string.IsNullOrWhiteSpace(this.appsettings.CustomVoiceDeploymentIds)) { // Set one or more IDs associated with the custom TTS voice your bot will use. // The format of the string is one or more GUIDs separated by comma (no spaces). You get these GUIDs from // your custom TTS on the speech portal https://speech.microsoft.com/portal. config.SetProperty(PropertyId.Conversation_Custom_Voice_Deployment_Ids, this.appsettings.CustomVoiceDeploymentIds); } this.timeout = this.appsettings.Timeout; if (!string.IsNullOrWhiteSpace(this.appsettings.KeywordRecognitionModel)) { this.kwsTable = KeywordRecognitionModel.FromFile(this.appsettings.KeywordRecognitionModel); } if (this.appsettings.SetPropertyId != null) { foreach (KeyValuePair <string, JToken> setPropertyIdPair in this.appsettings.SetPropertyId) { config.SetProperty(setPropertyIdPair.Key, setPropertyIdPair.Value.ToString()); } } if (this.appsettings.SetPropertyString != null) { foreach (KeyValuePair <string, JToken> setPropertyStringPair in this.appsettings.SetPropertyString) { config.SetProperty(setPropertyStringPair.Key.ToString(CultureInfo.CurrentCulture), setPropertyStringPair.Value.ToString()); } } if (this.appsettings.SetServiceProperty != null) { foreach (KeyValuePair <string, JToken> setServicePropertyPair in this.appsettings.SetServiceProperty) { config.SetServiceProperty(setServicePropertyPair.Key.ToString(CultureInfo.CurrentCulture), setServicePropertyPair.Value.ToString(), ServicePropertyChannel.UriQueryParameter); } } if (this.appsettings.RealTimeAudio) { config.SetProperty("SPEECH-AudioThrottleAsPercentageOfRealTime", "100"); config.SetProperty("SPEECH-TransmitLengthBeforeThrottleMs", "0"); } if (this.connector != null) { // Then dispose the object this.connector.Dispose(); this.connector = null; } this.pushAudioInputStream = AudioInputStream.CreatePushStream(); this.connector = new DialogServiceConnector(config, AudioConfig.FromStreamInput(this.pushAudioInputStream)); if (this.appsettings.BotGreeting) { // Starting the timer to calculate latency for Bot Greeting. this.stopWatch.Restart(); } this.AttachHandlers(); }
/// <summary> /// Sets up the initial state needed for Direct Line Speech, including creation of the /// underlying DialogServiceConnector and wiring of its events. /// </summary> /// <param name="keywordFile"> The keyword file to be loaded as part of initialization.</param> /// <returns> A task that completes once initialization is complete. </returns> public Task InitializeAsync(StorageFile keywordFile) { Contract.Requires(keywordFile != null); // Default values -- these can be updated this.ConnectorConfiguration = this.CreateConfiguration(); this.ConfirmationModel = KeywordRecognitionModel.FromFile(keywordFile.Path); this.connectorInputStream = AudioInputStream.CreatePushStream(); this.connector = new DialogServiceConnector( this.ConnectorConfiguration, AudioConfig.FromStreamInput(this.connectorInputStream)); this.connector.SessionStarted += (s, e) => this.SessionStarted?.Invoke(e.SessionId); this.connector.SessionStopped += (s, e) => this.SessionStopped?.Invoke(e.SessionId); this.connector.Recognizing += (s, e) => { switch (e.Result.Reason) { case ResultReason.RecognizingKeyword: this.logger.Log($"Local model recognized keyword \"{e.Result.Text}\""); this.KeywordRecognizing?.Invoke(e.Result.Text); break; case ResultReason.RecognizingSpeech: this.logger.Log($"Recognized speech in progress: \"{e.Result.Text}\""); this.SpeechRecognizing?.Invoke(e.Result.Text); break; default: throw new InvalidOperationException(); } }; this.connector.Recognized += (s, e) => { switch (e.Result.Reason) { case ResultReason.RecognizedKeyword: this.logger.Log($"Cloud model recognized keyword \"{e.Result.Text}\""); this.KeywordRecognized?.Invoke(e.Result.Text); break; case ResultReason.RecognizedSpeech: this.logger.Log($"Recognized final speech: \"{e.Result.Text}\""); this.SpeechRecognized?.Invoke(e.Result.Text); break; case ResultReason.NoMatch: // If a KeywordRecognized handler is available, this is a final stage // keyword verification rejection. this.logger.Log($"Cloud model rejected keyword"); this.KeywordRecognized?.Invoke(null); break; default: throw new InvalidOperationException(); } }; this.connector.Canceled += (s, e) => { var code = (int)e.ErrorCode; var message = $"{e.Reason.ToString()}: {e.ErrorDetails}"; this.ErrorReceived?.Invoke(new DialogErrorInformation(code, message)); }; this.connector.ActivityReceived += (s, e) => { // Note: the contract of when to end a turn is unique to your dialog system. In this sample, // it's assumed that receiving a message activity without audio marks the end of a turn. Your // dialog system may have a different contract! var wrapper = new ActivityWrapper(e.Activity); var payload = new DialogResponse( messageBody: e.Activity, messageMedia: e.HasAudio ? new DirectLineSpeechAudioOutputStream(e.Audio, LocalSettingsHelper.OutputFormat) : null, shouldEndTurn: e.Audio == null && wrapper.Type == ActivityWrapper.ActivityType.Message, shouldStartNewTurn: wrapper.InputHint == ActivityWrapper.InputHintType.ExpectingInput); this.logger.Log($"Connector activity received"); this.DialogResponseReceived?.Invoke(payload); }; return(Task.FromResult(0)); }
/// <summary> /// Keyword-triggered intent recognition using microphone. This is useful for when you don't have a push-to-talk feature /// and want to activate your device with voice only. A keyword model is used for local recognition and activation. /// NOTE: It is possible to still call recognize once during a keyword spotting session if you want to have both /// push-to-talk and keyword activation. /// Example interaction: "Computer turn on the lights". /// </summary> public static async Task IntentPatternMatchingWithMicrophoneAndKeywordSpottingAsync() { // Creates an instance of a speech config with specified subscription key and service region. Note that in // contrast to the other samples this DOES NOT require a LUIS application. // The default recognition language is "en-us". var config = SpeechConfig.FromSubscription( "YourSubscriptionKey", "YourSubscriptionRegion"); // Creates an instance of a keyword recognition model. Update this to // point to the location of your keyword recognition model. var keywordModel = KeywordRecognitionModel.FromFile(@"PathToKeywordModel\Keyword.table"); // The phrase your keyword recognition model triggers on. var keyword = "YourKeyword"; // Creates an intent recognizer using microphone as audio input. using (var recognizer = new IntentRecognizer(config)) { // Create a string containing the keyword with the optional pattern tags on it. This can be useful if you // are using push to talk and keyword activation. var keywordOptionalPattern = "[" + keyword + "]"; // Creates a Pattern Matching model and adds specific intents from your model. The Id is used to identify // this model from others in the collection. var patternMatchingModel = new PatternMatchingModel("YourPatternMatchingModelId"); // Creates the "floorName" entity and set it to type list. // Adds acceptable values. NOTE the default entity type is Any and so we do not need // to declare the "action" entity. patternMatchingModel.Entities.Add(PatternMatchingEntity.CreateListEntity( "floorName", EntityMatchMode.Strict, "ground floor", "lobby", "1st", "first", "one", "1", "2nd", "second", "two", "2")); // Creates the "parkingLevel" entity as a pre-built integer patternMatchingModel.Entities.Add(PatternMatchingEntity.CreateIntegerEntity("parkingLevel")); // Creates a string with a pattern that uses groups of optional words. Optional phrases in square brackets can // select one phrase from several choices by separating them inside the brackets with a pipe '|'. Here, // "[Go | Take me]" will match either "Go", "Take me", or "". Note the space after the keyword. var patternWithOptionalWords = keywordOptionalPattern + " " + "[Go | Take me] to [floor|level] {floorName}"; // Creates a string with a pattern that uses an optional entity and group that could be used to tie commands // together. Optional patterns in square brackets can also include a reference to an entity. "[{parkingLevel}]" // includes a match against the named entity as an optional component in this pattern. var patternWithOptionalEntity = keywordOptionalPattern + " " + "Go to parking [{parkingLevel}]"; // You can also have multiple entities of the same name in a single pattern by adding appending a unique identifier // to distinguish between the instances. For example: var patternWithTwoOfTheSameEntity = keywordOptionalPattern + " " + "Go to floor {floorName:1} [and then go to floor {floorName:2}]"; // NOTE: Both floorName:1 and floorName:2 are tied to the same list of entries. The identifier can be a string // and is separated from the entity name by a ':' // Adds some intents to look for specific patterns. patternMatchingModel.Intents.Add(new PatternMatchingIntent( "ChangeFloors", patternWithOptionalWords, patternWithOptionalEntity, patternWithTwoOfTheSameEntity)); patternMatchingModel.Intents.Add(new PatternMatchingIntent("DoorControl", keywordOptionalPattern + " " + "{action} the doors", keywordOptionalPattern + " " + "{action} doors", keywordOptionalPattern + " " + "{action} the door", keywordOptionalPattern + " " + "{action} door")); // Add the model to a new language model collection var modelCollection = new LanguageUnderstandingModelCollection(); modelCollection.Add(patternMatchingModel); // Apply the language model collection to the recognizer. recognizer.ApplyLanguageModels(modelCollection); var stopRecognition = new TaskCompletionSource <int>(); // Subscribes to events. recognizer.Recognizing += (s, e) => { if (e.Result.Reason == ResultReason.RecognizingKeyword) { Console.WriteLine($"RECOGNIZING KEYWORD: Text={e.Result.Text}"); } else if (e.Result.Reason == ResultReason.RecognizingSpeech) { Console.WriteLine($"RECOGNIZING: Text={e.Result.Text}"); } }; recognizer.Recognized += (s, e) => { // Checks result. var result = e.Result; if (result.Reason == ResultReason.RecognizedKeyword) { Console.WriteLine($"RECOGNIZED KEYWORD: Text={e.Result.Text}"); } else if (result.Reason == ResultReason.RecognizedIntent) { Console.WriteLine($"RECOGNIZED: Text={result.Text}"); Console.WriteLine($"{"Intent Id=",13} {result.IntentId}."); var entities = result.Entities; switch (result.IntentId) { case "ChangeFloors": if (entities.TryGetValue("floorName", out string floorName)) { Console.WriteLine($"{"FloorName=",17} {floorName}"); } if (entities.TryGetValue("floorName:1", out floorName)) { Console.WriteLine($"{"FloorName:1=",17} {floorName}"); } if (entities.TryGetValue("floorName:2", out floorName)) { Console.WriteLine($"{"FloorName:2=",17} {floorName}"); } if (entities.TryGetValue("parkingLevel", out string parkingLevel)) { Console.WriteLine($"{"ParkingLevel=",17} {parkingLevel}"); } break; case "DoorControl": if (entities.TryGetValue("action", out string action)) { Console.WriteLine($"{"Action=",17} {action}"); } break; default: Console.WriteLine($"Unknown intent ID: {result.IntentId}"); break; } } else if (result.Reason == ResultReason.RecognizedSpeech) { Console.WriteLine($"RECOGNIZED: Text={result.Text}"); Console.WriteLine($"{"Intent not recognized.",17}"); } else if (result.Reason == ResultReason.NoMatch) { Console.WriteLine($"NOMATCH: Speech could not be recognized."); } }; recognizer.Canceled += (s, e) => { Console.WriteLine($"CANCELED: Reason={e.Reason}"); if (e.Reason == CancellationReason.Error) { Console.WriteLine($"CANCELED: ErrorCode={e.ErrorCode}"); Console.WriteLine($"CANCELED: ErrorDetails={e.ErrorDetails}"); Console.WriteLine($"CANCELED: Did you update the subscription info?"); } stopRecognition.TrySetResult(0); }; recognizer.SessionStarted += (s, e) => { Console.WriteLine($"{"Session started event.",17}"); }; recognizer.SessionStopped += (s, e) => { Console.WriteLine($"{"Session stopped event.",17}"); Console.WriteLine($"{"Stop recognition.",17}"); stopRecognition.TrySetResult(0); }; // Starts recognizing. Console.WriteLine($"Say something starting with the keyword '{keyword}' followed by whatever you want..."); // Starts continuous recognition using the keyword model. Use // StopKeywordRecognitionAsync() to stop recognition. await recognizer.StartKeywordRecognitionAsync(keywordModel).ConfigureAwait(false); // Waits for a single successful keyword-triggered speech recognition (or error). await stopRecognition.Task; // Stops recognition. await recognizer.StopKeywordRecognitionAsync().ConfigureAwait(false); } }