English version of this page while is not ready.
Please use google-translate (see upper right conner of this page)

Download last version VoiceToText:


The program is distributed as an archive and does not require installation.
After unpacking the archive ("to the current folder") is completely ready to work.

Если вам нужны языки, которые не входит в комплект, то можете сами их добавить, а флаги взять из архива по этой ссылке (их там 240 штук).

Голоса для озвучки можно найти на множестве ресурсов в интернете, например, вот хорошая подборка.

P.S. Не забудьте измерить "уровень тишины" (и поиграть его значениями, если результат не очень).


Примечание:
Видео по программе начиная с версии 1.0.1.8 очень сильно устарело. Переписывать их после каждого обновления долго, и видео будет переписано когда изменений накопится больше.
А пока, после просмотра видео, рекомендуется ознакомиться со всеми комментариями ("Что нового?") по выпускам версий.

В частности, очень рекомендую почитать про функциональность "замен", в описании версии 1.0.1.8, а затем продолжить знакомство с заменами в описании версии 2.0.0.0.


Старые пользователи программы, очевидно, заметили, что некоторые апгрейды надо самим скачивать с сайта, а некоторые идут автоматически (программа сама умеет скачивать и обновлять вашу версию).

Почему так?
Дело в том, что если необходимо обновить только исполняемые файлы (exe или dll файлы), то программа справляется с этим сама. Однако, в программе для пользователя заложена возможность изменять и расширять некоторый функционал, редактируя и создавая файлы в папке \options\. Поэтому, если в новой версии изменяется содержимое этой папоки, то самостоятельно принять решение - что там нужно изменить, а что нет, программа не может. Ведь так можно запросто затереть плоды вашего творчества ("все что нажито непосильным трудом").

Внимание! При скачивании с сайта новой версии, если вы сами разрабатывали новые "замены" и "функции", то, конечно же, случайно не удалите сразу папку со старой версией программы - не забудьте предварительно перенести все ваши "нажитые непосильным трудом" собственные расширения в новую версию.


Version 2.0.2.1

  • Глобальные горячие клавиши.

    Добавлена глобальная горячая клавиша для включения/выключения записи (распознавания речи).
    По умолчанию это [Alt+V], но вы можете поменять комбинацию клавиш на любую другую в новом разделе "H.Keys" (Горячие клавиши) в окне опций.

    Почему "глобальная"?
    Обычно, горячие клавиши работают только внутри программы которая сейчас активна - в одной программе они одни, но если вы переключитесь на другую программу, они будут другие...
    Эта же горячая клавиша действует во всех программах, т.е. глобально во всей операционной системе. Неважно где вы находитесь - нажмите ее и запись включится или, если она уже включена, отключится.

    Если вы находитесь в программе, которая запущена с правами администратора, то, чтобы глобальная клавиша работала внутри такой программы, VoiceToText тоже должна быть запущена с админскими правами.


    Обратите внимание, что как всегда, все элементы интерфейса и опции имеют тултипы (всплывающие подсказки) и если у вас включены русские тултипы, то незнание английского не будет для вас препятствием.


    • В разделе "H.Keys" окна опций, галочкой "Use global hot keys" можно отключить/включить глобальные горячие клавиши - по умолчанию они включены.
      Глобальные горячие клавиши выделены в этом разделе в отдельную группу, поскольку не исключаю, что появятся и просто горячие клавиши (локального действия - только внутри VoiceToText) если возникнет такая необходимость (пишите, если у вас возникнут идеи/предложения на этот счет).
    • У горячей клавиши также можете видеть настройку-галочку "Any (left/right)".
      Дело в том, что при назначении комбинации клавиш, модификаторы (Shift, Ctrl, Alt, Win) могут быть как правыми, так и левыми. И если вы определите комбинацию, например, нажав ее с левым Ctrl, то для правого Ctrl она уже не будет работать. Но если вы вдруг захотите, чтобы работал любой (левый/правый) Ctrl, то включите эту галочку.
    • Настройки глобальных горячих клавиш находится в файле '\options\shotKeysGlobal.json'.
      Не знаю зачем вам это нужно знать, поскольку их можно изменять в окне опций, разве что вы любитель редактировать настройки в тексте. Если так, то в файле '\options\_doc\KeyCodes.txt' можете найти справку по кодам клавиш. Хотя, в тексте, в отличии настроек в программе, можно переопределить не только актуальную комбинацию клавиш, но и ее значение по умолчанию. Если же вы удалите '\options\shotKeysGlobal.json', то он пересоздастся с базовыми настройками по умолчанию.

    Сейчас имеем только одну глобальную горячую клавишу, но пишите, если у вас будут идеи/предложения для определения каких-либо других, могущих быть вам полезными.
  • Авто-запуск программы вместе со стартом Windows.

    В разделе "General" окна опций, добавлена соответствующая галочка - "Starting Application on Windows startup", отметив которую вы обяжете программу запускаться вместе с Windows.

    По умолчанию она отключена.
  • Запуск программы с правами администратора.

    В разделе "General" окна опций, добавлена соответствующая галочка - "Run Application as admin".

    Зачем нужна?
    Как отмечалось в примечание при описании глобальных горячих клавиш: если вы находитесь в программе, которая запущена с правами администратора, то, чтобы глобальные клавиши работали внутри такой программы, VoiceToText тоже должна быть запущена с админскими правами.

    Сразу после выбора этой галочки, программа перезапускается с админскими правами (если вы, конечно, админ на своем компе).

    Хотя, разумеется, вы можете сделать это и вручную - просто закрыв программу и открыв ее ярлык уже от админа (а то и сразу создать ярлык для такого запуска).
    Существенная же польза этой галочки проявляется тогда, когда выбрана вышеописанная галочка авто-запуска программы с Windows (Starting Application on Windows startup). В этом случае при старте Windows программа сразу запустится от админа (конечно, как водится, с запросом разрешения на это).

    Если программа запущена от админа, то справа от этой галочки вы увидите сообщение об этом - "(running as admin now)" (русский тултип: "Программа сейчас выполняется в режиме администратора")

    По умолчанию опция отключена.
  • Функционал Speak функции расширен возможность добавить в ее вызов новый параметр - recOff.

    Более того, этот параметр теперь добавлен в определение замены "повторение SAPI голосом":
    "New": "fun|Speak|recOff"
    (раньше было просто "fun|Speak")

    Зачем он нужен?
    Если вы не в наушниках и озвучка идет на колонки, то ваш микрофон может "услышать" ее и соответственно распознать, опять озвучить... и т.д, что называется "пластинка заела". Добавление параметра recOff решает эту проблему - пока звучит озвучка, запись (распознавание речи) будет отключена.

    Но если вы в наушниках, или громкость колонок установлена небольшая, то можете убрать этот параметр (сделать как раньше), или определить дополнительную аналогичную замену без этого параметра и включать либо ее, либо замену по умолчанию в зависимости от ситуации.
    Очевидно, что при наличии recOff, программа во время озучки ваш голос тоже не будет воспринимать. Поэтому, если вы все же захотите одновременно и слушать и наговаривать текст и уверены, что программа не "услышит" озвучку, то удалите этот параметр, .

    Таким образом, варианты возможного синтаксиса вызова Speak функции сейчас такие:
    • "New": "fun|Speak|recOn"
      или, эквивалентно:
      "New": "fun|Speak"
      т.е. когда опускаем параметр, то он принимает значение по умолчанию - recOn.
    • "New": "fun|Speak|recOff"
    • "New": "fun|Speak|recOff|Имя голоса"
      если же вам запись нужна, то:
      "New": "fun|Speak|recOn|Имя голоса"
      или, еще проще, опуская параметр:
      "New": "fun|Speak||Имя голоса"
    Остальной функционал Speak функции остался прежним и вы можете почитать/освежить его описание здесь
  • Совсем чуть-чуть в паре мест подретуширован интерфейс.

Version 2.0.2.0

  • Коррекция регистра.

    Эта версия практически полностью посвящена коррекции регистра слов.
    Если вы активный пользователь программы, то наверняка замечали, что google-распознавание нередко возвращает слова в неправильном регистре. В этой версии добавленны инструменты, которые вам позволяют полностью контролировать этот аспект.

    А именно, добавлены:
    • Новая галочка Start text with upper (по умолчанию выключена) в окне опций на вкладке General. Если ее включить, то при старте записи текст будет начинаться c большой буквы.
    • Новая функциональная замена, которая так и называется "коррекция регистра" (для английского языка "case correction"). Если вы включите эту замену (по умолчанию она выключена), то весь текст будет идти в нижнем регистре, кроме случаев, которые явно заданы заменами (такими как "точка", "вопрос", "c большой буквы"...), а также слов определенных в специальных текстовых файлах.

      Эти файлы находится в папке '\options\externApi\properWords\'. Например, для русского языка это файл 'ru-RU.txt'. В нём сейчас находится приблизительно три с половиной тысячи собственных имен русского языка. Если при распознавании текста вы обнаружите, что некоторые слова, с вашей точки зрения, имеют неправильный регистр, то вы можете добавить их в этот файл в правильном регистре. Только не используйте букву "ё" - вместо неё пишите букву "е".

  • Исправлены мелкие (фактически косметические) недостатки.

Version 2.0.1.0

  • Новый способ вывода текста.

    Добавлен новый способ вывода текста под курсор, который теперь работает по умолчанию. Раньше вставка текста происходила через буфер обмена - программа передавала в буфер обмена распознанный текст и далее делала его вставку путем эмуляции нажатия клавиш [Ctrl+V] под курсором.
    Новый способ не связывается с буфером обмена, для вставки текста он просто эмулирует последовательное нажатие всех букв текста.

    В окне опции на вкладке General добавились настройки, которые позволяют выбрать способ вывода текста - новый (по умолчанию) или старый (через буфер обмена).
  • Галочка у групп.

    В редакторе замен, в выпадающем списке фильтра по группам, у каждой группы теперь имеется галочка. Она позволяет массово включать/выключать сразу все замены находящиеся в этой группе.

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

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

    Раньше каждой такой команде соответствовала своя функция определенная в одном из cs-файлов папки \options\externApi\. Сейчас же написана единая функция, а точнее две почти идентичные функции: KeyPress и ее расширенная версия KeysPress (на практике, если хотите, можно использовать только последнюю). Кому интересно, тот может посмотреть реализацию этих функций в файле \options\externApi\_common.cs (хотя для последующего изложения это совершенно не важно).

    Чтобы определить новую команду, достаточно передать комбинацию клавиш в качестве параметра на вход одной из этих универсальных функций. Например, если написать в качестве New:
    fun|KeyPress|CONTROL+VK_S
    то это будет соответствовать нажатию клавиш [Ctrl+S], что, как известно, является горячей клавишей сохранения документа. Именно так сейчас определена голосовая команда "сохранить документ [Ctrl+S]" (см. в редакторе замен).

    А команда "закрыть приложение [Alt+F4]" сейчас определяется через:
    fun|KeyPress|MENU+F4

    Допустимые названия всех клавиш (типа CONTROL, MENU, VK_S...) можно найти в файле \options\externApi\_KeyCodes.txt.

    Имеется множество справочников по горячим клавишам, из самого простого, например, см. ту же википедию.
    Так, вы можете определить команду для поиска, команду делающую скриншот, команду "выделить все" команду для печати, команду удаляющую последнее слово и т.д. и т.п...

    В параметре функции KeysPress, через "+", первыми идут так называемые клавиши-модификаторы, такие как SHIFT, MENU (т.е. [Alt]), CONTROL... последовательность которых заканчивается обычными клавишами такими как VK_S (т.е. [S]), VK_R (т.е. [R]), F4, TAB, LEFT, DELETE, RETURN..., которые тоже можно "нажать" одновременно через "&". Например:
    fun|KeyPress|SHIFT+CONTROL + VK_N & VK_J
    соответствует одновременному нажатию клавиш [Shift]+[Ctrl]+[N]+[J].

    Названия клавиш можно писать в любом регистре, а между разделителями типа "+" и "&" (далее появится еще ">") вставлять (для читабельности) пробелы - это никак не влияет на результат.


    Вместо KeyPress, с таким же успехом, в наших примерах можно было использовать KeysPress. Разница у них только в том, что KeysPress дополнительно позволяет эмулировать нажатие последовательности комбинаций клавиш и даже целых строк через ">" разделитель. Например:
    fun|KeysPress|SHIFT+CONTROL+LEFT > DELETE
    удалит последнее слово: сначала комбинация клавиш [Shift]+[Ctrl]+[Left] выделит последнее слово, а затем последующее нажатие на [Del] удалит его.

    На самом деле для этого действия уже есть комбинация [Ctrl]+[Backspace], но нам сейчас важно продемонстрировать простой пример последовательности нажатий.


    Более продвинутый пример:
    fun|KeysPress|LWIN+VK_R > 1000 > 'notepad' > 500 > RETURN
    он вызовет запуск блокнота (notepad).
    В нем видим цифры и строку 'notepad'. Цифры задают задержку в миллисекундах между нажатиями, а строка (определяется как нечто в одинарных кавычках) вызывает по-буквенное нажатие содержимого внутри кавычек, в нашем случае это печать строки notepad. Итак:
    - сначала комбинация клавиш [Win]+[R] откроет виндовое системное окошко "Выполнить"
    - задержка в 1 секунду достаточна чтобы это окошко успело открыться
    - далее идет печать notepad в поле "Открыть" этого окошка
    - опять, на всякий случай, небольшая задержка
    - и в конце нажатие на клавишу [Enter] (RETURN) собственно запустит блокнот
    Как понимаете, вместо блокнота, таким же способом, можно запускать и другие программы.

  • Использование т.н. "групп" регулярных выражений в функциональных заменах.

    Для не функциональных замен с регулярным выражением в Old, "группы" и раньше работали, просто специально об этом не писал. Это довольно мощная вещь, которая во многих случаях позволяет обойтись без написания специальных функций для замен.

    Если вы все еще не в курсе, то рекомендую хотя бы очень бегло ознакомится с таким одним из самых распространенных в IT понятием как Регулярные выражения.

    Пользователи Linux должны быть с этим понятием на "ты". В Windows же, если кто пользовался поиском в проводнике (или в некоторых редакторах, и др. программах), то, возможно, задавал в качестве шаблона для поиска что-то вроде "искомое_слово*", где "*" означает любое количество любых символов (кстати, этим шаблоном можно пользоваться и при поиске в google или yandex...). Так вот, он как раз пользовался неким очень ущербным вариантом регулярного выражения.

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

    Рассмотрим простую замену, которая использует группы рег.выражений:
    Old: (привет)\s+(\w+)
    New: $2, $1
    
    Результат ее работы такой, что фразы типа "привет Таня", "привет Антон", "привет мир"... будут преобразованы в "Таня, привет", "Антон, привет", "мир, привет"...

    Согласно формализму рег.выражений:
    "\s" - означает пробел (space)
    "\w" - любую печатную букву, т.е. букву которое может входить в слово (word)
    "+"  - суффикс, означающий что предыдущий символ может встречаться в любом количестве большим нуля. Т.обр. "\s+" - означает пробел или любое их большее количество, а "\w+" - печатная буква или любое их большее число, т.е. это попросту некое слово.
    Соответственно регулярное выражение "привет\s+\w+" ищет фразы типа "привет нечто".
    Добавление же скобок в него в данном случае никак не меняет его смысла, а лишь выделяет 2 группы: 1-я "привет" и 2-я "\w+" на которые можно ссылаться при замене по их номеру как на $1 и $2.
    Например, берем фразу "привет Таня". В ней 1-й группой будет "привет", а 2-й "Таня". Выражение в New гласит, что новым значением должно быть "$2, $1". Подставляя конкретные значения групп, в итоге и получаем: "Таня, привет".


    В функциональных же заменах введенных в предыдущей версии эта "супер-способность" рег.выражений не работала. Что в принципе можно понять, ведь New надо сначала вычислить, а потом уже использовать для замены. И если бы в рассмотренном примере у нас в качестве New была функция типа:
    New: ReverseHello
    которая как результат вычисления возвращала бы "$2, $1", то все работало бы в точности также как только что описывалось для не функциональных замен.

    Однако, иногда бывает полезно использовать группы рег.выражений также и до вычисления функции. Именно такая возможность добавлена в новой версии. Теперь группы рег.выражений можно использовать в параметре функции (если она его имеет).

    Чтобы не уходить в абстрактные сферы, рассмотрим использование групп в параметре функции на конкретном примере. А именно, определим голосовую команду "искать слово", которая ищет в редакторе слово следующее за словом "искать":
    Name: искать слово
    Old: искать\s+(\w+)
    New: fun|KeysPress|CONTROL+VK_F > 500 > '$1' > 100 > RETURN > 100 > ESCAPE
    
    (полное ее определение можно посмотреть в редакторе замен)

    Если вы читали предыдущей текст, то, вероятно, уже поняли как она работает, но распишу для порядка:
    • группой $1 у нас как раз является слово следующее за "искать". Например пусть мы сказали "искать золото", тогда $1 это будет слово "золото".
    • функция KeysPress сначала нажимает [Ctrl+F], что открывает в редакторе окно поиска.
    • затем, на всякий случай, следует задержка в пол-секунды.
    • затем, как раз срабатывает новая фича, которая заменяет '$1' на 'золото'. Что в нашем случае означает, что в окошке поиска будет напечатано слово "золото".
    • небольшая задержечка
    • затем жмется [Enter] (RETURN) в результате чего редактор находит (или не находит) искомое слово.
    • еще небольшая задержечка
    • и нажатие на клавишу [Esc] закрывает окно поиска.

    Данная команда прекрасно работает в редакторе Word, в текстовом редакторе Notepad++, в браузерах Firefox и Chrome.
    В других программах не проверял.


  • Добавлены команды управления мышью.

    • Команда двигать мышью..
      например, команда "150 налево" передвинет курсор мыши на 150 пикселей влево. Доступны все 4 направления: лево, право, вниз, вверх. Более того, можно альтернативно задавать направления по сторонам света - в этом случае доступны уже 8 направлений: север, юг, запад, восток, северо-запад, юго-восток...
    • кликать мышью.
      Чтобы эмулировать клик скажите одно из 3-х: левый/правый/двойной клик.
      Если потребуется можно определить клики и другими кнопками мыши, если ваша мышь "крутая" и они у нее предусмотрены.
    • прокрутка мышью
      Эмулирует прокрутку колеса мыши, причем в 4-х направлениях: вверх/вниз/влево/вправо. Так, команда "прокрутка вверх" прокручивает текст вверх на одну позицию. Если нужна прокрутка на большее число позиций, скажите "прокрутка вверх 5" (или другое требуемое число).
    Подробности по этим командам можно посмотреть в редакторе замен, все они находятся в одной группе - "мышь". А реализацию функций, на которых они основаны, можно посмотреть в файлах:
    "\options\externApi\ru-RU.cs" и
    "\options\externApi\_common.cs".
  • Прочие новые команды.

    • Команда искать слово
      Ищет в редакторах (а также в браузерах и др. программах...) слово следующее за словом "искать". В конце раздела Использование т.н. "групп" регулярных выражений в функциональных заменах, в качестве примера, рассматривалось создание этой команды.
      По умолчанию она отключена, поскольку словосочетание "искать СЛОВО" все-таки не редкое и может не к месту срабатывать. Но, если хотите, можете назначить этой команде более уникальный голосовой "тригер": "выполнить поиск СЛОВО", "найди дружок мне СЛОВО"...
    • Команды включить русскую озвучку и включить английскую озвучку.
      Если вы работаете с несколькими языками или включаете перевод на них, а также включаете озвучку, то наверное заметили, что всё время лазить в окно опций чтобы изменить голос озвучки довольно неудобно. Теперь можно создавать команды, которые будут включать озвучку на любой заранее выбранный вами голос.

      Прежняя команда включить озвучку работает также как и раньше - включает озвучку голосом выбранном в окне опций. И все эти команды (включая еще отключить озвучку) вызывают в New функцию VoiceTurn. Ранее эта функция могла принимать в качестве параметра только значения on (включить) или off (выключить). Сейчас добавился 3-й вариант - она может принимать имя голоса. В этом случае, включается озвучка именно этим голосом.
      См. реализацию этих команд в редакторе замен.
      Все замены относящиеся к озвучке теперь находятся в одной новой группе - озвучка.

      По умолчанию, эти команды выключены, поскольку они требуют знания, какие голоса у вас установлены в системе. В окне опции на вкладке Repls. вы можете посмотреть установленные голоса и специальной кнопочкой скопировать имя нужного голоса. И далее скопированное имя можно в качестве параметра подставить в соответствующую команду включения озвучки - после чего уже можете включить эту команду.

      Чтобы при включенной озвучке, при отключении режима перевода (команда отключить перевод) не нужно было специально давать команду переключения озвучки на исходный язык, была добавлена возможность сброса имени голоса озвучки к значению, которое вы выбрали в окне опций. Для этого функции TranslateOff, которая вызывается командой отключить перевод, нужно предавать (необязательный) параметр ResetVoice (см. текущую реализацию команды отключить перевод в редакторе замен).

    • тест клавиш+мышь..
      Эта единственная функциональная замена в новой группе тесты. По умолчанию она отключена, но рекомендую хотя бы раз включить ее, и произнеся "тестировать клавиши и мышь", полюбоваться на красоту "мини-представления" :).
      Реализация ее очень проста и даже если вы не разбираетесь в программировании все равно можете заглянуть в файл "\options\externApi\_common.cs" и найти там функцию KeysAndMouseTest. Там все просто, и если понадобится, вы легко можете изменить ее под свои нужды или, лучше, написать свою подобную.

  • Исправлены мелкие огрехи и незначительные грехи :).

Version 2.0.0.0


Лирика: Номер версии скачком увеличил до 2.0, поскольку эта версия наконец достигла точки, где реализовано мое концептуальное видение этого продукта, реализованы принципиальные замыслы на программу.
Что будет дальше, посмотрим... это, в том числе, во многом зависит от вас, дорогой пользователь, от ваших отзывов и предложений.

Свершился!
Честное слово, совершенно не специально, однако, релиз вышел в точности в 100-летие революции (07.11.2017). Прямо как это было принято в оное время (сработала генетическая память?) - подгонять трудовые свершения под годовщину революции.

Все обновляйтесь! Ура Товарищи!
Перефразируя известное выражение: коммунизм это есть LeanLang + VoiceToText-фикация всей страны!
А если в "мировом масштабе" (а что языки, в отличии от Чапая, знаем - см. LeanLang), то - всего мира!
:)


  • Физика (занимательная) :) — или обзор функциональных замен.

    Довольно существенно расширился функционал и концепция "замен". Более того, это расширение, позволило функционал "голосовых команд" переместить в "замены". Так что сущностей стало меньше - "замены" поглотили "голосовые команды".

    Тем кто читал о "заменах" в разделе "Что нового?" версии 1.0.1.8, сразу сообщу - все что писалось полностью осталось в силе. Лишь расширился функционал, о чем сейчас и будет рассказ.
    А если вы новый пользователь и только хотите разобраться с "заменами", то рекомендую сначала почитать тот раздел.

    Раньше в качестве значения замены (свойства "New"), допускалось лишь только фиксированная строка, которая в точности и подставлялась вместо "Old". Сейчас, варианты значений "New" расширились - теперь помимо просто строки стало возможным задавать вызов "функций".
    Собственно остальной рассказ в основном будет посвящен тому, что под "функциями" имеется ввиду и как задавать свои функции.

    Это могут быть произвольные функции, которые вычисляют значения и/или производят некоторые действия.

    Например (то, что входит а комплект поставки новой версии):
    • можно сказать "текущая дата" и программа вставит текущую дату (ключевое слово и формат даты/времени пользователь, конечно, может задать сам).
    • сказать "открыть калькулятор" ("блокнот", "мои документы"... любую др.программу или папку/файл заданные пользователем) и программа откроет это.
      Также можно закрыть любую программу или переключится на нее, если ее окно скрыто другими окнами.
    • сказать "сохранить документ" и он сохранится в той программе (например каком-либо редакторе) где вы сейчас находитесь. Здесь просто эмулируется нажатие [Ctrl+S].
      Более того, вы можете определять свои подобные функциональные замены на любое сочетание горячих клавиш.
    • сказать "вычислить 178 умножить на 25" (любые другие числа и математические операции) и программа подставит ответ. Помимо арифметики пользователь также может определить вычисление любых собственных или стандартных функций (например, тригонометрических).
    • сказать "текущий курс доллара" и программа вставит его под курсор. И, конечно, вы можете очень легко создать собственную функ.замену на любое другое сочетание валют.
      В общем же, программа может вытаскивать по определенной вами команде любую информацию из сети (или ваших БД) - курсы акций, погоду, рейтинги...
    • сказать "свернуть в компактный вид" или "развернуть в нормальный вид".
    • сказать "очистить лог".
    • ...
    Теперь более "тяжелые", а где-то и забавные возможности (тоже входят а комплект поставки новой версии):
    • автоматический голосовой переводчик.
      Т.е., например, пользователь говорит по русски, а программа пишет текст уже на английском (сочетание языков может быть любым).
      Более того, сам "переводчик" можно включать/отключать голосом, сказав "включить перевод на английский (любой другой язык)" и "отключить перевод".
    • сказать любую фразу и программа повторит ее уже синтетическим голосом (каким именно, его скорость и громкость определяется пользователем). Т.е. пользователь говорит текст, а программа тут же его повторяет, но синтетическим голосом. Полезная штука для шпионов :)
    • можно составлять "комбинации" (суперпозиции функций) - например, пользователь говорит, программа пишет перевод и тут же произносит его.
    • можно голосом переключаться на любой другой язык распознавания. Например, если вы сейчас говорите по русски и хотите перейти на английскую речь, то просто скажите "переключится на английский" (а для обратного переключения нужно сказать "switch to Russian").
    • ...
    Это все лишь ПРИМЕРЫ!
    Т.е. в программу добавлена общая функциональность, инструмент, который позволяет квалифицированному пользователю (а еще лучше программисту) создавать подобные вещи. Ну или, конечно, всегда можно обратиться ко мне - в этом случае по такому запросу могу оперативно создать для вас требуемую функцию.

    Тут важно, что для добавления таких расширений, не нужно выпускать новую версию программы, все эти функции описываются во внешних по отношению к программе текстовых файлах.
    Еще "плюс", что тем самым снимается зависимость от меня (хотя никуда не пропадаю) - программу могут развивать сами пользователи. А при развитом сообществе (пишите свои расширения и делитесь ими на форуме), это может существенно увеличить темпы развития функционала программы.

    Все замены на данный момент условно делятся на 4 группы:
    • текст - текстовые замены (то что и было).
    • функции - функциональные замены, которые в качестве "New" возвращают вычисленное значение какой-либо функции, либо имеют некий "сторонний эффект" (типа озвучки).
    • клавиши (горячие) - функциональные замены, которые эмулируют нажатие (горячих) клавиш.
    • команды - функциональные замены, которые ничего не возвращают в целевой текст, но выполняют некоторое действие (открывают приложения, переключают режимы...)
    Для знакомства с полным списком замен ("огласите весь список, пожалуйста" :)) - просто откройте в программе "редактор замен" (см. его описание ниже).

    Сами функции (большей частью) вместе с их кодом находятся в папке программы:
    \options\externApi\
    Но некоторые функции, например, такие как "отмена" (Rollback) или переключение языков (SwitchCultureTo), определены внутри программы. Это такие функции, которым требуется влияние на процессы внутри самой программе - например, той же функции Rollback нужно манипулировать логом программы, а SwitchCultureTo менять текущий язык в выпадающем списке (комбо-боксе) языков.
  • Подробнее о функциональных заменах или "физика" с формулами.

    Синтаксически вызов "функции" в "New" задается так:
      "New": "fun|имя_функции"
    или
      "New": "fun|имя_функции|параметр"
    если функция предполагает параметр (или еще говорят - аргумент функции).

    Например (реальный пример):
    {
      "Old": "текущая дата",
      "IsIgnoreCase": true,
      "New": "fun|NowDate|yyyy.MM.dd"
    }
    Здесь NowDate - это функция, которая возвращает текущую дату-время в формате заданным ее аргументом. Так что когда пользователь произнесет "текущая дата", то в место под курсор вставится дата на тот момент когда он это произносит, например "2017.10.15".
    Если кому-то нужно вставлять дату в другом формате или кроме даты требуется еще и время, то он легко может определить другой формат, например:
      "New": "fun|NowDate|dd.MM.yyyy HH:mm:ss"
    получив в результате, что-то в виде "15.10.2017 21:45:37".

    Если вы совсем не разбираетесь (и не хотите разбираться) в программировании, то можете пропустить следующий блок информации.
    Моей задачей минимум было донести информацию о возможностях программы. Например, если вам вдруг понадобится функция, которая бы вставляла дату прописью типа "пятнадцатое октября две тысячи семнадцатого года", то вам важно знать, что это возможно.

    В таких случаях просто напишите мне и я обязуюсь оперативно делать для вас такие функции, если это конечно будут запросы на реальные функции, а не на волшебные типа "программа напиши сама сочинение на тему...". И что важно - вам после запроса на функцию, не придется ждать, возможно, месяцы до следующей версии и перекачивать программу. Все может занять считанные дни, а для простых функций, возможно - часы.

    А если у вас есть друг склонный к программированию, то и он может написать вам требуемую функцию - ведь они определяются не внутри, а ВО ВНЕ программы.

    Итак, далее будет текст для тех, кто хоть как-то знаком с программированием (хотя бы на уровне школьной информатики), а так же для пытливых умов, кому интересна эта тема.

    пишется...


  • Новые режимы.

    • Теперь можно поставить (и снять) программу на паузу.
      Переключение либо с помощью новых кнопочек, либо через соответствующие голосовые команды ("поставить на паузу"/"продолжить запись"). В режиме паузы программа воспринимает только две голосовые команды - это "продолжить запись" (т.е. снять с паузы) и "остановить запись".
    • Еще один режим, который переключается исключительно голосовыми командами "включить текст"/"выключить текст".
      Он похож на режим паузы (когда текст "выключен"), но в отличии паузы в этом режиме просто не выводится текст (ни в лог ни под курсор), однако все голосовые команды актуальны. Т.е. можно, например, открывать/закрывать приложения, включать/отключать голосовой перевод...

      Для индикации того что вывод текста выключен, при переходе в этот режим, кнопка остановки записи (синий квадратик) поворачивается на 45 градусов превращаясь в ромбик.
    Эти режимы добавлены для поддержки управления "без рук". Чтобы при включенной записи можно было, даже не смотря на экран, полностью управлять программой - см. примечание.

    Однако, рекомендую использовать эти режимы только кратковременно. Если же вы надолго прерываетесь, то лучше остановите запись, поскольку в этих режимах программа продолжает работать, записывая и отправляя аудио-поток на распознавание.

    При переключении режимов через голосовые команды, но не только этих режимов (а также при переключении на другой язык или включении перевода), по умолчанию, издается короткий сигнал. Это полезно опять-таки при "слепой" работе с программой - дает обратную связь, контроль, что переключение произошло.

    Вы можете поменять аудио файл этого сигнала, настроить его громкость или заменить его системным "бипом", а то и вовсе отключить на вкладке "Repls." (сокр.англ. "replaces" - "замены") в окне опций.

    А если вам не понравился сигнал по умолчанию (файл \options\signals\_default.wav), то массу дополнительных сигналов можете найти, например, в папке:
    C:\Windows\Media\ (или где у вас винда стоит?)
  • Новые свойства (атрибуты) замен.

    • "IsEnabled" - флаг, который определяет испольуется ли замена.
      В ранних версиях описывалась галочка "Allow replaces" в окне опций, которая позволяет отключить функциональность ВСЕХ замен. Это же свойство позволяет включать/выключать индивидуально каждую замену. Что особенно актуально в связи появлением редактора замен (см. его описание в следующем пункте новых фич).
      В отличии от все остальных флагов этот флаг имеет по умолчанию значение 'true'.
    • "Name" - имя замены. Может быть пустым.
      Под этим именем она будет видна в списке редактора замен. А также его в принципе можно использовать для поиска замены в коде пользовательских функций.
    • "IsBreak" - если у замены этот флаг 'true', то при выполнении списка замен, все нижеследуюшие замены не будут применяться - выполнение замен прервется на этой замене.

      Например, для замены "отмена", которая идет первой в списке замен, коль она случилась, нет смысла далее анализировать и выполнять все нижеследующие замены. Все такие замены-терминаторы (логично так назвать, поскольку они завершают выполнение замен - вот такое "восстание машин", запомните ИИ "скайнет" начнется с VoiceToText :)) преимущество собраны в начале списка замен.

      Кроме того, функциональные замены, в коде своей функции, могут локально (только на время единичного прохода по списку замен) устанавливать этот флаг.
    • "Group" - группа, используется для группировки замен (их каталогизации). Может быть пустой.
      В редакторе замен (см. описание чуть ниже) помимо того, что можно изменять данное свойство, еще можно фильтровать по нему (для удобства просмотра, сами же замены это не отключает).
      Замечу, что если такой фильтр включен, то двигать замены уже нельзя - специально запретил, ведь важна точная позиция замены в списке всех замен, в фильтрованном же списке она неоднозначна.
    • "IsSound" - если у замены этот флаг 'true', то когда эта замена случается, будет издаваться звук в соответствии с настройками на вкладке "Repls." в окне опций. Что особенно полезно при "слепой" работе с программой. У многих команд этот флаг установлен.
    Теперь перечислю свойства, которые зарезервированы на всякий случай - вдруг они кому понадобятся. Они не представлены в редакторе, но их можно вручную добавлять в json-файлы замен и далее использовать в логике внешних cs-файлов, где определяются функции для функциональных замен.

    • "Key" - предположительное использование: как (уникальный) ключ замены, по которому можно делать поиск замен(ы) с этим ключом в функциях (такое иногда нужно).
    • "Options" - предположительное использование: любые опции, в виде строки json-объекта, которая в функциях десериализуется в c#-object.
    • "Tag" - все что угодно, любая дополнительная строка.

  • Редактор замен.

    С правого края главного окна программы, появилась кнопочка с иконкой, нажатие на которую откроет выпадающий контент со списком замен + их редактором.

    Собственно как-то подробно описывать как пользоваться редактором смысла особого нет - тут проще увидеть, чем рассказать. Он позволяет создавать/редактировать/удалять замены, а также двигать их в списке замен (из рассказа о заменах в описании версии 1.0.1.8 помним, что их порядок - важен).

    "Крупными мазками" + некоторые важные акценты:

    • Слева - список замен.
      Каждый элемент в этом списке представляет замену с ее именем (свойство "Name") и галочкой, которой можно ее включать/выключать (флаг "IsEnabled").
    • Справа - форма для редактирования свойств выделеной замены.
    • Все UI-элементы редактора имеют всплывающие подсказки (тултипы).
    • Обратите внимание на свойство "Old".
      Если это свойство является регулярным выражением (включена галка "Regex"), то его название является ссылкой, кликнув на которую вы перейдете в онлайн редактор рег.выражений, где уже будет находится текущее значение "Old" и где можно его протестировать.
    • Также важно знать, что если правите замены через редактирование их json-файла, то чтобы они вступили в силу, необходимо перезапустить программу (так всегда было, так и осталось). Однако, теперь, если вы правите их через редактор замен (в том числе и прямо во время включенной записи), то все изменения вступают в силу немедленно.
    • Любые правки замен авто-сохраняются в их json-файле, вам не нужно об этом специально заботиться.
      + на всякий случай, исходные замены хранятся в папке:
      \options\replaces\archive\

  • Подробнее о "голосовом переводчике".

    За перевод отвечает функциональная замена "перевод на (английский)":
    {
      "Name": "перевод на (английский)",
      "Old": ".*",
      "IsEnabled": false,
      "IsRegex": true,
      "New": "fun|TranslateTo|en"
    }
    Как видно, по умолчанию она выключена ("IsEnabled": false). Поэтому чтобы включить перевод, просто включите галку в редакторе замен. Еще видим, что по умолчанию это перевод на английский ("New": "fun|TranslateTo|en"), однако вы можете легко изменить это умолчание, подставив в качестве параметра функции вместо "en" любую другую культуру, например, для испанского - "es".

    Полный код культуры состоит из 2-х частей - типа "en-GB", однако в нашем случае этого не требуется (хотя и не запрещено), достаточно и первой части, кроме почему-то китайского, для которого нужно указывать "zh-CN".


    Отключить перевод можно либо сняв галочку с замены перевода, либо, что удобнее, просто произнести "отключить перевод" (см. соответствующую замену).

    Более того, и включить перевод можно не трогая мышь - для этого служит команда "включить перевод на...".
    {
      "Name": "включить перевод на...",
      "Old": "\\s*включить перевод(\\s+на английский|\\s+на американский|\\s+на испанский|\\s+на немецкий|\\s+на итальянский|\\s+на французский|\\s+на$)\\b",
      "IsRegex": true,
      "IsIgnoreCase": true,
      "New": "fun|TranslateOn|en-GB"
    }
    Одна довольно хитрая. Если скажете "включить перевод на", то она включит перевод на язык, который указан ей по умолчанию - "en-GB". Однако вы также можете сказать, например, "включить перевод на немецкий" и в этом случае включится переводчик именно на немецкий.

    Языки на которые она умеет переключать можно видеть в значении свойства "Old". Если вам нужно добавить любые другие языки, то просто добавьте их туда по аналогии. А также в файл \options\externApi\ru-RU.cs опять-таки по аналогии, добавьте соответствие названия языка и кода культуры.

    Команды "включить перевод на..." и "отключить перевод" являются примером "команд-деривативов", т.е. они как бы являются производными над другими заменами - в нашем случае над заменой "перевод на (английский)". Сами они ничего не переводят а просто включают/выключают последнюю замену и подсовывают ей в качестве параметра запрошенный язык. Когда вы произносите эти команды, то если у вас открыт редактор замен, вы можете вживую увидеть как галочка у замены "перевод на (английский)" соответственно включается/выключается.

    Вся эта логика реализована в файле \options\externApi\_common.cs и кто имеет соответствующую квалификации может ее изучить (а, возможно, захочет и поменять ее).

    Следующая полезная вещь это галочка "Support another text for 'Log' at 'Export'" расположенная в выпадающем контенте, где определяется "Режим деления аудио-потока на фразы".
    Эта галочка общего назначения, значение которой могут использовать различные функциональные замены в логике своей реализации. Пока же ее использует только замена перевода.

    Поясню на примере перевода для чего она нужна. Пусть, язык на который идет перевод совсем вам не знаком и поэтому вы никак не можете проконтролировать качество перевода. Google переводчик весьма неплох, но ведь это качество еще существенно зависит от того насколько корректно распозналась ваша родная речь - от того, что идет на "вход" переводчика, ведь, как говориться, "мусор на входе дает мусор на выходе". Однако, когда включен переводчик, "входа" мы не видим, а видим сразу перевод.

    Чтобы иметь возможность контролировать "вход" и нужна эта галочка. Если она включена и включен режим экспорта, то под курсор вашего целевого редактора будет идти перевод, и в то же время вы сможете видеть, как в лог программы будет параллельно писаться исходный текст.
    Т.е. в лог будет идти другой текст ("another text") чем "под курсор" о чем название галочки и говорит в несколько обобщенной формулировке - ведь, как уже сказал, значение этой галочки, в принципе, могут использовать и другие функциональные замены, а не только переводчик.

    Перевод идет предпоследним в списке замен совершенно не случайно - в результате этого, сначала отработают все положенные для русского языка замены, и только потом текст пойдет на перевод.

    Абсолютно аналогично, для английского описанная функциональность лежит за заменами с названиями:
    - translation to (Spanish)
    - start translate to...
    - stop translate

  • Переозвучка вашей речи и озвучка перевода ("дубляж").

    За озвучку отвечает последняя замена в списке замен:
    {
      "Name": "повторение SAPI голосом",
      "IsEnabled": false,
      "Old": ".*",
      "IsRegex": true,
      "New": "fun|Speak"
    }
    Она очень похожа на замену перевода и также по умолчанию выключена ("IsEnabled": false). Соответственно, чтобы включить озвучку, просто включите галку в редакторе замен.

    Голос, скорость произношения и громкость берется из настроек установленных на вкладке "Repls." (сокр.англ. "replaces" - "замены") в окне опций. Поэтому, не забудьте предварительно выбрать там нужный вам голос. Но имя голоса можно также передать и параметром в функцию замены, например:
    "New": "fun|Speak|IVONA 2 Tatyana"
    При этом скорость и громкость будут по прежнему браться из окна опций.
    В окне опций обратите внимание на кнопочку с иконкой копирования, справа от имени голоса - она позволяет скопировать имя голоса в буфер обмена. Так что если вы хотите подставить в функцию определенный голос (или определить дополнительную замену с таким жестко заданным голосом), вам не нужно его название набирать вручную.

    Если у вас замена перевода не включена, то, очевидно, будет произносится (переозвучиваться) текст на том языке на котором вы и говорите. А если включена - то услышите озвучку перевода.

    Совершенно также как и для переводчика, включать/выключать озвучку можно голосом - через команды-деривативы "включить озвучку" и "выключить озвучку".

    Наконец, очевидно, почему озвучка идет самой последней в списке замен - сначала должны отработать все замены (включая перевод), и только окончательный (целевой) вариант текста будет произнесен.


    пишется...

  • Изменен/улучшен интрефейс программы.

    • Выбор и настройки режимов деления аудио-потока на фразы, вынесены (а вернее занесены :)), как выпадающий контент, под кнопку расположенную сразу справа от кнопки записи/остановки.

      На "морде" этой кнопки отображается название текущего режима, а сразу справа от нее, для удобства (чтобы избежать лишних кликов), продублировано наиболее востребованное поле настройки выбраного режима. Для режима деления по промежуткам тишины ("by silence (auto)") это "уровень (громкость) тишины", а для деления по таймеру ("by timer") - период таймера.
    • Улучшена поддержка темных цветовых схем (хотя не только темных - просто для них это наиболее актуально). В окне опций на вкладке "Colors" добавлены две новые настройки "Input foreground" и "Input background", которые отвечают за цвет и фон полей ввода (inputs).
    • Исправлены некоторые замеченные мелкие неудобства.

  • Разное:

    • Добавлены замены для английского и американского языков.
    • Команда "отмена" теперь поддерживает бесконечное число шагов (раньше можно было откатиться лишь на один шаг назад).
    • Исправлены замеченные ошибки.

Version 1.0.2.0

  • Переключатель языков в компактном виде программы.

    Если вы пользуетесь более чем одним языком, то теперь для удобного переключения между ними, в компактном виде программы добавилась кнопочка-переключатель с иконкой флага текущего языка.

    А в окне опций (на вкладке "General"), там где можно выбрать язык интерфейса (тултипов), чуть правее появилась новая кнопка "Your active languages", кликнув на которую можно галочками выбрать ваши активные языки.
    Именно эти языки будут циклически перебираться при кликах на нашу кнопочку с флажком в компактном виде.

    Благодарю пользователя программы - Вадима, за эту идею-предложение.
  • Регулировка прозрачности компактного вида.

    В выпадающих настройках прозрачности (совсем маленькая кнопочка в левом верхнем углу, сразу за кнопкой открытия окна опций) добавился еще ползунок регулирующий прозрачность компактного вида.
    По умолчанию, прозрачность уставновлена в 25%.

    Долгое время работая на компе, со временем стал предпочитать темные схемы или же теплые цвета, и чтобы было меньше резких контрастов (+ f.lux - рекомендую глянуть, если не пользовались). На мой вкус, так меньше устаешь. И случайно попробовав компактный режим при прозрачном фоне, был в этом смысле удовлетворен. Считаю, что программа, кроме того что должна быть полезной, также, как хороший слуга, должна быть еще и незаметной ("ненавязчивый сервис"; спрятавшийся тигр, затаившийся дракон... :)).

    Хотя, как говорится, "на вкус и цвет все фломастеры разные", поэтому, пожалуйста, сообщите если вам не понравится значение по умолчанию в 25% (мне важно для статистики).


Version 1.0.1.8

  • Правила (замены).

    Настоятельно рекомендую хотя бы пробежать глазами данный текст (хоть и понимаю, что "много буквъ" и не каждый пользователь доберется до середины этого "Днепра"). А потом заглянуть в файл "\options\replaces\ru-RU.json", чтобы просто знать что нужно говорить, когда хотите вставить знаки препинания, начать новый абзац, начать фразу с большой буквы...
    (я же, по ходу текста, буду стараться вас немного развлекать, чтобы не засыпали :))

    Прежде чем описывать этот новый функционал, остановлюсь на том, зачем он понадобился (ведь может все-таки "скрипач не нужен"?).
    Как известно, все программы тупые, они принципиально не умеют мыслить и никак не могут понимать, что вам от них нужно.
    Как идет работа с google распознавателем речи, который использует программа?
    VoiceToText отправляет ему кусочек аудио-фразы, он возвращает какой-то текст, программа добавляет перед этим текстом разделитель (чтобы он не слипся с предыдущим кусочком текста) и "паровозиком" вставляет его под курсор. И больше ничего, в то время как жизнь, братцы, гораздо сложнее.

    Если вы сколько-нибудь серьезно использовали старую версию программы, то, очевидно, заметили, насколько результат отличается от того, что вам хотелось бы. Где запятые и тире? Где точки, вопросительные и восклицательные знаки? Почему текст после последних (которых, впрочем, нет) не начинается с большой буквы? Почему не начинается новый абзац когда мне надо?... (и вообще, где мой компот?! :)) Кроме того, google распознаватель конечно мощная штука, но не так уж редко и он делает ошибки, особенно на некоторых "проклятых" фразах.

    Чтобы помочь решать эти проблемы и была добавлена эта новая функциональность.
    Так что даже если все-таки скрипач вам и не нужен, то вот эта функциональность вам может быть весьма полезна.
    Она позволяет пользователю самому определять правила, которые научат программу лучше "понимать", что от нее требуется. Эти правила определены в виде списка объектов, которые я условно назвал "замены" (replaces), поскольку в основном они задают некоторые замены (но не только).

    Естественно, для каждого языка они должны быть свои. И эти правила находятся в под-папке программы:
    \options\replaces
    Для каждого языка свой файл. Их имена должны иметь строго определенные названия, в точности совпадающие с международным обозначением, так называемой, "культуры" вашего языка:
    https://msdn.microsoft.com/en-US/library/ee825488.aspx

    Пока мною определен такой файл только для русского языка - "ru-RU.json".

    Определять для других, даже для английского, как не носитель этих языков, пока не решился (файл "en-US.json" на самом деле пустой).

    Это обычный текстовый файл с расширением "json". Единственное, если будете создавать аналогичные файлы для других языков, настоятельно рекомендую ставить кодировку текста "UTF-8", ведь языки разные (не только в латинском алфавите), а такая кодировка позволяет писать хоть иероглифы (привыкайте, скоро все будем учить китайский, а что, древняя и интересная культура), и именно эту кодировку ожидает программа.

    Почему поставил расширение "json", а не "txt"?
    - Во-первых, Хоть там и текст, но это текст именно в синтаксисе формата json (очень распространенный формат для описания свойств тех или иных объектов).
    - Во вторых, очень рекомендую редактировать его не в стандартном блокноте (notepad), а скачать и установить на замену ему, такой бесплатный блокнот из разряда маст хэйв (must have!) как notepad++.
    Помимо массы очень полезных функций (в том числе, кстати, и проверки орфографии), он подсвечивает синтаксис многих известных форматов. Поэтому, если вы откроете json-файл в нем, то у вас будет все разноцветно и красиво, и сделать ошибку (если будете определять свои правила) будет значительно сложнее.
    - "В-третьих" не будет :)

    Теперь заглянем внутрь "ru-RU.json".
    Там внутри квадратных скобок [...], через запятую идет перечисление замен в свою очередь находящихся в фигурных скобках {...}.
    В терминах компьютерной науки (computer science), каждая замена определена в виде объекта со свойствам (атрибутами).

    Перечислю все возможные свойства, которые можно задать в замене:

    • "Old" - определяет то, что следует заменять.
    • "New" - то на что следует заменить значение свойства "Old"
      Например, замена { "Old": "точка", "New": "." }, говорит, что в тексте (который приходит от google распознавателя), следует заменять слово "точка" на символ ".".
    • "IsIgnoreCase" (флаг) - может иметь значения true (истина) или false (ложь). Свойства принимающие только такие значения называть "флагами". Если он true, то значит поиск на замену будет происходить без учета регистра. Т.е. для нашего примера на замену подойдет как слово "точка", так и "Точка" или "ТОЧКА"... Если же false, то в точности только то, что определено в "Old".
    • "IsNextLetterToUpper" (флаг) - если этот флаг true, то следующая за ним буква (Next Letter) должна переводится в верхний регистр (To Upper). Например, после "." (т.е. конца предложения), следующую фразу следует начинать с большой буквы. Данный флаг как раз позволяет определять такое поведение.
    • "IsRemoveSpaceAfterNew" (флаг) - между всеми словами находятся пробелы, но иногда пробел (Space), после замененного текста (After New) не нужен, его нужно удалить (Remove). Например, это нужно делать после "-" (дефиса), в словах типа "что-либо", "когда-нибудь" и т.д... (и вы уж простите, сам везде в этом тексте вместо тире использую дефис). Соответствующее правило для дефиса может выглядеть как { "Old": "дефис", "New": "-", "IsRemoveSpaceAfterNew": true }.
    • "IsRemoveSpaceBeforeNew" (флаг) - как можно догадаться из названия, когда этот флаг true, то пробел будет удален (Remove) перед замененным текстом (Before New). В частности, это нужно делать перед знаками препинания. Например, без этого флага, наша замена { "Old": "точка", "New": "." }, превратит фразу "Наступило лето точка" в "Наступило лето .", где, как видим, пробел перед "." - лишний.

      Однако, по существу, этот флаг совсем не нужен, поскольку это можно делать с помощью регулярных выражений (покажу как, когда буду описывать флаг "IsRegex"). Этот флаг существует для "симметричности" с "IsRemoveSpaceAfterNew", и, возможно для тех, кто будет испытывать трудности с рег.выражениями. Я не рекомендую его использовать в том случае, если ваше правило уже задается как рег.выражение - лучше просто добавьте соответствующую опцию в рег.выражение. Если же вместо этого использовать флаг, то пусть и совсем незаметно, но это будет работать чуть медленнее.
    • "Exceptions" - иногда все же надо вместо замены "точка" на "." получить реальное слово "точка". Как быть в этом случае? Для этих исключений (Exceptions) и можно задать правила с помощью этого свойства. Например, можем определить, что для этого надо сказать "точка точка" ("пока пока" :)) или "в натуре точка". Последний случай приведен скорее для примера того, что можно определить несколько вариантов. Все-таки наиболее удачно это определять исключения через повторение слова (если вы не страдаете заиканием).
      Суммируя, приведем полный текст правила замены для точки:
      { 
        "Old": "точка",
        "New": ".",
        "IsIgnoreCase": true,
        "IsRemoveSpaceBeforeNew": true, // не рекомендуется, позже будет убран
        "Exceptions": ["точка", "точка точка", "в натуре точка"]
      }
      Почему первой в "Exceptions" стоит просто "точка"? Этот первый элемент имеет особый смысл - он определяет текст на который будут заменять следующие за ним варианты. Казалось бы этот текст можно взять из "Old"? Ан нет, как мы увидим чуть ниже, в "Old" может быть задано не просто слово, а так называемое "регулярное выражение", так что Old нам здесь не подходит.
      Если вы не хотите иных вариантов, кроме повторения ("точка точка"), то исключения можно записать совсем просто: "Exceptions": ["точка"]. Такой вот "синтаксический сахар".
    • "IsRegex" (флаг) - позволяет определять замены с помощью такой очень известной и супер-мощной вещи как "Регулярные выражения" (Regular Expressions). Пользователи Linux должны быть с этим понятием на "ты". В Windows же, если кто пользовался поиском в проводнике (или в некоторых редакторах, и др. программах), то, возможно, задавал в качестве шаблона для поиска что-то вроде "искомое_слово*", где "*" означает любое количество любых символов (кстати, этим шаблоном можно пользоваться и при поиске в google или yandex...). Так вот, он как раз пользовался неким очень ущербным вариантом регулярного выражения.

      В сети по ним масса информации и кто не знаком, см. хотя бы:
      https://ru.wikipedia.org/wiki/Регулярные_выражения.
      Также есть множество инструментов, программ и онлайн сервисов, которые помогают составлять и тестировать ваши регулярные выражения. Если вы будете это делать, то можете воспользоваться, например:
      https://regex101.com/.

      Так, для той же точки могут подходить слова: "точками", "веточкам"... Сейчас, согласно нашему правилу, они будут заменяться на ".ми" и "ве.м", что, согласитесь, некорректно. Правильно было бы заменять только отдельно стоящее слово "точка", т.е. когда оно как-то отделено (пробелами или другими знаками) от окружения. Это можно сделать, во-первых, добавив в наше правило свойство "IsRegex": true, во-вторых, скорректировать Old как: "Old": "\\bточка\\b" (кто ожидал, увы, "в-третьих" опять не будет).
      "\b" - в регулярных выражениях говорит о наличии границы (boundary) слова. Т.е. в нашем случае ищем "точка", которое имеет границы слева и справа.

      Как можно видеть, вместо "\b" в наших json-файлах пишется "\\b".
      Это не ошибка. Здесь накладываются правила синтаксиса json-формата, согласно которым, если мы хотим использовать символ "\" в строке, то его надо повторять - "\\" (кто не в курсе, примите как данность - о причинах этого рассказывать тут не место, если интересно, можете сами поискать в сети).


      Кроме того, на всякий случай учтем, что google-распознаватель может вдруг возвращать и ".".
      В рег.выражении альтернативы отделяются символом "|" и также как в арифметических выражениях, части рег.выражений можно группировать круглыми скобками, которые аналогично используются для определения области действия и приоритета операций.
      А "\s*", согласно формализму рег.выражений, описывает любое количество пробелов, "\s" здесь означает пробел (space), а "*" - любое количество, пробелов в данном случае.
      В итоге, применяя эти знания, получим следующее правило для точки:
      { 
        "Old": "\\s*(\\bточка\\b|[.])",
        "New": ".",
        "IsIgnoreCase": true,
        "IsNextLetterToUpper": true,
        "IsRegex": true,
        "Exceptions": ["точка", "точка точка", "в натуре точка"]
      }
      Возможно, людям не знакомым рег.выражениями, тут не все детально ясно, интуитивно же, думаю, все более-менее должно быть понятно. Просто было бы не верно в это описание втискивать еще и учебник по рег.выражениям, по ним уже есть масса руководств в инете, кому интересно, найдет.

      Благодаря "\s*", в найденную строку будут включатся и все ведущие пробелы, так что флаг "IsRemoveSpaceBeforeNew" не нужен. И всегда, если ваше правило задается рег.выражением и ведущие пробелы нужно удалить, то просто добавьте в начало "\\s*".

      Это очень-очень простой пример такого мощного средства как регулярные выражения, и если понадобится, можно составлять правила куда сложнее.

    Почему в отличии от "IsRemoveSpaceBeforeNew" флаг "IsRemoveSpaceAfterNew" все же нужен? Ведь казалось бы, добавь уже не в начало, а в конец "\\s*" и пробелы следующие за словом удаляться. Это правда, но за одним исключением. Если мы, например, скажем "девочки играли в дочки дефис матери", то с таким правилом (где в конце "\\s*"), действительно получим "девочки играли в дочки-матери". Однако, мы можем сказать это по частям:
    "девочки играли в дочки" (пауза) "дефис" (пауза, попили кофе :)) "матери".
    Это будут три отдельных распознавания.

    Программа, последовательно получая эти кусочки, отдельно для каждого, действует как три рабочих на конвейере, делающих следующие три операции:
    - первый, добавляет впереди разделитель (пробел):
       " девочки играли в дочки" + " дефис" + " матери"
    - второй, применяет "гребенку" замен:
       " девочки играли в дочки" + "-" + " матери"
    - третий, вставляет каждый кусочек под курсор или в лог.

    Заметили, что в результате перед "матери" у нас оказался ненужный пробел?
    Все верно, "\\s*" в конце дефиса "убрал" несуществующий в данном случае пробел, но нам то нужно его убрать перед следующим словом, которое обрабатывается совершенно независимо и может быть любым (дочки-бабушки...).

    Т.е. нам нужно как-то передать "по-наследству" следующей за дефисом фразе, что ее ведущие пробелы должны быть удалены, но в том и только в том случае, если фраза заканчивается на дефис. Например, для цельной фразы "девочки играли в дочки дефис матери целый день" ничего передавать не нужно.
    Рег.выражения тут не помогут (они работают только в рамках каждого кусочка), а вот флаг "IsRemoveSpaceAfterNew" я программно наделил таким свойством (хозяин-барин :)).
    (второй "рабочий", как бы на миг отвлекается от своей операции и кричит третьему - Эй, Петрович, а иди ка ты к такой-то матери, в смысле, иди и убери перед матерью пробел, перед тем как "вставить" :))

    Таким же свойством наследования наделен флаг "IsNextLetterToUpper".
    Например, в сценарии "наступило лето точка" (пауза) "и это ужасно", также необходимо передать второй фразе, что она должна начинаться с большой буквы.


    Если какие-то свойства упущены при определении замены (а они могут быть упущены хоть все, но тогда такая "замена" ни на что не влияет - ее все равно что нет), то тогда они принимают значения по умолчанию. Для флагов это значение false, а если пропущено "New", то оно считается равным "Old".

    Замены применяются в точности в том порядке как они определены в файле. И этот порядок важен. Пусть у нас есть, например, фраза "все будет плохо".
    Рассмотрим 2 варианта отличающихся только порядком замен:
    [ {"Old": "плохо", "New": "еще хуже"}, 
      {"Old": "плохо", "New": "хорошо"} ]
    и
    [ {"Old": "плохо", "New": "хорошо"}, 
      {"Old": "плохо", "New": "еще хуже"} ]
    После применения первого варианта к фразе, получим "все будет еще хуже", а после применения второго - "все будет хорошо". Как говорится, почувствуйте разницу :)

    Некоторые правила замен в файле "ru-RU.json" кажутся излишне усложненными, например, для "абзаца", в то время как, казалось бы, можно сделать проще. Однако, если такое увидите, то скорее всего это связано с неоднозначностью, амбивалентностью (блесну словечком, может за умного сойду) возвращаемых от google данных. Но! Это не значит, что я все-таки не дурак, возможно существуют и более простые решения. Если вы так считаете - проверьте их на практике! А если вы кроме того, что умный, еще и милостливый, то, пожалуйста, сообщите эти более лаконичные решения мне или на форум.


    Я специально не определил правил для кавычек.
    - Во-первых, каждому может захотеться своих кавычек, кому-то "елочки", кому-то простые двойные, кому-то одинарные...
    - Во-вторых, это может быть для вас хорошим упражнением (но если что, обращайтесь за помощью).
    - А в-третьих..., вот засада! у меня вечный облом с придумыванием "в-третьих".

    Обращайтесь ко мне (на почту) или на форум, если вы захотите еще какие-то правила и у вас возникнут затруднения с их определением, как говорится, одна голова хорошо, а две лучше (даешь три! - добавил змей-горыныч. - Да!!! С воодушевлением поддержали его 3 мужика стоящие в очереди за водкой).

    Галочка "Allow replaces" в окне опций позволяет отключить функциональность замен.
    Это может быть нужно не только если вы придерживаетесь минималистических взглядов и не хотите "всяких новомодных штучек", но и когда вы составляете свои правила - ведь для этого важно знать что реально, "на сырую" приходит от гугла, до того как по тексту еще не прошлась гребенка всех замен.

    Кто дочитал до этого места - тот Большой(-ая) Молодец(-а)!!!
    Пойдите, возьмите очень вкусную конфету с полочки, вы это заслужили! (упс, сорри, а я ее уже там съел смайлик стыдно ).
    Ну в общем, порадуйте себя как-то, откройте шампанское, примите ванннуу, выпейте чашечку кофээ...

  • Голосовые команды.

    Теперь в режиме записи можно голосом отдавать программе определенные команды.
    Их описание находится в файле "\options\voiceCommands.json"

    На данный момент, пока имеется всего одна такая команда - "rollback", но в ее определении, как в капле воды, отражен общий формализм океана других возможных команд :)

    Этой команда определена для русского и английского языков (кто знает больше, может сам добавить другие языки).
    Она откатывает (удаляет) последний кусочек распознанного ввода. Если ваша фраза распозналась неправильно, то скажите, например, "отмена".
    Замечу, что удаляется фраза через нажатие клавиши "забоя" ("back space") в месте под курсором, поэтому, если вы руками переставите курсор в другое место, то там и будет удаление, что бы там ни находилось.

    Программа хранит историю только последнего кусочка. Поэтому вы можете отменить только последний, но не пред- (или пред-пред-...) последний кусочек, если будете пытаться несколько раз непрерывно применять эту команду. Если же практика покажет, что будет полезно хранить более длинную историю (длину можно сделать опций), то пишите - реализуем (тем более это не сложно).


    Для русского определены 2 варианта ее активации через слова-тригеры ("отмена" и "откатить") вместе с исключениями через повторение.
    Для английского (британского "en-GB" и американского "en-US") - один вариант ("rollback") с аналогичным исключением.

    Если вы читали раздел о заменах то, думаю, сможете разобраться в файле команд, что за что отвечает и как изменять/добавлять свои варианты. А если у кого это вызовет затруднение, пишите - добавлю детальное описание.

    Отмечу только, что для команд не предусмотрен вариант с регулярными выражениями (не увидел пока необходимости в этом, но если возникнет, то добавить несложно), соответственно и в исключения не нужно первым добавлять слово - там в явном виде (без "синтаксического сахара") находится только то, что вызывает исключения.

    Обращайтесь, если придумаете еще какие-то типы голосовых команд - если сойдемся и если это будет реализуемо, то, конечно, добавлю их.

    В окне опций, галочкой "Allow voice commands" можно отключить функциональность голосовых команд.
  • "Caps Lock"

    Теперь, когда нажата эта клавиша, весь распознанный текст будет идти в верхнем регистре.

    В принципе, еще сделал, что если клавиша "Shift" нажата и удерживается, то следующий распознанный кусочек должен идти начинаясь с большой буквы. Но эта функциональность работает нестабильно - иногда срабатывает, иногда нет. Плюс винда все время выдает сообщение, что "залипла" клавиша Shift (возможно поэтому и нестабильно).


  • Добавлена возможность включить сигнал ("бип" он же "пик"), при обработке каждого кусочка.

    В окне опций, галочкой "Signal" можно выключить/отключить этот сигнал.
    А в полях чуть правее этой галочки настроить его характеристики:
    • "Frequency" - частота сигнала, диапазон: 37 - 32767 (в герцах).

      По умолчанию, частота сигнала выставлена в 500 герц. Но возможность поставить ее в близкой к инфра-звуку частоте в 37 герц, при достаточно большой длительности и выкрученных на полную громкость ваших мощных динамиков, поможет вам сэкономить деньги на кино-сеансы фильмов ужасов :)

    • "Duration" - длительность сигнала (в миллисекундах).
    • "After recognize" - если эта галочка установлена, то сигнал должен звучать после распознавания (появления кусочка текста в программе). В противном случае (по умолчанию), он звучит перед отправкой аудио-кусочка на сервис распознавания google.

      В этом последним случае, по задержке между "бипом" и появлением текста в программе, видно насколько оперативно работает сервис распознавания (задержка есть, но совсем маленькая). Если вы говорите фразами, делая между ними паузы и хотите четко знать когда программа отрезает кусочек аудио, то вот вам бип-индикатор.

      Еще этот режим можно, использовать как альтернативу измерения громкости промежутка тишины. Если установить минимальное значение громкости тишины (100), то программа будет часто "пикать", даже если вы молчите. При постепенном увеличении громкости тишины "пики" будут все реже и реже, пока совсем не прекратятся - думаю, где-то тут близко и находится оптимальное значение этого параметра. Хотя, также думаю, что все это индивидуально - у каждого разные микрофоны, разные условия (которые могут меняться)..., поэтому рекомендую вам находить ваш оптимум также индивидуально - по приципу "практика критерий истины".
      Но вот вам еще один инструмент для этого.


  • Добавлены новые функции и улучшения интерфейса программы.

    • Scale - добавлена возможность настраивать масштаб.
      Его значение можно задать в окне опций либо в поле "Scale, %", либо двигая ползунок синхронизованный с этим полем, в диапазоне от 100% (по умолчанию) до 300%.
    • Hide to tray - кнопочка "спрятать программу в системный лоток (трей)".
      Она добавлена туда же, где находятся кнопки закрытия, минимизации... окна.
    • Clear log - кнопочка "очистить лог".
      Она добавлена чуть правее галочки включения/выключения лога, в виде иконки с перечеркнутым кружком.
    • Обновил цветовую схему "DarkSchema" и вообще улучшил поддержку программой темных схем.
      А также совсем немного изменил "Default" схему.

  • Исправлены замеченные ошибки.

    В частности, исправлена наблюдавшаяся на некоторых компах ошибка "CLIPBRD_E_CANT_OPEN"