Título: Calculadora por Voz
Publicado por: rigorvzla en 9 Diciembre 2017, 15:02 pm
hola de nuevo amigos hoy les traigo un asunto interesante, resulta que quiero hacer una calculadora que funcione con voz, en efecto basandome en ejemplos consegui eso, suma, resta, multiplica y divide. eh aqui el codigo para que lo prueben class ConsoleSpeechProgram { static SpeechSynthesizer habla = new SpeechSynthesizer(); static SpeechRecognitionEngine escucha; static bool done = false; static bool speechOn = true; static void Main(string[] args) { try { habla.SetOutputToDefaultAudioDevice(); habla.SpeakAsync("Esperando Datos Para Calcular"); escucha = new SpeechRecognitionEngine(); escucha.SetInputToDefaultAudioDevice(); escucha.SpeechRecognized += habla_SpeechRecognized; Choices ch_StartStopCommands = new Choices(); ch_StartStopCommands.Add("calcula esto"); ch_StartStopCommands.Add("desactivado"); ch_StartStopCommands.Add("calculo terminado"); GrammarBuilder gb_StartStop = new GrammarBuilder(); gb_StartStop.Append(ch_StartStopCommands); Grammar g_StartStop = new Grammar(gb_StartStop); //Choices ch_Numbers = new Choices(); //ch_Numbers.Add("1" + "1"); //ch_Numbers.Add("10" + "1"); //ch_Numbers.Add("10" + "2"); //ch_Numbers.Add("10"); //string[] Numbers = new string[1000]; //fallo en reconocimiento no es acertivo //for (int i = 0; i < 1000; ++i) // Numbers[i] = i.ToString(); //Choices ch_Numbers = new Choices(Numbers); // Choices ch_Numbers = new Choices(File.ReadAllLines(@"Numeral.txt")); // escucha.LoadGrammarAsync(new System.Speech.Recognition.Grammar(new GrammarBuilder(new Choices(File.ReadAllLines(@"Numeral.txt"))))); GrammarBuilder gb_WhatIsXplusY = new GrammarBuilder(); gb_WhatIsXplusY.Append("cuanto es"); gb_WhatIsXplusY.Append(ch_Numbers); gb_WhatIsXplusY.Append("mas"); gb_WhatIsXplusY.Append(ch_Numbers); GrammarBuilder gb_WhatIsXmenosY = new GrammarBuilder(); gb_WhatIsXmenosY.Append("cuanto es"); gb_WhatIsXmenosY.Append(ch_Numbers); gb_WhatIsXmenosY.Append("menos"); gb_WhatIsXmenosY.Append(ch_Numbers); GrammarBuilder gb_WhatIsXporY = new GrammarBuilder(); gb_WhatIsXporY.Append("cuanto es"); gb_WhatIsXporY.Append(ch_Numbers); gb_WhatIsXporY.Append("por"); gb_WhatIsXporY.Append(ch_Numbers); GrammarBuilder gb_WhatIsXentreY = new GrammarBuilder(); gb_WhatIsXentreY.Append("cuanto es"); gb_WhatIsXentreY.Append(ch_Numbers); gb_WhatIsXentreY.Append("entre"); gb_WhatIsXentreY.Append(ch_Numbers); Grammar g_WhatIsXplusY = new Grammar(gb_WhatIsXplusY); Grammar g_WhatIsXmenosY = new Grammar(gb_WhatIsXmenosY); Grammar g_WhatIsXporY = new Grammar(gb_WhatIsXporY); Grammar g_WhatIsXentreY = new Grammar(gb_WhatIsXentreY); escucha.LoadGrammarAsync(g_StartStop); escucha.LoadGrammarAsync(g_WhatIsXplusY); escucha.LoadGrammarAsync(g_WhatIsXmenosY); escucha.LoadGrammarAsync(g_WhatIsXporY); escucha.LoadGrammarAsync(g_WhatIsXentreY); escucha.RecognizeAsync(RecognizeMode.Multiple); while (done == false) {; } habla.Speak("Cálculos Desactivados"); Application.Exit(); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.ReadLine(); } } // Main
static void habla_SpeechRecognized(object sender, SpeechRecognizedEventArgs e) { string txt = e.Result.Text; float confidence = e.Result.Confidence; Console.WriteLine("\nRecognized: " + txt); if (confidence < 0.60) return; if (txt.IndexOf("calcula esto") >= 0) { habla.Speak("Esperando Datos"); speechOn = true; } if (txt.IndexOf("desactivado") >= 0) { habla.Speak("cálculos desactivados"); speechOn = false; } if (speechOn == false) return; if (txt.IndexOf("calculo") >= 0 && txt.IndexOf("terminado") >= 0) {
((SpeechRecognitionEngine)sender).RecognizeAsyncCancel(); done = true; } if (txt.IndexOf("cuanto") >= 0 && txt.IndexOf("mas") >= 0) { string[] words = txt.Split(' '); double num1 = int.Parse(words[2]); double num2 = int.Parse(words[4]); double sum = num1 + num2; Console.WriteLine("(Speaking: " + words[2] + " + " + words[4] + " = " + sum + ")"); habla.Speak(words[2] + " mas " + words[4] + " es igual a " + sum); } if (txt.IndexOf("cuanto") >= 0 && txt.IndexOf("menos") >= 0) { string[] words = txt.Split(' '); double num1 = int.Parse(words[2]); double num2 = int.Parse(words[4]); double res = num1 - num2; Console.WriteLine("(Speaking: " + words[2] + " - " + words[4] + " = " + res + ")"); habla.Speak(words[2] + " menos " + words[4] + " es igual a " + res); } if (txt.IndexOf("cuanto") >= 0 && txt.IndexOf("por") >= 0) { string[] words = txt.Split(' '); double num1 = int.Parse(words[2]); double num2 = int.Parse(words[4]); double mul = num1 * num2; Console.WriteLine("(Speaking: " + words[2] + " * " + words[4] + " = " + mul + ")"); habla.Speak(words[2] + " por " + words[4] + " es igual a " + mul); } if (txt.IndexOf("cuanto") >= 0 && txt.IndexOf("entre") >= 0) { string[] words = txt.Split(' '); double num1 = int.Parse(words[2]); double num2 = int.Parse(words[4]); double div = num1 / num2; Console.WriteLine("(Speaking: " + words[2] + " / " + words[4] + " = " + div + ")"); habla.Speak(words[2] + " entre " + words[4] + " es igual a " + div); } }
} } hasta aqui todo va chevere pero las gramaticas de numeros es lo que se complica ya alla arriba comentado estan formas que probe y no dio resultado como queria entocnes investigando, encontre este codigo. Perfecto si lo que quisiera pasar de numeros a palabras. class Program { // PROGRAM HANDLES NEGATIVE AND POSITIVE DOUBLES
static String NumWordsWrapper(double n) { string words = ""; double intPart; double decPart = 0; if (n == 0) return "cero"; try { string[] splitter = n.ToString().Split('.'); intPart = double.Parse(splitter[0]); decPart = double.Parse(splitter[1]); } catch { intPart = n; }
words = NumWords(intPart);
if (decPart > 0) { if (words != "") words += " y "; int counter = decPart.ToString().Length; switch (counter) { case 1: words += NumWords(decPart) + " decimas"; break; case 2: words += NumWords(decPart) + " centesimas"; break; case 3: words += NumWords(decPart) + " milesimas"; break; case 4: words += NumWords(decPart) + " diez-milesimas"; break; case 5: words += NumWords(decPart) + " cien-milesimas"; break; case 6: words += NumWords(decPart) + " millonesima"; break; case 7: words += NumWords(decPart) + " diez-millonesima"; break; } } return words; }
static String NumWords(double n) //converts double to words { string[] numbersArr = new string[] { "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve", "diez", "once", "doce", "trece", "catorce", "quince", "dieciseis", "diecisiete", "dieciohco", "diecinueve" }; string[] tensArr = new string[] { "veinte", "treinta", "cuarenta", "cincuenta", "sesenta", "setenta", "ochenta", "noventa" }; string[] suffixesArr = new string[] { "mil", "millones", "billon", "trillon", "quadrillon", "quintillon", "sextillon", "septillon", "octillon", "nonillon", "decillon", "undecillon", "duodecillon", "tredecillon", "Quattuordecillon", "Quindecillon", "Sexdecillon", "Septdecillon", "Octodecillon", "Novemdecillon", "Vigintillon" }; string words = "";
bool tens = false;
if (n < 0) { words += "negative "; n *= -1; }
int power = (suffixesArr.Length + 1) * 3;
while (power > 3) { double pow = Math.Pow(10, power); if (n >= pow) { if (n % pow > 0) { words += NumWords(Math.Floor(n / pow)) + " " + suffixesArr[(power / 3) - 1] + ", "; } else if (n % pow == 0) { words += NumWords(Math.Floor(n / pow)) + " " + suffixesArr[(power / 3) - 1]; } n %= pow; } power -= 3; } if (n >= 1000) { if (n % 1000 > 0) words += NumWords(Math.Floor(n / 1000)) + " mil, "; else words += NumWords(Math.Floor(n / 1000)) + " mil"; n %= 1000; } if (0 <= n && n <= 999) { if ((int)n / 100 > 0) { words += NumWords(Math.Floor(n / 100)) + " ciento"; n %= 100; } if ((int)n / 10 > 1) { if (words != "") words += " "; words += tensArr[(int)n / 10 - 2]; tens = true; n %= 10; }
if (n < 20 && n > 0) { if (words != "" && tens == false) words += " "; words += (tens ? " y " + numbersArr[(int)n - 1] : numbersArr[(int)n - 1]); n -= Math.Floor(n); } }
return words;
} static void Main(string[] args) { Console.Write("Introduce un numero para escribirlo en letras: "); Double n = Double.Parse(Console.ReadLine());
Console.WriteLine("{0}", NumWordsWrapper(n)); Console.ReadKey(); } } con este codigo al ejecutarlo yo puedo colocar cualquier numero y el lo responde escrito en letras, en este caso lo que necesito es lo contrario y ver como adaptar ese codigo a la calculadora , en teoria no harian falta millones de numeros y el resultado seria una calculadora que entendiera cualquier cifra hablada.
|