private async Task <string> GetReminderTitleAsync() { string title = ""; var titleIdentifierRegex = new Regex("(?<=(named |called |titled )).+"); var match = titleIdentifierRegex.Match(this.CommandString); if (match.Success) { title = match.Value; } else { // ask the user to give a title if listening is enabled, else tell the user to retry with a title if (Utils.IsListeningSettingEnabled()) { TextToSpeechEngine.SpeakText(this.MediaElement, "Sure, what's the title of the reminder?"); await SpeechRecognitionManager.RequestListen(this.GetType(), (text) => title = text); } else { // title should be null, which will be used in the calling method to tell the user that title is required title = null; } } return(title); }
public async override void PerformAction() { List <WeatherInfo> weatherInfos = await WeatherService.GetWeather(); // if there's a date in the command string, find it and compare it with the dates provided DateTime commandDate = DateTimeParser.ParseDateTimeFromText(this.CommandString); // get the first applicable weather info WeatherInfo firstApplicableWeatherInfo = weatherInfos.Find(info => info.DateApplicable >= commandDate); if (firstApplicableWeatherInfo != null && this.MediaElement != null) { this.ClearArea(); // TODO get better at determining where there should be inflection. Right now this works but sounds a bit too robotic string inflectionData = new SSMLBuilder().Prosody(SplitWeatherDescUpIntoSSMLSentences(firstApplicableWeatherInfo.Description), contour: "(30%,+10%) (60%,-10%) (90%,+5%)").Build(); TextToSpeechEngine.SpeakInflectedText(this.MediaElement, inflectionData); this.ShowMessage(firstApplicableWeatherInfo.Description); } else if (firstApplicableWeatherInfo == null) { this.ClearArea(); string message = "I could not find any weather info for the date specified. Try making sure that you have location enabled, and that this app can access your location through system settings, privacy, location"; TextToSpeechEngine.SpeakText(this.MediaElement, message); this.ShowMessage(message.Replace("settings, privacy, location", "settings > privacy > location")); } }
private async Task <Reminder> CreateReminderAsync() { this.ClearArea(); Reminder createdReminder = new Reminder(); DateTime?dateTime = this.GetReminderDateAndTime(); // if the date is null, then we need to tell the user that a date and time is required if (dateTime != null) { string title = await this.GetReminderTitleAsync(); if (title == null) { string message = "Sorry, but reminders require a title. If you don't need a title, try setting an alarm instead."; TextToSpeechEngine.SpeakText(this.MediaElement, message); this.ShowMessage(message); createdReminder = null; } else { // description can't be easily input with text, so don't set it createdReminder.Title = title; createdReminder.ActivateDateAndTime = dateTime.Value; } } else { // tell the user that a date is needed, and set the alarm to null so the calling code can handle it var message = "Sorry, but to create a reminder I need a date and time to set the reminder off at. Please try again."; TextToSpeechEngine.SpeakText(this.MediaElement, message); this.ShowMessage(message); createdReminder = null; } return(createdReminder); }
public async override void PerformAction() { CommandString = CommandString.ToUpper(); string strDestination = ""; if (CommandString.Contains(" TO ")) { strDestination = CommandString.Substring(CommandString.IndexOf(" TO ") + 4); } else { // have bob ask the user where they want to go TextToSpeechEngine.SpeakText(this.MediaElement, "Sure, where do you want to go?"); // sleep the thread to give bob enough time to speak if (!await SpeechRecognitionManager.RequestListen(this.GetType(), (text) => { strDestination = text; GetDirections(text); })) { string message = "Sorry, but something went wrong. To get directions, say \"Hey Bob, how do I get to thePlace\""; TextToSpeechEngine.SpeakText(this.MediaElement, message); this.ShowMessage(message); } else { ProvideDirectionsSuccessMessage(strDestination); } } if (StringUtils.IsNotBlank(strDestination)) { GetDirections(strDestination); ProvideDirectionsSuccessMessage(strDestination); } }
private int GenerateRandomNumber(int lowerBound, int upperBound) { // get the actual upper and lower bounds (the user could have put the higher number first, but they could also have put it last so we need to figure out which it is) if (lowerBound > upperBound) { var temp = lowerBound; lowerBound = upperBound; upperBound = temp; } // if the user said "exclusive", move the lower bound up and the upper bound down if (this.CommandString.ToLower().Contains("exclusive")) { lowerBound++; upperBound--; } // make sure the upper bound is greater than the lower bound if (upperBound == lowerBound) { TextToSpeechEngine.SpeakText(this.MediaElement, $"Sorry, but I can't pick a whole number between {lowerBound} and {upperBound}"); throw new ArgumentException(); } else { return(new Random().Next(lowerBound, upperBound)); } }
public override void PerformAction() { Joke joke = StoredProcedures.QueryRandomJoke(); this.ClearArea(); if (joke != null) { TextToSpeechEngine.SpeakText(this.MediaElement, joke.Text); this.ShowMessage(joke.Text); } }
private async void RequestMicrophoneAcessIfUserWantsVoiceDetection() { if (Utils.IsListeningSettingEnabled()) { if (await AudioCapturePermissions.RequestMicrophonePermission()) { SpeechRecognitionManager.StartListeningForMainPage(performActionFromCommandBoxText, this.CommandBox); } else { TextToSpeechEngine.SpeakText(this.media, "Sorry, but something went wrong with setting up your microphone. You cannot use me through speech, but you can still use the command bar at the bottom of the screen."); } } }
void btnSpeakText_Click(object sender, EventArgs e) { btnSpeakText.Enabled = false; try { tts.Volume = (comboBox3.SelectedItem as EnumData <SpeechVolumeEnums>).Value; tts.Speed = (comboBox2.SelectedItem as EnumData <SpeechSpeedEnums>).Value; tts.Speaker = (comboBox1.SelectedItem as SpeakerInfo).Id; tts.SpeakText(rtbContent.Text); } catch (Exception ex) { } btnSpeakText.Enabled = true; }
private void FlipCoin() { // coins are always 2-sided, so pick a random number and associate it with heads or tails int side = new Random().Next(2); string sideName = side == 0 ? "Heads" : "Tails"; string text = $"It landed on {sideName}"; AudioPlayer.PlaySound("coin_flip", () => { Utils.RunOnMainThread(() => { TextToSpeechEngine.SpeakText(this.MediaElement, text); this.ShowMessage(sideName); }); }); }
/// <summary> /// should only be called after <see cref="StartListeningForMainPage(Action{string}, TextBox)"/> has been called since the main page was navigated to /// </summary> private static void StartListeningForMainPage() { if (Utils.IsListeningSettingEnabled()) { if (MainPageFunction != null && MainPageTextBox != null) { // the main page takes priority over everything when it comes to listening, so force stop SpeechRecognitionUtils.Stop(); CurrentListener = typeof(MainPage); IsCurrentListenerDone = false; SpeechRecognitionUtils.StartLooping(MainPageFunction, MainPageTextBox); } } else { TextToSpeechEngine.SpeakText(new MediaElement(), "Sorry, but something went wrong with setting up your microphone. You cannot use me through speech, but you can still use the command bar at the bottom of the screen."); } }
public override async void PerformAction() { Action <string> repeatAction = (text) => { this.ClearArea(); TextToSpeechEngine.SpeakText(this.MediaElement, $"{text}"); this.ShowMessage($"You said {text}"); }; var executedSuccessfully = await SpeechRecognitionManager.RequestListen(this.GetType(), repeatAction); if (!executedSuccessfully) { this.ClearArea(); string message = "Something went wrong with listening to you, so I cannot repeat after you. Do you have voice activation set to off in the app settings or system settings?"; TextToSpeechEngine.SpeakText(this.MediaElement, message); this.ShowMessage(message); } }
private async void ProvideDirectionsSuccessMessage(string destination) { // show a link to the search this.ClearArea(); var linkElement = new HyperlinkButton(); linkElement.Content = $"Directions to {destination.ToLower()}"; string directionsLink = await GetDirectionsLink(destination); if (directionsLink != null) { linkElement.NavigateUri = new Uri(directionsLink); linkElement.FontSize = 24; RelativePanel.SetAlignHorizontalCenterWithPanel(linkElement, true); RelativePanel.SetAlignVerticalCenterWithPanel(linkElement, true); this.DynamicArea.Children.Add(linkElement); TextToSpeechEngine.SpeakText(this.MediaElement, $"Alright, getting {linkElement.Content.ToString().ToLower()}"); } }
public override void PerformAction() { //get list of searchable websites from database List <SearchableWebsite> allSearchableWebsites = StoredProcedures.QueryAllSearchableWebsites(); //need to check if user provided a website to search bool isUserProvidedWebsiteSearch = false; //go through list of searchable websites. return true if user included the searchable website in search //this will also set the website if there is a match isUserProvidedWebsiteSearch = GetActionFromCommand(allSearchableWebsites); string searchParameters; string searchQuery; if (isUserProvidedWebsiteSearch) { //find what is wanted to be searched and concatenate with + for end of url searchParameters = GetSearchParameters(isUserProvidedWebsiteSearch); searchQuery = BuildSearchQuery(desiredSearchableWebsite, searchParameters); //launch browser. this will be done with the default browser LaunchSearch(searchQuery); } else { //sets desiredSearchEngine, which is the default selected in settings GetDefaultSearchEngine(); searchParameters = GetSearchParameters(isUserProvidedWebsiteSearch); searchQuery = BuildSearchQuery(desiredSearchEngine, searchParameters); //launch browser. this will be done with the default browser LaunchSearch(searchQuery); } // show a link to the search this.ClearArea(); var linkElement = new HyperlinkButton(); linkElement.Content = $"{searchParameters} on {(desiredSearchableWebsite != null ? desiredSearchableWebsite.Name : desiredSearchEngine?.Name)}"; linkElement.NavigateUri = new Uri(searchQuery); linkElement.FontSize = 24; RelativePanel.SetAlignHorizontalCenterWithPanel(linkElement, true); RelativePanel.SetAlignVerticalCenterWithPanel(linkElement, true); this.DynamicArea.Children.Add(linkElement); // announce to the user that we're searching for something TextToSpeechEngine.SpeakText(this.MediaElement, $"Sure, searching for {linkElement.Content}"); }
private Alarm CreateAlarm() { Alarm createdAlarm = new Alarm(); DateTime?dateTime = this.GetAlarmDateAndTime(); if (dateTime != null) { string title = this.FindAlarmTitle(); createdAlarm.Title = title; createdAlarm.ActivateDateAndTime = dateTime.Value; } else { // tell the user that a date is needed, and set the alarm to null so the calling code can handle it var message = "Sorry, but to create an alarm I need a date and time to set the alarm off at. Please try again."; TextToSpeechEngine.SpeakText(this.MediaElement, message); this.ShowMessage(message); createdAlarm = null; } return(createdAlarm); }
private void RollDie() { // the first number we come across is the number of sides the die has, if we don't come across a number we default it to 6 sides string numberOfSides = new Regex("[0-9]+").Match(this.CommandString).Value; int parsedSideCount = 6; if (numberOfSides != "") { parsedSideCount = int.Parse(numberOfSides); } // pick the random number with the range [1, numberOfSides] int pickedSide = new Random().Next(1, parsedSideCount + 1); AudioPlayer.PlaySound("die_roll", () => { Utils.RunOnMainThread(() => { TextToSpeechEngine.SpeakText(this.MediaElement, $"You rolled a {pickedSide}"); this.ShowMessage(pickedSide.ToString()); }); }); }
public override void PerformAction() { this.ClearArea(); types type = GetTypeFromCommand(); if (type == types.DICE) { this.RollDie(); } else if (type == types.COIN) { this.FlipCoin(); } else if (type == types.NUMBER) { this.PickRandomNumber(); } else { TextToSpeechEngine.SpeakText(this.MediaElement, "Sorry, but something went wrong and I couldn't pick a random number for you"); } }
private void PickRandomNumber() { // there will be 2 numbers that the user picks (e.g. "pick a random number between 1 and 5") var numberRegex = new Regex("[0-9]+|one"); var matches = numberRegex.Matches(this.CommandString); int generatedNumber = -1; // the default lower and upper bounds are 1 and 100 int lowerBound = 1; int upperBound = 100; // controls if we show an error message instead of a generated number bool successfullyGenerated = true; // if there's less than 2 matches, tell the user they need 2 numbers if (matches.Count == 1) { TextToSpeechEngine.SpeakText(this.MediaElement, "Sorry, but in order to pick a random number I need 2 numbers to pick between"); successfullyGenerated = false; } else if (matches.Count >= 2) { lowerBound = matches[0].Value.ToLower() == "one" ? 1 : int.Parse(matches[0].Value); upperBound = matches[1].Value.ToLower() == "one" ? 1 : int.Parse(matches[1].Value); } // now generate the number try { generatedNumber = GenerateRandomNumber(lowerBound, upperBound); } catch (ArgumentException) { successfullyGenerated = false; } if (successfullyGenerated) { // TODO play a sound maybe? idk TextToSpeechEngine.SpeakText(this.MediaElement, $"It's {generatedNumber}"); this.ShowMessage(generatedNumber.ToString()); } }
private async Task <string> GetDirectionsLink(string destination) { string query = null; Dictionary <string, double> coordinates = await LocationProvider.GetLatitudeAndLongitude(); if (coordinates != null) { double latitude = coordinates["latitude"]; double longitude = coordinates["longitude"]; Setting setting = StoredProcedures.QuerySettingByName("Map Provider"); MapProvider mapProvider = StoredProcedures.QueryMapProvider(setting.GetSelectedOption().DisplayName); query = mapProvider.BaseURL.ToString(); query = query.Replace("{Latitude}", latitude.ToString()).Replace("{Longitude}", longitude.ToString()).Replace("{Destination}", HttpUtility.UrlEncode(destination)); } else { // have bob tell the user that location information couldn't be retrieved string message = "Sorry, but I couldn't get your location. In order to get you directions to a place, I need your location to use for the starting point."; TextToSpeechEngine.SpeakText(this.MediaElement, message); this.ShowMessage(message); } return(query); }