public void BuildAndAddGrammar(string[] equipPrefix, string phrase, string command, bool isSingleHanded)
        {
            Choices equipPrefixChoice = new Choices(equipPrefix.ToArray());

            List <string> handsSuffix = new List <string>();

            handsSuffix.AddRange(bothHandsSuffix);
            handsSuffix.AddRange(rightHandSuffix);
            handsSuffix.AddRange(leftHandSuffix);
            Choices handChoice = new Choices(handsSuffix.ToArray());

            GrammarBuilder grammarBuilder = new GrammarBuilder();

            // Append hand choice prefix
            if (isSingleHanded && useEquipHandPrefix)
            {
                // Optional left/right. When excluded, try to equip to both hands
                grammarBuilder.Append(handChoice, 0, 1);
            }

            grammarBuilder.Append(equipPrefixChoice, omitHandSuffix ? 0 : 1, 1);
            Phrases.appendPhrase(grammarBuilder, phrase, config);

            // Append hand choice suffix
            if (isSingleHanded && !useEquipHandPrefix)
            {
                // Optional left/right. When excluded, try to equip to both hands
                grammarBuilder.Append(handChoice, 0, 1);
            }

            Grammar grammar = new Grammar(grammarBuilder);

            grammar.Name = phrase;
            commandsByGrammar[grammar] = command;
        }
        public string ProbableEquipmentType(string itemName)
        {
            //
            // NOTICE:
            //    1. Some languages (such as Chinese) don't add spaces between words.
            //       So the code such as `itemName.Split(' ')` will not work for them.
            //       Be aware of this when changing the code below.
            //
            //    2. knownEquipmentTypes should be sorted in reverse order of string length to avoid prefix masking.
            //       Consider "axe" and "battleaxe", the former is the prefix of the latter.
            //       If the order is not correct, the latter will never have a chance to be matched.
            //       Sorting is currently done in the constructor.
            //       Note: Adding leading space alleviates the problem, but some languages don't add spaces between words.
            //
            itemName = Phrases.normalize(itemName).ToLower();

            foreach (string type in knownEquipmentTypes)
            {
                if (itemName.Contains(type))
                {
                    return(type);
                }
            }
            return(null);
        }
예제 #3
0
        public SpeechRecognitionManager(Configuration config)
        {
            this.config = config;

            string locale = config.Get("SpeechRecognition", "Locale", CultureInfo.InstalledUICulture.Name);

            dialogueMinimumConfidence = float.Parse(config.Get("SpeechRecognition", "dialogueMinConfidence", "0.5"), CultureInfo.InvariantCulture);
            commandMinimumConfidence  = float.Parse(config.Get("SpeechRecognition", "commandMinConfidence", "0.7"), CultureInfo.InvariantCulture);
            logAudioSignalIssues      = config.Get("SpeechRecognition", "bLogAudioSignalIssues", "0") == "1";

            Trace.TraceInformation("Locale: {0}\nDialogueConfidence: {1}\nCommandConfidence: {2}", locale, dialogueMinimumConfidence, commandMinimumConfidence);

            pauseAudioFile  = config.Get("SpeechRecognition", "pauseAudioFile", DEFAULT_PAUSE_AUDIO_FILE).Trim();
            resumeAudioFile = config.Get("SpeechRecognition", "resumeAudioFile", DEFAULT_RESUME_AUDIO_FILE).Trim();

            List <string> pausePhraseStrings  = config.GetPausePhrases();
            List <string> resumePhraseStrings = config.GetResumePhrases();

            foreach (string phrase in pausePhraseStrings)
            {
                if (phrase == null || phrase.Trim() == "")
                {
                    continue;
                }
                Trace.TraceInformation("Found pause phrase: '{0}'", phrase);
                try {
                    Grammar g = new Grammar(new GrammarBuilder(Phrases.normalize(phrase)));
                    pausePhrases.Add(g);
                } catch (Exception ex) {
                    Trace.TraceError("Failed to create grammar for pause phrase {0} due to exception:\n{1}", phrase, ex.ToString());
                }
            }
            foreach (string phrase in resumePhraseStrings)
            {
                if (phrase == null || phrase.Trim() == "")
                {
                    continue;
                }
                Trace.TraceInformation("Found resume phrase: '{0}'", phrase);
                try {
                    Grammar g = new Grammar(new GrammarBuilder(Phrases.normalize(phrase)));
                    resumePhrases.Add(g);
                } catch (Exception ex) {
                    Trace.TraceError("Failed to create grammar for resume phrase {0} due to exception:\n{1}", phrase, ex.ToString());
                }
            }

            this.DSN = new SpeechRecognitionEngine(new CultureInfo(locale));
            this.DSN.UpdateRecognizerSetting("CFGConfidenceRejectionThreshold", 10); // Range is 0-100
            this.DSN.EndSilenceTimeoutAmbiguous  = TimeSpan.FromMilliseconds(250);
            this.DSN.AudioStateChanged          += DSN_AudioStateChanged;
            this.DSN.AudioSignalProblemOccurred += DSN_AudioSignalProblemOccurred;
            this.DSN.SpeechRecognized           += DSN_SpeechRecognized;
            this.DSN.SpeechRecognitionRejected  += DSN_SpeechRecognitionRejected;
            this.deviceEnum.RegisterEndpointNotificationCallback(this);

            WaitRecordingDeviceNonBlocking();
        }
        public static DialogueList Parse(string input, Configuration config)
        {
            string[]      tokens = input.Split('|');
            long          id     = long.Parse(tokens[0]);
            List <string> lines  = new List <string>();

            for (int i = 1; i < tokens.Length; i++)
            {
                lines.Add(Phrases.normalize(tokens[i]));
            }
            return(new DialogueList(id, lines, config));
        }
        public static CommandList FromIniSection(IniData ini, string sectionName, Configuration config)
        {
            KeyDataCollection sectionData = ini.Sections[sectionName];
            CommandList       list        = new CommandList();

            if (sectionData != null)
            {
                foreach (KeyData key in sectionData)
                {
                    string value = key.Value.Trim();
                    if (value.Length == 0)
                    {
                        Trace.TraceInformation("Ignore empty command '{0}'", key.KeyName);
                        continue;
                    }
                    Grammar grammar;
                    if (value[0] == '@')
                    {
                        string path = config.ResolveFilePath(value.Substring(1));
                        if (path == null)
                        {
                            Trace.TraceError("Cannot find the SRGS XML file '{0}', key: {1}", value.Substring(1), key.KeyName);
                            continue;
                        }

                        // load a SRGS XML file
                        XmlDocument doc = new XmlDocument();
                        doc.Load(path);

                        // If xml:lang in the file does not match the DSN's locale, the grammar cannot be loaded.
                        XmlAttribute xmlLang = doc.CreateAttribute("xml:lang");
                        xmlLang.Value = config.GetLocale().Name;
                        doc.DocumentElement.SetAttributeNode(xmlLang);

                        MemoryStream xmlStream = new MemoryStream();
                        doc.Save(xmlStream);
                        xmlStream.Flush(); //Adjust this if you want read your data
                        xmlStream.Position = 0;

                        grammar = new Grammar(xmlStream);
                    }
                    else
                    {
                        grammar = Phrases.createGrammar(Phrases.normalize(key.KeyName, config), config);
                    }
                    grammar.Name = key.KeyName;
                    list.commandsByPhrase[grammar] = value;
                }
            }
            return(list);
        }
        public void Update(string input)
        {
            if (!enabled)
            {
                return;
            }

            var firstEquipmentOfType = new Dictionary <string, string> {
            };

            dynamic itemNameMap = LoadItemNameMap();

            commandsByGrammar.Clear();
            string[] itemTokens = input.Split('|');
            foreach (string itemStr in itemTokens)
            {
                try
                {
                    if (itemStr.Length == 0)
                    {
                        continue;
                    }

                    string[] tokens         = itemStr.Split(',');
                    string   itemName       = tokens[0];
                    long     formId         = long.Parse(tokens[1]);
                    long     itemId         = long.Parse(tokens[2]);
                    bool     isSingleHanded = int.Parse(tokens[3]) > 0;
                    int      typeId         = int.Parse(tokens[4]);

                    itemName = MaybeReplaceItemName(itemNameMap, itemName);
                    string command = formId + ";" + itemId + ";" + typeId + ";";

                    BuildAndAddGrammar(equipPhrasePrefix, Phrases.normalize(itemName), command, isSingleHanded);

                    // Are we looking at an equipment of some sort?
                    // Record the first item of a specific weapon type
                    string equipmentType = ProbableEquipmentType(itemName);
                    if (equipmentType != null && !firstEquipmentOfType.ContainsKey(equipmentType))
                    {
                        Trace.TraceInformation("ProbableEquipmentType: {0} -> {1}", itemName, equipmentType);
                        BuildAndAddGrammar(equipPhrasePrefix, Phrases.normalize(equipmentType), command, isSingleHanded);
                    }
                } catch (Exception ex) {
                    Trace.TraceError("Failed to parse {0} due to exception:\n{1}", itemStr, ex.ToString());
                }
            }

            PrintToTrace();
        }
        public void Update(string input)
        {
            if (Configuration.Get("Favorites", "enabled", "1") == "0")
            {
                return;
            }

            var firstEquipmentOfType = new Dictionary <string, string> {
            };

            dynamic itemNameMap = LoadItemNameMap();

            Trace.TraceInformation("Received favorites list: {0}", input);

            string equipPrefix = Configuration.Get("Favorites", "equipPhrasePrefix", "equip");

            commandsByGrammar.Clear();
            string[] itemTokens = input.Split('|');
            foreach (string itemStr in itemTokens)
            {
                try
                {
                    string[] tokens         = itemStr.Split(',');
                    string   itemName       = tokens[0];
                    long     formId         = long.Parse(tokens[1]);
                    long     itemId         = long.Parse(tokens[2]);
                    bool     isSingleHanded = int.Parse(tokens[3]) > 0;
                    int      typeId         = int.Parse(tokens[4]);

                    itemName = MaybeReplaceItemName(itemNameMap, itemName);

                    string phrase  = equipPrefix + " " + Phrases.normalize(itemName);
                    string command = formId + ";" + itemId + ";" + typeId + ";";

                    BuildAndAddGrammar(phrase, command, isSingleHanded);

                    // Are we looking at an equipment of some sort?
                    // Record the first item of a specific weapon type
                    string equipmentType = ProbableEquipmentType(itemName);
                    if (equipmentType != null && firstEquipmentOfType.ContainsKey(equipmentType) == false)
                    {
                        BuildAndAddGrammar(equipPrefix + " " + equipmentType, command, isSingleHanded);
                    }
                } catch (Exception ex) {
                    Trace.TraceError("Failed to parse {0} due to exception:\n{1}", itemStr, ex.ToString());
                }
            }

            PrintToTrace();
        }
        public void Update(string input)
        {
            if (Configuration.Get("Favorites", "enabled", "1") == "0")
            {
                return;
            }

            leftHandSuffix  = Configuration.Get("Favorites", "equipLeftSuffix", "left");
            rightHandSuffix = Configuration.Get("Favorites", "equipRightSuffix", "right");

            Trace.TraceInformation("Received favorites list: {0}", input);

            string equipPrefx = Configuration.Get("Favorites", "equipPhrasePrefix", "equip");

            commandsByGrammar.Clear();
            string[] itemTokens = input.Split('|');
            foreach (string itemStr in itemTokens)
            {
                try {
                    string[] tokens         = itemStr.Split(',');
                    string   itemName       = tokens[0];
                    long     formId         = long.Parse(tokens[1]);
                    long     itemId         = long.Parse(tokens[2]);
                    bool     isSingleHanded = int.Parse(tokens[3]) > 0;
                    int      typeId         = int.Parse(tokens[4]);

                    string phrase  = Phrases.normalize(equipPrefx + " " + itemName);
                    string command = formId + ";" + itemId + ";" + typeId + ";";

                    GrammarBuilder grammarBuilder = new GrammarBuilder(phrase);

                    // Append hand choice if necessary
                    if (isSingleHanded)
                    {
                        Choices handChoice = new Choices(new string[] { leftHandSuffix, rightHandSuffix });
                        grammarBuilder.Append(handChoice, 0, 1); // Optional left/right. When excluded, try to equip to both hands
                    }

                    Grammar grammar = new Grammar(grammarBuilder);
                    grammar.Name = phrase;
                    commandsByGrammar[grammar] = command;
                } catch (Exception ex) {
                    Trace.TraceError("Failed to parse {0} due to exception:\n{1}", itemStr, ex.ToString());
                }
            }

            PrintToTrace();
        }
        private DialogueList(long id, List <string> lines, Configuration config)
        {
            this.id     = id;
            this.config = config;

            SubsetMatchingMode matchingMode   = config.getConfiguredMatchingMode();
            List <string>      goodbyePhrases = config.GetGoodbyePhrases();

            for (int i = 0; i < lines.Count; i++)
            {
                string line = lines[i];
                if (line == null || line.Trim() == "")
                {
                    continue;
                }
                try {
                    Grammar g = new Grammar(config.IsSubsetMatchingEnabled() ? new GrammarBuilder(line, matchingMode) : new GrammarBuilder(line));
                    grammarToIndex[g] = i;
                }
                catch (Exception ex) {
                    Trace.TraceError("Failed to create grammar for line {0} due to exception:\n{1}", line, ex.ToString());
                }
            }

            foreach (string phrase in goodbyePhrases)
            {
                if (phrase == null || phrase.Trim() == "")
                {
                    continue;
                }
                Trace.TraceInformation("Found goodbye phrase: '{0}'", phrase);
                try {
                    Grammar g = new Grammar(new GrammarBuilder(Phrases.normalize(phrase), matchingMode));
                    grammarToIndex[g] = -2;
                } catch (Exception ex) {
                    Trace.TraceError("Failed to create grammar for exit dialogue phrase {0} due to exception:\n{1}", phrase, ex.ToString());
                }
            }
        }
        public FavoritesList(Configuration config)
        {
            this.config       = config;
            commandsByGrammar = new Dictionary <Grammar, string>();

            enabled            = config.Get("Favorites", "enabled", "1") == "1";
            useEquipHandPrefix = config.Get("Favorites", "useEquipHandPrefix", "0") == "1";

            knownEquipmentTypes = config.Get("Favorites", "knownEquipmentTypes", DEFAULT_KNOWN_EQUIPMENT_TYPES)
                                  .Split(';').Select((x) => x.ToLower()).ToList();
            if (knownEquipmentTypes.Count == 1 && knownEquipmentTypes[0].Length == 0)
            {
                knownEquipmentTypes.Clear();
                Trace.TraceInformation("Known Equipment Types Disabled");
            }
            else
            {
                // Sort in reverse order of string length to avoid prefix masking.
                // Consider "axe" and "battleaxe", the former is the prefix of the latter.
                // If the order is not correct, the latter will never have a chance to be matched.
                // Note: Adding leading space alleviates the problem, but some languages don't add spaces between words.
                knownEquipmentTypes.Sort((x, y) => y.Length - x.Length);
                Trace.TraceInformation("Known Equipment Types: \"{0}\"", string.Join("\", \"", knownEquipmentTypes.ToArray()));
            }

            leftHandSuffix = config.Get("Favorites", "equipLeftSuffix", "left")
                             .Split(';').Select((x) => Phrases.normalize(x)).ToArray();
            rightHandSuffix = config.Get("Favorites", "equipRightSuffix", "right")
                              .Split(';').Select((x) => Phrases.normalize(x)).ToArray();
            bothHandsSuffix = config.Get("Favorites", "equipBothSuffix", "both")
                              .Split(';').Select((x) => Phrases.normalize(x)).ToArray();

            List <string> equipPrefixList = config.Get("Favorites", "equipPhrasePrefix", "equip")
                                            .Split(';').Select((x) => Phrases.normalize(x)).ToList();

            for (int i = equipPrefixList.Count - 1; i >= 0; i--)
            {
                if (equipPrefixList[i].Length == 0)
                {
                    equipPrefixList.RemoveAt(i);
                    omitHandSuffix = true;
                }
            }
            equipPhrasePrefix = equipPrefixList.ToArray();

            mainHand = config.Get("Favorites", "mainHand", "none");

            // Determine the main hand used when user didn't ask for a specific hand.
            //
            // If an initializer is used and the key name conflicts (such as bothHandsSuffix == "both"),
            // an System.ArgumentException will be thrown. So assigning values one by one is a safer way.
            var mainHandMap = new Dictionary <string, string> {
                // Comment of `mainHand` in `DragonbornSpeaksNaturally.SAMPLE.ini` said:
                // > Valid values are "right", "left", "both"
                // We should keep the compatibility to prevent user confusion.
                ["both"]  = "0",
                ["right"] = "1",
                ["left"]  = "2"
            };

            // Use assignment statements to avoid key conflicts.
            bothHandsSuffix.Select((x) => mainHandMap[x] = "0");
            rightHandSuffix.Select((x) => mainHandMap[x] = "1");
            leftHandSuffix.Select((x) => mainHandMap[x]  = "2");

            if (mainHandMap.ContainsKey(mainHand))
            {
                mainHandId = mainHandMap[mainHand];
            }
            else
            {
                // User does not specify the main hand. Equipped with both hands by default.
                mainHandId = "0";
            }
        }
        public FavoritesList(Configuration config)
        {
            this.config       = config;
            commandsByGrammar = new Dictionary <Grammar, string>();

            enabled            = config.Get("Favorites", "enabled", "0") == "1";
            leftHandMode       = config.Get("Favorites", "leftHandMode", "0") == "1";
            useEquipHandPrefix = config.Get("Favorites", "useEquipHandPrefix", "1") == "1";
            useEquipHandInfix  = config.Get("Favorites", "useEquipHandInfix", "1") == "1";
            useEquipHandSuffix = config.Get("Favorites", "useEquipHandSuffix", "1") == "1";

            knownEquipmentTypes = config.Get("Favorites", "knownEquipmentTypes", DEFAULT_KNOWN_EQUIPMENT_TYPES)
                                  .Split(';').Select((x) => x.ToLower()).ToList();
            if (knownEquipmentTypes.Count == 1 && knownEquipmentTypes[0].Length == 0)
            {
                knownEquipmentTypes.Clear();
                Trace.TraceInformation("Known Equipment Types Disabled");
            }
            else
            {
                // Sort in reverse order of string length to avoid prefix masking.
                // Consider "axe" and "battleaxe", the former is the prefix of the latter.
                // If the order is not correct, the latter will never have a chance to be matched.
                // Note: Adding leading space alleviates the problem, but some languages don't add spaces between words.
                knownEquipmentTypes.Sort((x, y) => y.Length - x.Length);
                Trace.TraceInformation("Known Equipment Types: \"{0}\"", string.Join("\", \"", knownEquipmentTypes.ToArray()));
            }

            leftHandSuffix  = Phrases.normalize(config.Get("Favorites", "equipLeftSuffix", "off;left").Split(';'), config);
            rightHandSuffix = Phrases.normalize(config.Get("Favorites", "equipRightSuffix", "main;right").Split(';'), config);
            bothHandsSuffix = Phrases.normalize(config.Get("Favorites", "equipBothSuffix", "both").Split(';'), config);

            if (leftHandMode)
            {
                LEFT_HAND_ID  = "1";
                RIGHT_HAND_ID = "2";
            }
            else
            {
                LEFT_HAND_ID  = "2";
                RIGHT_HAND_ID = "1";
            }
            BOTH_HAND_ID = "0";

            equipPhrasePrefix = Phrases.normalize(config.Get("Favorites", "equipPhrasePrefix", "equip;wear;use").Split(';'), config);

            omitHandSuffix = config.Get("Favorites", "omitHandSuffix", "0") == "1";

            string mainHand = config.Get("Favorites", "mainHand", "right");

            mainHandId = getMainHandId(mainHand);

            string spellMainHand = config.Get("Favorites", "spellMainHand", "");

            if (spellMainHand != "")
            {
                spellMainHandId = getMainHandId(spellMainHand);
            }

            string weaponMainHand = config.Get("Favorites", "weaponMainHand", "");

            if (weaponMainHand != "")
            {
                weaponMainHandId = getMainHandId(weaponMainHand);
            }
        }