Голосовое распознавание

я на delphi такую поделку встречал давно, правда там полноценное управление ПК голосом было, на сколько знаю проект и компоненты стали платными.

Не понял как цитаты в одном сообщении разместить поэтмоу отдельно скажу.
У авесомиума было неплохое взаимодействие со скриптами на странице. Там можно было внедрять свой код на лету и получать ответ.
Эти браузеры я рассматривал ранее и чтото в них не пошло. Почему то же я их отставил в сторонку. А тут получается что мне нужно аудиопоток отправить на сервер а обратно перехватить текст.

Оказывается есть либа, которая автоматом биндит кресты в шарпы.

Вот это прикольно … Не видел. ))

Так мало того что бесплатно дают. Гугл тоже дает час в месяц. Для использования программы в поле этого не хватит.

Нормально там дают)) https://cloud.google.com/speech-to-text/quotas

как и на старом ПФ, выделить и появится кнопка.

Он только в самом Хроме от Гугла.
Может быть можно через Селениум извратиться, но думаю там есть какой-то лимит, а то б все так делали.

Speech API не бесплатен и не бесконечен.

Да не особо …

А вы указываете на лимиты загрузки. То есть максимум в сутки вы можете обработать 480 часов аудио. Но и заплатите за это из расчета 0,016 доллара за единицу.

До появления всех этих сервисов вроде ж было много и обычных оффлайн библиотек. Вопрос наверно только в качестве.

Например это вроде бесплатно https://docs.microsoft.com/en-us/archive/msdn-magazine/2014/december/voice-recognition-speech-recognition-with-net-desktop-applications

Они не поддерживают русский язык. И то что вы привели может распознавать только заготовленные фразы. С развитием облаков оффлайн распознавание как то приглохло. Сейчас вот кое как расковырял сфинкса. Вроде распознает чего то … но как то тоскливо. путается и лишнее выводит. Да и отклик долгий

5 пост был перенесен в новую тему: CppSharp пользовался кто-нибудь? (использование C++ библиотек в C#)

Его не сложно поставить, но

вряд ли поможет. В Хроме ж вроде просто вшит ключ API гугла или типа того. https://code.google.com/archive/p/chromiumembedded/issues/1297 —> http://www.chromium.org/developers/how-tos/api-keys

для теста/прототипа думаю проще всего

В целом качественная халява вряд ли пока существует :clkolsad:

Более того, это урезанный хром, исключительно для рендера UI. Скорее всего всё лишнее там отсутствует напрочь.

Посмотри как оборнута им ChakraCore.
Да, нужно указать путь к заголовоному файлу где описаны экспортируемые функции, либа парсит файл и генерирует импорты.

Я думаю правильный ответ на сабж - никак :slight_smile: Бесплатно поиметь гугл не получится. Нужно идти брать ключик, прописывать его и будет работать в CefSharp. Я пытался:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using CefSharp;
    using CefSharp.WinForms;
    namespace CefCallAPITest
    {
        static class Program
        {
            /// <summary>
            /// Главная точка входа для приложения.
            /// </summary>
            [STAThread]
            static void Main()
            {
                var settings = new CefSettings();
                settings.CefCommandLineArgs.Add("enable-speech-input","1");
                Cef.Initialize(settings);
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
                Cef.Shutdown();
            }
        }
    }

Форма:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using CefSharp;

    namespace CefCallAPITest
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            private void btnCallSomeAPI_Click(object sender, EventArgs e)
            {
                Task<JavascriptResponse> response = chrome.EvaluateScriptAsync(scriptBox.Text);
                response.Wait();
                if (response.Result.Success)
                {
                    dynamic res = response.Result.Result;
                    scriptBoxOut.Text = Convert.ToString(res);
                } else
                {
                    scriptBoxOut.Text = "Error: "+response.Result.Message;
                }

            }

            private void btnGoogle_Click(object sender, EventArgs e)
            {
                chrome.Load("http://127.0.0.1:1646/");
            }
        }
    }

Форма-код:

    namespace CefCallAPITest
    {
        partial class Form1
        {
            /// <summary>
            /// Обязательная переменная конструктора.
            /// </summary>
            private System.ComponentModel.IContainer components = null;

            /// <summary>
            /// Освободить все используемые ресурсы.
            /// </summary>
            /// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }

            #region Код, автоматически созданный конструктором форм Windows

            /// <summary>
            /// Требуемый метод для поддержки конструктора — не изменяйте 
            /// содержимое этого метода с помощью редактора кода.
            /// </summary>
            private void InitializeComponent()
            {
                this.gbBrowser = new System.Windows.Forms.GroupBox();
                this.chrome = new CefSharp.WinForms.ChromiumWebBrowser();
                this.btnGoogle = new System.Windows.Forms.Button();
                this.btnCallSomeAPI = new System.Windows.Forms.Button();
                this.scriptBox = new System.Windows.Forms.TextBox();
                this.scriptBoxOut = new System.Windows.Forms.TextBox();
                this.editUrl = new System.Windows.Forms.TextBox();
                this.label1 = new System.Windows.Forms.Label();
                this.gbBrowser.SuspendLayout();
                this.SuspendLayout();
                // 
                // gbBrowser
                // 
                this.gbBrowser.Controls.Add(this.chrome);
                this.gbBrowser.Dock = System.Windows.Forms.DockStyle.Top;
                this.gbBrowser.Location = new System.Drawing.Point(0, 0);
                this.gbBrowser.Name = "gbBrowser";
                this.gbBrowser.Size = new System.Drawing.Size(800, 235);
                this.gbBrowser.TabIndex = 0;
                this.gbBrowser.TabStop = false;
                this.gbBrowser.Text = "Browser";
                // 
                // chrome
                // 
                this.chrome.ActivateBrowserOnCreation = false;
                this.chrome.Dock = System.Windows.Forms.DockStyle.Fill;
                this.chrome.Location = new System.Drawing.Point(3, 18);
                this.chrome.Name = "chrome";
                this.chrome.Size = new System.Drawing.Size(794, 214);
                this.chrome.TabIndex = 0;
                // 
                // btnGoogle
                // 
                this.btnGoogle.Location = new System.Drawing.Point(688, 241);
                this.btnGoogle.Name = "btnGoogle";
                this.btnGoogle.Size = new System.Drawing.Size(112, 29);
                this.btnGoogle.TabIndex = 1;
                this.btnGoogle.Text = "Lest\'s ROCK!";
                this.btnGoogle.UseVisualStyleBackColor = true;
                this.btnGoogle.Click += new System.EventHandler(this.btnGoogle_Click);
                // 
                // btnCallSomeAPI
                // 
                this.btnCallSomeAPI.Location = new System.Drawing.Point(688, 409);
                this.btnCallSomeAPI.Name = "btnCallSomeAPI";
                this.btnCallSomeAPI.Size = new System.Drawing.Size(100, 29);
                this.btnCallSomeAPI.TabIndex = 2;
                this.btnCallSomeAPI.Text = "Run JS";
                this.btnCallSomeAPI.UseVisualStyleBackColor = true;
                this.btnCallSomeAPI.Click += new System.EventHandler(this.btnCallSomeAPI_Click);
                // 
                // scriptBox
                // 
                this.scriptBox.Location = new System.Drawing.Point(12, 289);
                this.scriptBox.Multiline = true;
                this.scriptBox.Name = "scriptBox";
                this.scriptBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
                this.scriptBox.Size = new System.Drawing.Size(776, 114);
                this.scriptBox.TabIndex = 3;
                // 
                // scriptBoxOut
                // 
                this.scriptBoxOut.Enabled = false;
                this.scriptBoxOut.Location = new System.Drawing.Point(15, 416);
                this.scriptBoxOut.Name = "scriptBoxOut";
                this.scriptBoxOut.Size = new System.Drawing.Size(667, 22);
                this.scriptBoxOut.TabIndex = 4;
                // 
                // editUrl
                // 
                this.editUrl.Location = new System.Drawing.Point(12, 244);
                this.editUrl.Name = "editUrl";
                this.editUrl.Size = new System.Drawing.Size(670, 22);
                this.editUrl.TabIndex = 5;
                this.editUrl.Text = "http://127.0.0.1:1646/";
                // 
                // label1
                // 
                this.label1.AutoSize = true;
                this.label1.Location = new System.Drawing.Point(12, 269);
                this.label1.Name = "label1";
                this.label1.Size = new System.Drawing.Size(109, 17);
                this.label1.TabIndex = 6;
                this.label1.Text = "JS code to eval:";
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(800, 450);
                this.Controls.Add(this.label1);
                this.Controls.Add(this.editUrl);
                this.Controls.Add(this.scriptBoxOut);
                this.Controls.Add(this.scriptBox);
                this.Controls.Add(this.btnCallSomeAPI);
                this.Controls.Add(this.btnGoogle);
                this.Controls.Add(this.gbBrowser);
                this.Name = "Form1";
                this.Text = "Form1";
                this.gbBrowser.ResumeLayout(false);
                this.ResumeLayout(false);
                this.PerformLayout();

            }

            #endregion

            private System.Windows.Forms.GroupBox gbBrowser;
            private CefSharp.WinForms.ChromiumWebBrowser chrome;
            private System.Windows.Forms.Button btnGoogle;
            private System.Windows.Forms.Button btnCallSomeAPI;
            private System.Windows.Forms.TextBox scriptBox;
            private System.Windows.Forms.TextBox scriptBoxOut;
            private System.Windows.Forms.TextBox editUrl;
            private System.Windows.Forms.Label label1;
        }
    }

Собственно скрипт на вебе:

    <!doctype html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Sample</title>
      alert(13);
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <script type="text/javascript">
      
    function readOutLoud(message) {
      var speech = new SpeechSynthesisUtterance();

      // Set the text and voice attributes.
      speech.text = message;
      speech.volume = 1;
      speech.rate = 1;
      speech.pitch = 1;

      window.speechSynthesis.speak(speech);
    }

    	function speakit() {
    		readOutLoud(document.getElementById('text').value);
    	};

      </script>
    </head>
    <body>
    	<label for="#text">text to speak:</label>
    	<input type="text" id="text"/>
    	<br/>
    	<button onclick="speakit()">speak it!</button>
    </body>
    </html>

Так тогда можно и с браузерами не париться, если не веб-приложение нужно )

Нужно чтобы приложуха могла голосом вводить данные в свои поля. в идеале без интернета, но уже согласны и на интернет.
Вот есть такая штука но она работает не удобно. Надо все время кнопку нажимать на странице сайта. То есть нужен аналог и чтобы включалось из приложения дектопного.

А если свою написать?
Реализовать MFCC как описано здесь:


Скользящее окно, БПФ , треугольные фильтры и функция пересчёта частот.

Полученные коэффициенты подаём на нейронную сеть ANN. Размер скользящего окна подбираем так что-бы у нас была N-грамма из 3-х фонем(букв). Идём с перекрытием в 33%.
Из 3-х результатов на каждую букву берём медиану.

Потом удаляем повторяющиеся гласные, проверяем по словарю на частоту встречи слов.

Для обучения ANN используем датасет.

БПФ:
https://web.archive.org/web/20140808002054/http://psi-logic.shadanakar.org/fft/fftf.htm
http://rosettacode.org/wiki/Fast_Fourier_transform
ANN можно взять здесь:
https://cs.stanford.edu/~karpathy/svmjs/demo/demonn.html
https://cs.stanford.edu/~karpathy/svmjs/lib/nn.js
Метод обучения AdataDelta.
https://cs.stanford.edu/people/karpathy/convnetjs/demo/trainers.html
Частотный словарь словоформ
http://www.ruscorpora.ru/new/corpora-freq.html
Словарь лучше сделать самому, так как тут словоформы нормализованы(приведены к одному падежу). Другими словами потеряна информация о окончании.

Я в вузе делал с помощью HTK http://htk.eng.cam.ac.uk/
Получилось плохое качество, даже при том что надо было распознавать только себя после тренировки системы на нескольких главах Белого Клыка :donald:

Это не студенческий проект. Тут времени не хватит если ковырять все самому.
Сфинкса получилось подключить к шарпу через DllImport. Распознает в целом неплохо. Читал что можно как то самому натренировать базу что очень вдохновляет.
Так что всем кому нужно офлайн распознавание можно использовать. )