Некоторые сталкиваются с тем что необходимо распознать речь перевести её в текст и обработать. Проблема описывалась много раз как впрочем и пути её решения так что Google в помощь, но вот я столкнулся на собственном опыте с проблемой которая потребовала нетривиального решения, а именно как заставить распознавать речь с микрофона которые не установлен «по умолчанию». Если вы тоже столкнулись с подобной проблемой то эта статья именно для вас.
Итак что мы имеем — есть два различных движка для распознавания речи в Microsoft Windows (стандартный и Microsoft Speech SDK 11) причём сразу скажу что русский язык поддерживает пока только один из них, а именно Microsoft Speech SDK 11 с установленным русским языком. Если внимательно прочитать документацию по обоим движкам, то видно что в качестве устройства можно выбрать только DefaultInputDevice, но копнув глубже, а именно открыв сборку декомпилятором Telerik JustDecompile я убедился что все классы являются лишь обёрткой над СОМ объектами, а как раз в этих СОМ объектах нужная функция есть. Естественно что как и все программисты я ленивый и работать с СОМ не хотел, поэтому совмести два решения. Итак первое что нам необходима это найти Token нужного нам микрофона для этого существует следующая функция:
Итак что мы имеем — есть два различных движка для распознавания речи в Microsoft Windows (стандартный и Microsoft Speech SDK 11) причём сразу скажу что русский язык поддерживает пока только один из них, а именно Microsoft Speech SDK 11 с установленным русским языком. Если внимательно прочитать документацию по обоим движкам, то видно что в качестве устройства можно выбрать только DefaultInputDevice, но копнув глубже, а именно открыв сборку декомпилятором Telerik JustDecompile я убедился что все классы являются лишь обёрткой над СОМ объектами, а как раз в этих СОМ объектах нужная функция есть. Естественно что как и все программисты я ленивый и работать с СОМ не хотел, поэтому совмести два решения. Итак первое что нам необходима это найти Token нужного нам микрофона для этого существует следующая функция:
private SpeechLib.SpObjectToken FindMicByName(string name) { if (isot != null) { for (int i = 0; i < isot.Count; i++) { sot = isot.Item(i); string desc = sot.GetDescription(1033); string id = sot.Id; if (desc.Contains(name) != false) { break; } } return sot; } else return null; }
После того как мы получим Token необходимо вызвать приватные методы у класса «движка» распознавания для этого используется следующая функция:
public void SetMicByName(string name, ref System.Speech.Recognition.SpeechRecognitionEngine sre) { if (isot != null) { sre.SetInputToDefaultAudioDevice(); sot = FindMicByName(name); if (sot != null) { FieldInfo fi = sre.GetType().GetField("_sapiRecognizer", BindingFlags.Instance | BindingFlags.NonPublic); object _sapiRecognizer = fi.GetValue(sre); MethodInfo mi = _sapiRecognizer.GetType().GetMethod("SetInput", BindingFlags.Instance | BindingFlags.NonPublic); object[] parms = new object[] { sot, true }; mi.Invoke(_sapiRecognizer, parms); } } }
В конце я приведу полный текст вспомогательного класса, который используется в моей разработке, Вы можете использовать его полностью или частично или просто вставить необходимые фрагмента кода себе. Всё это проверенно на Windows 7,8,8.1 ,NET 4.0, 4.5, но думаю что и с другими версиями будет работать также.
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; namespace RMI.SmartHouse.Service { /// <summary> /// Позволяет осуществить выбор микрофонов. /// </summary> public class MicSelector : IDisposable { #region Приватные поля SpeechLib.SpInProcRecoContext siprc; SpeechLib.ISpeechObjectTokens isot; SpeechLib.SpObjectToken sot; #endregion #region Конструкторы /// <summary> /// Конструктор по умолчанию. /// </summary> public MicSelector() { siprc = new SpeechLib.SpInProcRecoContext(); isot = siprc.Recognizer.GetAudioInputs(null, null); sot = null; } #endregion #region Публичные свойства /// <summary> /// Список доступных устройств. /// </summary> public SpeechLib.ISpeechObjectTokens Isot { get { return this.isot; } private set { this.isot = value; } } #endregion #region Публичные методы /// <summary> /// Устанавливает выбранный микрофон. /// </summary> /// <param name="name">Имя микрофона. /// <param name="sre">Движок для распознавания. public void SetMicByName(string name, ref System.Speech.Recognition.SpeechRecognitionEngine sre) { if (isot != null) { sre.SetInputToDefaultAudioDevice(); sot = FindMicByName(name); if (sot != null) { FieldInfo fi = sre.GetType().GetField("_sapiRecognizer", BindingFlags.Instance | BindingFlags.NonPublic); object _sapiRecognizer = fi.GetValue(sre); MethodInfo mi = _sapiRecognizer.GetType().GetMethod("SetInput", BindingFlags.Instance | BindingFlags.NonPublic); object[] parms = new object[] { sot, true }; mi.Invoke(_sapiRecognizer, parms); } } } /// <summary> /// Устанавливает выбранный микрофон. /// </summary> /// <param name="name">Имя микрофона. /// <param name="sre">Движок для распознавания. public void SetMicByName(string name, ref Microsoft.Speech.Recognition.SpeechRecognitionEngine sre) { if (isot != null) { sre.SetInputToDefaultAudioDevice(); sot = FindMicByName(name); if (sot != null) { FieldInfo fi = sre.GetType().GetField("_sapiRecognizer", BindingFlags.Instance | BindingFlags.NonPublic); object _sapiRecognizer = fi.GetValue(sre); MethodInfo mi = _sapiRecognizer.GetType().GetMethod("SetInput", BindingFlags.Instance | BindingFlags.NonPublic); object[] parms = new object[] { sot, true }; mi.Invoke(_sapiRecognizer, parms); } } } /// <summary> /// Обновляет список доступных устройств. /// </summary> /// <returns>Список доступных устройств.</returns> public SpeechLib.ISpeechObjectTokens UpdateDeviceList() { if (siprc != null) { isot = siprc.Recognizer.GetAudioInputs(null, null); return isot; } else { return null; } } /// <summary> /// Освобождение ресурсов. /// </summary> public void Dispose() { if (sot != null) { sot = null; } if (isot != null) { isot = null; } if (siprc != null) { siprc = null; } GC.Collect(); } #endregion #region Приватные функции /// <summary> /// Поиск микрофона по имени. /// </summary> /// <param name="name">Имя для поиска. /// <returns>Токен микрофона.</returns> private SpeechLib.SpObjectToken FindMicByName(string name) { if (isot != null) { for (int i = 0; i < isot.Count; i++) { sot = isot.Item(i); string desc = sot.GetDescription(1033); string id = sot.Id; if (desc.Contains(name) != false) { break; } } return sot; } else return null; } #endregion } }
ссылка на оригинал статьи http://habrahabr.ru/post/214635/
Добавить комментарий