Хае представителям расы программистов, кодеров и прочей нечисти ….Итак, речь пойдет о том, как заставить заговорить компьютер и главное, чтобы он хоть немного понимал, что вы говорите и отвечал. Да – да, именно говорил с вами. Тема не новая, многими уже расписана, поэтому не надо кричать, что то в духе «Чувак, это олд скул», когда я искал материал на эту тему я выдирал ее по кусочкам, а тут все вместе будет. Предисловие к идеи: познакомился с одной очень красивой, умной и милой девушкой, мне она сразу понравилась. Естественно, встал вопрос о том, как сказать ей это по – нашему, по – программерский, я тут не буду расписывать про цветы и все такое, так как речь не о том, как понравиться девушке (здесь работает только один принцип: «Влюбитесь в девушку и она влюбиться в вас»), но концепция понятна……….(кстати, если ты это читаешь: «Привет, милая! Вот как выглядит эта магия.») Итак, что нам понадобиться? 1) Руки из нужного места и навык программирования на языке высокого уровня(в моем случае это C#) 2) Библиотека распознавания SpeechLib.dll (за ней можете стукнуть в лс) 3) Установленный синтезатор голоса в моем случае RHVoice. 4) Библиотека для работы со звуком NAudio.dll 5) Понимание, что такое нейронная сеть и как она работает (класс нейронки настроен под общение о девушке поэтому вряд ли она вам понадобиться) Начнем естественно с захвата звука из микрофона, тут нам на помощь придет либа NAudio 1) Итак подключаем либу к шарпу (если вы не знаете как это сделать, то начните с вывода на экран «Привет, мир») Для того, чтобы все заработала и звук писался с майка необходимо явно определить событие Из листинга 1. В нем мы просто вызывает наш event с шаблонным делегатом: Событие определили, теперь, конечно, нам нужен сам объект и подписаться на сие событие: Но мы программисты засранцы еще те, поэтому мы забыли определить другое событие, а именно, остановка записи, которое будет срабатывать вызовом метода StopRecording()! Итак вешаем на кнопку «Начать запись» следующий код Code: wave = new WaveIn(); //Дефолтное устройство для записи (если оно имеется) wave.DeviceNumber = 0; //Прикрепляем к событию DataAvailable обработчик, возникающий при наличии записываемых данных wave.DataAvailable += waveIn_DataAvailable; //Прикрепляем обработчик завершения записи wave.RecordingStopped += waveIn_RecordingStopped; //Формат wav-файла - принимает параметры - частоту дискретизации и количество каналов(здесь mono) wave.WaveFormat = new WaveFormat(8000, 1); //Инициализируем объект WaveFileWriter writer = new WaveFileWriter(FILE_NAME, wave.WaveFormat); //Начало записи wave.StartRecording(); В данном случае имя файла находиться в константе FILE_NAME И в дальнейшем я доработал это дело до частотного анализа, чтобы не приходилось нажимать кнопки, но в силу на тот момент ограниченности времени (так как у меня времени было меньше 5 часов, до встречи) мне пришлось действовать именно так. Кому интересно могу скинуть доработку с UI графикой и полной автоматизацией. А теперь к делу, звук то мы записали, всё, мы клевые парни, но это только начало пути, теперь машина должна понять, че вы там нагородили ей в микрофон. Для этого, мы конечно будем использовать уже всем нам полюбившуюся распознавалочку от гугл! Вот тут – то нам и понадобиться либа (собственного написания) SpeechLib.dll (не путать со стандартной либой встроенной в любую ОС от Майкрософта). В принципе, внутренности опишу вкратце, сначала мы конвертирует из Wave во формат Flac, так как именно этот формат гугл принимает, после чего собственно его и отправляем на гугл, и читаем уже ответ в формате JSon. В моем случае пришлось применить еще либу CUETools для перевода формата……..а после реализации дело свелось только к вызове двух методов: Итак останавливаем запись с помощью метода: Code: wave.StopRecording(); И собственно начинаем само распознавание: Code: label1.Text = JSon.Parse(SpeechLibBySooLFAA.SendFileRequest(FILE_NAME, "voice.flac")).hypotheses[0].utterance; в одну строчку мы вызываем все действия: конвертирование – отсылка – чтение ответа – парсинг в объект формата JSon. УРА! Мы получили распознанный текст, теперь дело нашей нейронки, класс нейронной сети подбирался с помощью Neuro. Обучение происходило шаблонами…..я не буду описывать как писать нейронку так как это выходит за рамки данной статьи, просто скажу что она содержала. Во – первых, конечно программа должна была поздороваться со мной, если я произношу свое имя в разном контексте и здороваюсь сам с ней. Во – вторых, я должен представить программе девушку, опять же в разных контекстах программа в общем должна понять и отреагировать примерно так: - (Я)«Знакомься – это девушка, <Имя девушки>!» - (Программа)«<Имя девушки>, очень приятно, (представляется, говорит, что я рассказывал ей про эту девушку, и что она мне нравится)» - Дальше я с ней начинаю сердито ругаться, чтобы мол программа не болтала лишнего, а она наоборот должна была настоять на своем, обвинить меня в том, что нечего стрематься и так далее….. после нашего диалога, программа уже сама включает красивую музыку и выводит сообщение с признанием…… (Вот так мне удалось оригинально немного удивить девушку) В планах разработать программу по типу «Умный дом» и основные рутинные действия перенести на голос. Ну а сам синтез проще простого, установив RHVoicе мы используем стандартный .Net класс SpeechSynthesizer. Сам код выглядит вот так: Code: SpeechSynthesizer speaker = new SpeechSynthesizer(); speaker.SelectVoice("RHVoice Elena (Russian)"); //выбор голоса speaker.Rate = 1; //Десритизация speaker.Volume = 100; //Уровень звука speaker.SpeakAsync(Neuro.Answer(label.text)); //Метод для воспроизведения Ну вот в принципе и все, статья обозреватель, поэтому детализировано писать не вижу смысла….Ну а чем все кончилось?! А это уже [Access Denied]. Code: Листинг 1. Начало записи. void waveIn_DataAvailable(object sender, WaveInEventArgs e) { if (this.InvokeRequired) { this.BeginInvoke(new EventHandler<WaveInEventArgs>(waveIn_DataAvailable), sender, e); } else { //Записываем данные из буфера в файл writer.WriteData(e.Buffer, 0, e.BytesRecorded); } } Листинг 2. Остановка записи! private void waveIn_RecordingStopped(object sender, EventArgs e) { if (this.InvokeRequired) { this.BeginInvoke(new EventHandler(waveIn_RecordingStopped), sender, e); } else { wave.Dispose(); wave = null; writer.Close(); writer = null; } }
SpeechLib.dll? А чем тебя не устроил Google SpeechAPI? У гугла на данный момент самая лучшая система распознавания речи вообще и русской в частности. А вообще все это игрушки, не более... Для мобильных удобно набирать текст и делать поисковые запросы, на ПК абсолютно не нужно. п.с. Когда заголовок увидел, решил ты драйвера на .NET писать решил.
1) Он Платный. 2) Да самая лучшая, но это не исключает 1. 3) Не согласен, я на базе этой технологии построил голосовое управление железом. (принцип нейронной сети, обучается весьма не плохо) 4) Надо быть полным извращенцем и ненавидеть всё что связано с IT, чтобы писать драйвера на .Net.