using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Speech.Recognition;
using System.Speech.Recognition.SrgsGrammar;
using System.Xml;
using System.Xml.Linq;
// Add to references
// | System.Xml.Linq.dll | System.Core.dll | C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\System.Speech.dll
public static class VoiceBotScript
{
public static void Run()
{
// Depending on the type you want, set the return type. E.g. <string> or <float> or <int> or other.
var recogResult = SrHelper<int>();
// Show\Say what recognize. Need for feedback. Can be removed.
///BFS.Dialog.ShowMessageInfo(recogResult.ToString(CultureInfo.InvariantCulture));
// or
BFS.Speech.TextToSpeech(string.Format("I recognized {0}", recogResult));
// your code goes here
}
private static T SrHelper<T>()
where T : IConvertible
{
// Set Path to file
var pathToFile = @"C:\VBotFiles\Recognizer\";
// Set file name
var fileName = "Volume";
// Set your recognition language. Support languages: en-GB, en-US, de-DE, es-ES, fr-FR, ja-JP, zh-CN, zh-TW.
// Selected language pack must be installed.
var culture = new CultureInfo("en-US");
// Check whether the selected culture is installed for selected speech recognition.
if (!TestInstalledLanguages.TestLanguages(culture))
return (T)Convert.ChangeType(null, typeof(T));
// If the recognition does not recognize the first time set the flag to true
// and set the number of recognition tries
var flag = false;
var maxTries = 3;
// Set the range
var rangeStart = 0;
var rangeCount = 100;
// Create list with range 0-100. Ex. for set volume in audio app.
///var valList = Enumerable.Range(rangeStart, rangeCount).ToList();
// or create list with range 0-10-20...100
var valList = Enumerable.Range(rangeStart, rangeCount + 1).Where(x => x % 10 == 0).ToList();
// or create string list
///var valList = new List<string>
///{
/// "Add", "the", "recognition", "commands", "you", "want"
///};
var ext = ".xml";
var fullFileName = fileName + ext;
// Open\save srgs file
var srgsFile = SrgsDocumentCreator.GetSrgsFile(pathToFile, fileName, fullFileName, culture, valList);
// Get recognition result
var result = SpeechRecognition.Recognition(srgsFile, culture, flag, maxTries);
// Return a nullable type not default(T)
if (string.IsNullOrEmpty(result))
return (T)Convert.ChangeType(null, typeof(T));
return (T)Convert.ChangeType(result, typeof(T));
}
}
// Speech recognition. Initialize SpeechRecognitionEngine with selected language and return recognition result.
internal class SpeechRecognition
{
public static string Recognition(string srgsFile, CultureInfo culture, bool flag, int maxTries)
{
RecognitionResult result;
var recogResult = string.Empty;
var sre = new SpeechRecognitionEngine(culture);
var grammar = new Grammar(srgsFile);
var tries = 0;
sre.LoadGrammar(grammar);
try
{
sre.SetInputToDefaultAudioDevice();
if(flag == false)
{
result = sre.Recognize();
if (result != null)
recogResult = result.Text;
else
BFS.Speech.TextToSpeech("I can't recognize what you say.");
}
// If the recognition hasn't been successful the first time, try more.
do
{
result = sre.Recognize();
if (result != null)
{
recogResult = result.Text;
break;
}
tries++;
BFS.Speech.TextToSpeech("I can't recognize what you say. Please try again");
continue;
}
while (tries < maxTries);
}
catch (Exception ex)
{
BFS.Dialog.ShowMessageError(ex.Message);
}
finally
{
sre.UnloadGrammar(grammar);
}
return recogResult;
}
}
// Create Srgs file
internal class SrgsDocumentCreator
{
public static string GetSrgsFile<T>(string pathToFile, string fileName, string fullFileName, CultureInfo culture, List<T> valList)
{
// Check directory exist
if (!Directory.Exists(pathToFile))
Directory.CreateDirectory(pathToFile);
var srgsFile = Path.Combine(pathToFile, fullFileName);
// Check file exist and xml:lang value equals selected culture
if (File.Exists(srgsFile))
{
var xDoc = XDocument.Load(srgsFile);
if (xDoc.Root != null && xDoc.Root.FirstAttribute.Value == culture.Name)
return srgsFile;
}
// Create SrgsOneOf
var values = new SrgsOneOf();
// Add SrgsItem to SrgsOneOf
foreach (var val in valList)
values.Add(new SrgsItem(val.ToString()));
// Create root rule
var ruleVolume = new SrgsRule(fileName, values) {Scope = SrgsRuleScope.Public};
// Create SrgsDocument with selected culture
var srgsDoc = new SrgsDocument {Culture = culture};
// Add rules to document
srgsDoc.Rules.Add(ruleVolume);
// Set document root
srgsDoc.Root = ruleVolume;
// Save created srgsDoc to xml file
var xmlWriter = XmlWriter.Create(srgsFile);
srgsDoc.WriteSrgs(xmlWriter);
xmlWriter.Close();
return srgsFile;
}
}
internal class TestInstalledLanguages
{
public static bool TestLanguages(CultureInfo culture)
{
// Compare the selected speech recognition language with the installed
var info = SpeechRecognitionEngine.InstalledRecognizers()
.FirstOrDefault(x => string.Equals(x.Culture.Name, culture.Name, StringComparison.InvariantCultureIgnoreCase));
if (info != null)
return true;
BFS.Dialog.ShowMessageError(string.Format("The selected language \"{0}\" is not installed", culture.Name));
return false;
}
}