diff --git a/Crysis2 Sounds/FTP-СОЕДИНЕНИЕ УСТАНОВЛЕНО.wav b/Crysis2 Sounds/FTP-СОЕДИНЕНИЕ УСТАНОВЛЕНО.wav new file mode 100644 index 0000000..3bdfa81 Binary files /dev/null and b/Crysis2 Sounds/FTP-СОЕДИНЕНИЕ УСТАНОВЛЕНО.wav differ diff --git a/Crysis2 Sounds/ВОПРОС.wav b/Crysis2 Sounds/ВОПРОС.wav new file mode 100644 index 0000000..cd01508 Binary files /dev/null and b/Crysis2 Sounds/ВОПРОС.wav differ diff --git a/Crysis2 Sounds/ВОСКЛИЦАНИЕ.wav b/Crysis2 Sounds/ВОСКЛИЦАНИЕ.wav new file mode 100644 index 0000000..24ed836 Binary files /dev/null and b/Crysis2 Sounds/ВОСКЛИЦАНИЕ.wav differ diff --git a/Crysis2 Sounds/ВОССТАНОВЛЕНИЕ.wav b/Crysis2 Sounds/ВОССТАНОВЛЕНИЕ.wav new file mode 100644 index 0000000..0dea541 Binary files /dev/null and b/Crysis2 Sounds/ВОССТАНОВЛЕНИЕ.wav differ diff --git a/Crysis2 Sounds/ВХОД В WINDOWS.wav b/Crysis2 Sounds/ВХОД В WINDOWS.wav new file mode 100644 index 0000000..6c43af8 Binary files /dev/null and b/Crysis2 Sounds/ВХОД В WINDOWS.wav differ diff --git a/Crysis2 Sounds/ВХОДЯЩИЙ ЗВОНОК.wav b/Crysis2 Sounds/ВХОДЯЩИЙ ЗВОНОК.wav new file mode 100644 index 0000000..8709c43 Binary files /dev/null and b/Crysis2 Sounds/ВХОДЯЩИЙ ЗВОНОК.wav differ diff --git a/Crysis2 Sounds/ВЫБРАТЬ.wav b/Crysis2 Sounds/ВЫБРАТЬ.wav new file mode 100644 index 0000000..2989bf6 Binary files /dev/null and b/Crysis2 Sounds/ВЫБРАТЬ.wav differ diff --git a/Crysis2 Sounds/ВЫХОД ИЗ WINDOWS (2).wav b/Crysis2 Sounds/ВЫХОД ИЗ WINDOWS (2).wav new file mode 100644 index 0000000..f952e29 Binary files /dev/null and b/Crysis2 Sounds/ВЫХОД ИЗ WINDOWS (2).wav differ diff --git a/Crysis2 Sounds/ВЫХОД ИЗ WINDOWS.wav b/Crysis2 Sounds/ВЫХОД ИЗ WINDOWS.wav new file mode 100644 index 0000000..3b3b7a2 Binary files /dev/null and b/Crysis2 Sounds/ВЫХОД ИЗ WINDOWS.wav differ diff --git a/Crysis2 Sounds/ЗАБЛОКИРОВАНО ВСПЛЫВАЮЩЕЕ ОКНО.wav b/Crysis2 Sounds/ЗАБЛОКИРОВАНО ВСПЛЫВАЮЩЕЕ ОКНО.wav new file mode 100644 index 0000000..bfb0eb6 Binary files /dev/null and b/Crysis2 Sounds/ЗАБЛОКИРОВАНО ВСПЛЫВАЮЩЕЕ ОКНО.wav differ diff --git a/Crysis2 Sounds/ЗАВЕРШЕНИЕ ПЕЧАТИ.wav b/Crysis2 Sounds/ЗАВЕРШЕНИЕ ПЕЧАТИ.wav new file mode 100644 index 0000000..b6a7cdd Binary files /dev/null and b/Crysis2 Sounds/ЗАВЕРШЕНИЕ ПЕЧАТИ.wav differ diff --git a/Crysis2 Sounds/ЗАВЕРШЕНИЕ РАБОТЫ WINDOWS (2).wav b/Crysis2 Sounds/ЗАВЕРШЕНИЕ РАБОТЫ WINDOWS (2).wav new file mode 100644 index 0000000..26f4d66 Binary files /dev/null and b/Crysis2 Sounds/ЗАВЕРШЕНИЕ РАБОТЫ WINDOWS (2).wav differ diff --git a/Crysis2 Sounds/ЗАВЕРШЕНИЕ РАБОТЫ WINDOWS.wav b/Crysis2 Sounds/ЗАВЕРШЕНИЕ РАБОТЫ WINDOWS.wav new file mode 100644 index 0000000..0e7519a Binary files /dev/null and b/Crysis2 Sounds/ЗАВЕРШЕНИЕ РАБОТЫ WINDOWS.wav differ diff --git a/Crysis2 Sounds/ЗАКОНЧИТЬ ОБЗОР.wav b/Crysis2 Sounds/ЗАКОНЧИТЬ ОБЗОР.wav new file mode 100644 index 0000000..36ceccb Binary files /dev/null and b/Crysis2 Sounds/ЗАКОНЧИТЬ ОБЗОР.wav differ diff --git a/Crysis2 Sounds/ЗАКРЫТИЕ ПРОГРАММЫ.wav b/Crysis2 Sounds/ЗАКРЫТИЕ ПРОГРАММЫ.wav new file mode 100644 index 0000000..65ed8d4 Binary files /dev/null and b/Crysis2 Sounds/ЗАКРЫТИЕ ПРОГРАММЫ.wav differ diff --git a/Crysis2 Sounds/ЗВЕЗДОЧКА.wav b/Crysis2 Sounds/ЗВЕЗДОЧКА.wav new file mode 100644 index 0000000..a34d8f4 Binary files /dev/null and b/Crysis2 Sounds/ЗВЕЗДОЧКА.wav differ diff --git a/Crysis2 Sounds/ИЗМЕНЕНИЕ ТЕМЫ WINDOWS.wav b/Crysis2 Sounds/ИЗМЕНЕНИЕ ТЕМЫ WINDOWS.wav new file mode 100644 index 0000000..2630fed Binary files /dev/null and b/Crysis2 Sounds/ИЗМЕНЕНИЕ ТЕМЫ WINDOWS.wav differ diff --git a/Crysis2 Sounds/КОНТРОЛЬ УЧЕТНЫХ ЗАПИСЕЙ WINDOWS.wav b/Crysis2 Sounds/КОНТРОЛЬ УЧЕТНЫХ ЗАПИСЕЙ WINDOWS.wav new file mode 100644 index 0000000..2666960 Binary files /dev/null and b/Crysis2 Sounds/КОНТРОЛЬ УЧЕТНЫХ ЗАПИСЕЙ WINDOWS.wav differ diff --git a/Crysis2 Sounds/КОПИРОВАНИЕ - ПЕРЕМЕЩЕНИЕ ЗАВЕРШЕНО.wav b/Crysis2 Sounds/КОПИРОВАНИЕ - ПЕРЕМЕЩЕНИЕ ЗАВЕРШЕНО.wav new file mode 100644 index 0000000..09b89cc Binary files /dev/null and b/Crysis2 Sounds/КОПИРОВАНИЕ - ПЕРЕМЕЩЕНИЕ ЗАВЕРШЕНО.wav differ diff --git a/Crysis2 Sounds/КРИТИЧЕСКАЯ ОШИБКА.wav b/Crysis2 Sounds/КРИТИЧЕСКАЯ ОШИБКА.wav new file mode 100644 index 0000000..2e772a1 Binary files /dev/null and b/Crysis2 Sounds/КРИТИЧЕСКАЯ ОШИБКА.wav differ diff --git a/Crysis2 Sounds/НАЧАТЬ ОБЗОР.wav b/Crysis2 Sounds/НАЧАТЬ ОБЗОР.wav new file mode 100644 index 0000000..d54f059 Binary files /dev/null and b/Crysis2 Sounds/НАЧАТЬ ОБЗОР.wav differ diff --git a/Crysis2 Sounds/ОБНАРУЖЕН КАНАЛ.wav b/Crysis2 Sounds/ОБНАРУЖЕН КАНАЛ.wav new file mode 100644 index 0000000..e2a4be0 Binary files /dev/null and b/Crysis2 Sounds/ОБНАРУЖЕН КАНАЛ.wav differ diff --git a/Crysis2 Sounds/ОБНАРУЖЕН ПОСТАВЩИК УСЛУГ ПОИСКА (2).wav b/Crysis2 Sounds/ОБНАРУЖЕН ПОСТАВЩИК УСЛУГ ПОИСКА (2).wav new file mode 100644 index 0000000..68a0e25 Binary files /dev/null and b/Crysis2 Sounds/ОБНАРУЖЕН ПОСТАВЩИК УСЛУГ ПОИСКА (2).wav differ diff --git a/Crysis2 Sounds/ОБНАРУЖЕН ПОСТАВЩИК УСЛУГ ПОИСКА.wav b/Crysis2 Sounds/ОБНАРУЖЕН ПОСТАВЩИК УСЛУГ ПОИСКА.wav new file mode 100644 index 0000000..1347364 Binary files /dev/null and b/Crysis2 Sounds/ОБНАРУЖЕН ПОСТАВЩИК УСЛУГ ПОИСКА.wav differ diff --git a/Crysis2 Sounds/ОТКЛЮЧЕНИЕ УСТРОЙСТВА.wav b/Crysis2 Sounds/ОТКЛЮЧЕНИЕ УСТРОЙСТВА.wav new file mode 100644 index 0000000..a9c159b Binary files /dev/null and b/Crysis2 Sounds/ОТКЛЮЧЕНИЕ УСТРОЙСТВА.wav differ diff --git a/Crysis2 Sounds/ОТКРЫТИЕ ПРОГРАММЫ.wav b/Crysis2 Sounds/ОТКРЫТИЕ ПРОГРАММЫ.wav new file mode 100644 index 0000000..9bb7439 Binary files /dev/null and b/Crysis2 Sounds/ОТКРЫТИЕ ПРОГРАММЫ.wav differ diff --git a/Crysis2 Sounds/ОЧИСТКА КОРЗИНЫ.wav b/Crysis2 Sounds/ОЧИСТКА КОРЗИНЫ.wav new file mode 100644 index 0000000..99d8cc7 Binary files /dev/null and b/Crysis2 Sounds/ОЧИСТКА КОРЗИНЫ.wav differ diff --git a/Crysis2 Sounds/ОШИБКА ПОДКЛЮЧЕНИЯ УСТРОЙСТВА (2).wav b/Crysis2 Sounds/ОШИБКА ПОДКЛЮЧЕНИЯ УСТРОЙСТВА (2).wav new file mode 100644 index 0000000..e055e3a Binary files /dev/null and b/Crysis2 Sounds/ОШИБКА ПОДКЛЮЧЕНИЯ УСТРОЙСТВА (2).wav differ diff --git a/Crysis2 Sounds/ОШИБКА ПОДКЛЮЧЕНИЯ УСТРОЙСТВА.wav b/Crysis2 Sounds/ОШИБКА ПОДКЛЮЧЕНИЯ УСТРОЙСТВА.wav new file mode 100644 index 0000000..9e40ded Binary files /dev/null and b/Crysis2 Sounds/ОШИБКА ПОДКЛЮЧЕНИЯ УСТРОЙСТВА.wav differ diff --git a/Crysis2 Sounds/ОШИБКА ПРОГРАММЫ.wav b/Crysis2 Sounds/ОШИБКА ПРОГРАММЫ.wav new file mode 100644 index 0000000..c677233 Binary files /dev/null and b/Crysis2 Sounds/ОШИБКА ПРОГРАММЫ.wav differ diff --git a/Crysis2 Sounds/ОШИБКА ФАКСА.wav b/Crysis2 Sounds/ОШИБКА ФАКСА.wav new file mode 100644 index 0000000..d21b986 Binary files /dev/null and b/Crysis2 Sounds/ОШИБКА ФАКСА.wav differ diff --git a/Crysis2 Sounds/ПЕРЕДАЧА ЗАВЕРШЕНА.wav b/Crysis2 Sounds/ПЕРЕДАЧА ЗАВЕРШЕНА.wav new file mode 100644 index 0000000..f295615 Binary files /dev/null and b/Crysis2 Sounds/ПЕРЕДАЧА ЗАВЕРШЕНА.wav differ diff --git a/Crysis2 Sounds/ПОДКЛЮЧЕНИЕ УСТРОЙСТВА.wav b/Crysis2 Sounds/ПОДКЛЮЧЕНИЕ УСТРОЙСТВА.wav new file mode 100644 index 0000000..ea0d10f Binary files /dev/null and b/Crysis2 Sounds/ПОДКЛЮЧЕНИЕ УСТРОЙСТВА.wav differ diff --git a/Crysis2 Sounds/ПОИСК ЗАВЕРШЕН.wav b/Crysis2 Sounds/ПОИСК ЗАВЕРШЕН.wav new file mode 100644 index 0000000..fbdf15c Binary files /dev/null and b/Crysis2 Sounds/ПОИСК ЗАВЕРШЕН.wav differ diff --git a/Crysis2 Sounds/РАЗВЕРТЫВАНИЕ.wav b/Crysis2 Sounds/РАЗВЕРТЫВАНИЕ.wav new file mode 100644 index 0000000..7651051 Binary files /dev/null and b/Crysis2 Sounds/РАЗВЕРТЫВАНИЕ.wav differ diff --git a/Crysis2 Sounds/РАСКРЫТИЕ ВСПЛЫВАЮЩЕГО МЕНЮ.wav b/Crysis2 Sounds/РАСКРЫТИЕ ВСПЛЫВАЮЩЕГО МЕНЮ.wav new file mode 100644 index 0000000..3d1c3f7 Binary files /dev/null and b/Crysis2 Sounds/РАСКРЫТИЕ ВСПЛЫВАЮЩЕГО МЕНЮ.wav differ diff --git a/Crysis2 Sounds/РАСПАКОВКА ЗАВЕРШЕНА.wav b/Crysis2 Sounds/РАСПАКОВКА ЗАВЕРШЕНА.wav new file mode 100644 index 0000000..360a100 Binary files /dev/null and b/Crysis2 Sounds/РАСПАКОВКА ЗАВЕРШЕНА.wav differ diff --git a/Crysis2 Sounds/СВЕРТЫВАНИЕ.wav b/Crysis2 Sounds/СВЕРТЫВАНИЕ.wav new file mode 100644 index 0000000..0297860 Binary files /dev/null and b/Crysis2 Sounds/СВЕРТЫВАНИЕ.wav differ diff --git a/Crysis2 Sounds/СИГНАЛ НИЗКОГО ЗАРЯДА БАТАРЕЙ.wav b/Crysis2 Sounds/СИГНАЛ НИЗКОГО ЗАРЯДА БАТАРЕЙ.wav new file mode 100644 index 0000000..50b4a4f Binary files /dev/null and b/Crysis2 Sounds/СИГНАЛ НИЗКОГО ЗАРЯДА БАТАРЕЙ.wav differ diff --git a/Crysis2 Sounds/СИГНАЛ ПОЛНОЙ РАЗРЯДКИ БАТАРЕЙ.wav b/Crysis2 Sounds/СИГНАЛ ПОЛНОЙ РАЗРЯДКИ БАТАРЕЙ.wav new file mode 100644 index 0000000..2c7aeb0 Binary files /dev/null and b/Crysis2 Sounds/СИГНАЛ ПОЛНОЙ РАЗРЯДКИ БАТАРЕЙ.wav differ diff --git a/Crysis2 Sounds/СИСТЕМНОЕ УВЕДОМЛЕНИЕ.wav b/Crysis2 Sounds/СИСТЕМНОЕ УВЕДОМЛЕНИЕ.wav new file mode 100644 index 0000000..b8a915e Binary files /dev/null and b/Crysis2 Sounds/СИСТЕМНОЕ УВЕДОМЛЕНИЕ.wav differ diff --git a/Crysis2 Sounds/УВЕДОМЛЕНИЕ О ПОЛУЧЕНИИ ПОЧТЫ.wav b/Crysis2 Sounds/УВЕДОМЛЕНИЕ О ПОЛУЧЕНИИ ПОЧТЫ.wav new file mode 100644 index 0000000..7eef2fe Binary files /dev/null and b/Crysis2 Sounds/УВЕДОМЛЕНИЕ О ПОЛУЧЕНИИ ПОЧТЫ.wav differ diff --git a/Crysis2 Sounds/УВЕДОМЛЕНИЕ О ПРИХОДЕ ФАКСА.wav b/Crysis2 Sounds/УВЕДОМЛЕНИЕ О ПРИХОДЕ ФАКСА.wav new file mode 100644 index 0000000..29eba6b Binary files /dev/null and b/Crysis2 Sounds/УВЕДОМЛЕНИЕ О ПРИХОДЕ ФАКСА.wav differ diff --git a/Crysis2 Sounds/УДАЛЕНИЕ ЗАВЕРШЕНО.wav b/Crysis2 Sounds/УДАЛЕНИЕ ЗАВЕРШЕНО.wav new file mode 100644 index 0000000..73ce1e5 Binary files /dev/null and b/Crysis2 Sounds/УДАЛЕНИЕ ЗАВЕРШЕНО.wav differ diff --git a/Crysis2 Sounds/УПАКОВКА ЗАВЕРШЕНА (2).wav b/Crysis2 Sounds/УПАКОВКА ЗАВЕРШЕНА (2).wav new file mode 100644 index 0000000..185a422 Binary files /dev/null and b/Crysis2 Sounds/УПАКОВКА ЗАВЕРШЕНА (2).wav differ diff --git a/Crysis2 Sounds/УПАКОВКА ЗАВЕРШЕНА.wav b/Crysis2 Sounds/УПАКОВКА ЗАВЕРШЕНА.wav new file mode 100644 index 0000000..cd2ff2d Binary files /dev/null and b/Crysis2 Sounds/УПАКОВКА ЗАВЕРШЕНА.wav differ diff --git a/Crysis2 Sounds/ФАКС ОТПРАВЛЕН.wav b/Crysis2 Sounds/ФАКС ОТПРАВЛЕН.wav new file mode 100644 index 0000000..d92aac4 Binary files /dev/null and b/Crysis2 Sounds/ФАКС ОТПРАВЛЕН.wav differ diff --git a/src/src/greet3.wav b/Jarvis Sound Pack/used/Да сэр(второй).wav similarity index 100% rename from src/src/greet3.wav rename to Jarvis Sound Pack/used/Да сэр(второй).wav diff --git a/src/src/greet1.wav b/Jarvis Sound Pack/used/Да сэр.wav similarity index 100% rename from src/src/greet1.wav rename to Jarvis Sound Pack/used/Да сэр.wav diff --git a/src/src/ok1.wav b/Jarvis Sound Pack/used/Есть.wav similarity index 100% rename from src/src/ok1.wav rename to Jarvis Sound Pack/used/Есть.wav diff --git a/src/src/ok2.wav b/Jarvis Sound Pack/used/Загружаю сэр.wav similarity index 100% rename from src/src/ok2.wav rename to Jarvis Sound Pack/used/Загружаю сэр.wav diff --git a/src/src/ok3.wav b/Jarvis Sound Pack/used/Запрос выполнен сэр.wav similarity index 100% rename from src/src/ok3.wav rename to Jarvis Sound Pack/used/Запрос выполнен сэр.wav diff --git a/src/src/greet2.wav b/Jarvis Sound Pack/used/К вашим услугам сэр.wav similarity index 100% rename from src/src/greet2.wav rename to Jarvis Sound Pack/used/К вашим услугам сэр.wav diff --git a/Jarvis Sound Pack/used/Как пожелаете .wav b/Jarvis Sound Pack/used/Как пожелаете .wav new file mode 100644 index 0000000..9ba3794 Binary files /dev/null and b/Jarvis Sound Pack/used/Как пожелаете .wav differ diff --git a/src/src/off.wav b/Jarvis Sound Pack/used/Отключаю питание.wav similarity index 100% rename from src/src/off.wav rename to Jarvis Sound Pack/used/Отключаю питание.wav diff --git a/Jarvis Sound Pack/Включилось аварийное резервное питание.wav b/Jarvis Sound Pack/Включилось аварийное резервное питание.wav new file mode 100644 index 0000000..b7b9965 Binary files /dev/null and b/Jarvis Sound Pack/Включилось аварийное резервное питание.wav differ diff --git a/Jarvis Sound Pack/Восточное побережье.wav b/Jarvis Sound Pack/Восточное побережье.wav new file mode 100644 index 0000000..c4908f4 Binary files /dev/null and b/Jarvis Sound Pack/Восточное побережье.wav differ diff --git a/Jarvis Sound Pack/Вы создали новый элемент.wav b/Jarvis Sound Pack/Вы создали новый элемент.wav new file mode 100644 index 0000000..8ebd4f7 Binary files /dev/null and b/Jarvis Sound Pack/Вы создали новый элемент.wav differ diff --git a/Jarvis Sound Pack/Выхожу на грид оракл.wav b/Jarvis Sound Pack/Выхожу на грид оракл.wav new file mode 100644 index 0000000..4e18a52 Binary files /dev/null and b/Jarvis Sound Pack/Выхожу на грид оракл.wav differ diff --git a/Jarvis Sound Pack/Да, это поможет вам оставаться незамеченным.wav b/Jarvis Sound Pack/Да, это поможет вам оставаться незамеченным.wav new file mode 100644 index 0000000..a2e6717 Binary files /dev/null and b/Jarvis Sound Pack/Да, это поможет вам оставаться незамеченным.wav differ diff --git a/Jarvis Sound Pack/Джарвис - приветствие (Песня целиком).wav b/Jarvis Sound Pack/Джарвис - приветствие (Песня целиком).wav new file mode 100644 index 0000000..59c70df Binary files /dev/null and b/Jarvis Sound Pack/Джарвис - приветствие (Песня целиком).wav differ diff --git a/Jarvis Sound Pack/Джарвис - приветствие 2.wav b/Jarvis Sound Pack/Джарвис - приветствие 2.wav new file mode 100644 index 0000000..3e03046 Binary files /dev/null and b/Jarvis Sound Pack/Джарвис - приветствие 2.wav differ diff --git a/Jarvis Sound Pack/Джарвис - приветствие.wav b/Jarvis Sound Pack/Джарвис - приветствие.wav new file mode 100644 index 0000000..359699a Binary files /dev/null and b/Jarvis Sound Pack/Джарвис - приветствие.wav differ diff --git a/Jarvis Sound Pack/Для полетов на другие планеты слелует усовершенствовать экзосистемы.wav b/Jarvis Sound Pack/Для полетов на другие планеты слелует усовершенствовать экзосистемы.wav new file mode 100644 index 0000000..19f408f Binary files /dev/null and b/Jarvis Sound Pack/Для полетов на другие планеты слелует усовершенствовать экзосистемы.wav differ diff --git a/Jarvis Sound Pack/Другой информации нет.wav b/Jarvis Sound Pack/Другой информации нет.wav new file mode 100644 index 0000000..ca6cf3f Binary files /dev/null and b/Jarvis Sound Pack/Другой информации нет.wav differ diff --git a/Jarvis Sound Pack/Еще один заряд израсходован.wav b/Jarvis Sound Pack/Еще один заряд израсходован.wav new file mode 100644 index 0000000..0575f7b Binary files /dev/null and b/Jarvis Sound Pack/Еще один заряд израсходован.wav differ diff --git a/Jarvis Sound Pack/Заряд батареи, %/11 %.wav b/Jarvis Sound Pack/Заряд батареи, %/11 %.wav new file mode 100644 index 0000000..41e2a1d Binary files /dev/null and b/Jarvis Sound Pack/Заряд батареи, %/11 %.wav differ diff --git a/Jarvis Sound Pack/Заряд батареи, %/2 %.wav b/Jarvis Sound Pack/Заряд батареи, %/2 %.wav new file mode 100644 index 0000000..c4fee76 Binary files /dev/null and b/Jarvis Sound Pack/Заряд батареи, %/2 %.wav differ diff --git a/Jarvis Sound Pack/Заряд батареи, %/7 %.wav b/Jarvis Sound Pack/Заряд батареи, %/7 %.wav new file mode 100644 index 0000000..10c25a4 Binary files /dev/null and b/Jarvis Sound Pack/Заряд батареи, %/7 %.wav differ diff --git a/Jarvis Sound Pack/Заряд батареи, %/Сэр, энергия 19 %.wav b/Jarvis Sound Pack/Заряд батареи, %/Сэр, энергия 19 %.wav new file mode 100644 index 0000000..b14febb Binary files /dev/null and b/Jarvis Sound Pack/Заряд батареи, %/Сэр, энергия 19 %.wav differ diff --git a/Jarvis Sound Pack/Заряд батареи, %/Энергия 13%.wav b/Jarvis Sound Pack/Заряд батареи, %/Энергия 13%.wav new file mode 100644 index 0000000..52c550d Binary files /dev/null and b/Jarvis Sound Pack/Заряд батареи, %/Энергия 13%.wav differ diff --git a/Jarvis Sound Pack/Заряд батареи, %/Энергия 15 %.wav b/Jarvis Sound Pack/Заряд батареи, %/Энергия 15 %.wav new file mode 100644 index 0000000..14539dc Binary files /dev/null and b/Jarvis Sound Pack/Заряд батареи, %/Энергия 15 %.wav differ diff --git a/Jarvis Sound Pack/Заряд батареи, %/Энергия 48% и падает сэр.wav b/Jarvis Sound Pack/Заряд батареи, %/Энергия 48% и падает сэр.wav new file mode 100644 index 0000000..f96d8bc Binary files /dev/null and b/Jarvis Sound Pack/Заряд батареи, %/Энергия 48% и падает сэр.wav differ diff --git a/Jarvis Sound Pack/Импортирую установки, начинаю калибровку виртуальной среды.wav b/Jarvis Sound Pack/Импортирую установки, начинаю калибровку виртуальной среды.wav new file mode 100644 index 0000000..c7c26a1 Binary files /dev/null and b/Jarvis Sound Pack/Импортирую установки, начинаю калибровку виртуальной среды.wav differ diff --git a/Jarvis Sound Pack/К сожалению его невозможно синтезировать.wav b/Jarvis Sound Pack/К сожалению его невозможно синтезировать.wav new file mode 100644 index 0000000..1dbce84 Binary files /dev/null and b/Jarvis Sound Pack/К сожалению его невозможно синтезировать.wav differ diff --git a/Jarvis Sound Pack/К сожалению устройство которое сохраняет вам жизнь в то же время убивает вас.wav b/Jarvis Sound Pack/К сожалению устройство которое сохраняет вам жизнь в то же время убивает вас.wav new file mode 100644 index 0000000..ac7ebf1 Binary files /dev/null and b/Jarvis Sound Pack/К сожалению устройство которое сохраняет вам жизнь в то же время убивает вас.wav differ diff --git a/src/src/ready.wav b/Jarvis Sound Pack/Мы подключены и готовы.wav similarity index 100% rename from src/src/ready.wav rename to Jarvis Sound Pack/Мы подключены и готовы.wav diff --git a/Jarvis Sound Pack/Мы работаем над проектом сэр 2.wav b/Jarvis Sound Pack/Мы работаем над проектом сэр 2.wav new file mode 100644 index 0000000..264649b Binary files /dev/null and b/Jarvis Sound Pack/Мы работаем над проектом сэр 2.wav differ diff --git a/Jarvis Sound Pack/Начинаю автоматическую сборку.wav b/Jarvis Sound Pack/Начинаю автоматическую сборку.wav new file mode 100644 index 0000000..459b304 Binary files /dev/null and b/Jarvis Sound Pack/Начинаю автоматическую сборку.wav differ diff --git a/Jarvis Sound Pack/Начинаю диагностику системы (второй).wav b/Jarvis Sound Pack/Начинаю диагностику системы (второй).wav new file mode 100644 index 0000000..cb9931b Binary files /dev/null and b/Jarvis Sound Pack/Начинаю диагностику системы (второй).wav differ diff --git a/Jarvis Sound Pack/Начинаю диагностику системы.wav b/Jarvis Sound Pack/Начинаю диагностику системы.wav new file mode 100644 index 0000000..54935c8 Binary files /dev/null and b/Jarvis Sound Pack/Начинаю диагностику системы.wav differ diff --git a/Jarvis Sound Pack/О чем я думал, обычно у нас все веселенькое.wav b/Jarvis Sound Pack/О чем я думал, обычно у нас все веселенькое.wav new file mode 100644 index 0000000..15c12fa Binary files /dev/null and b/Jarvis Sound Pack/О чем я думал, обычно у нас все веселенькое.wav differ diff --git a/Jarvis Sound Pack/Образ создан (второй).wav b/Jarvis Sound Pack/Образ создан (второй).wav new file mode 100644 index 0000000..f3a1c2f Binary files /dev/null and b/Jarvis Sound Pack/Образ создан (второй).wav differ diff --git a/Jarvis Sound Pack/Образ создан.wav b/Jarvis Sound Pack/Образ создан.wav new file mode 100644 index 0000000..88101be Binary files /dev/null and b/Jarvis Sound Pack/Образ создан.wav differ diff --git a/Jarvis Sound Pack/Отключаю питание, начинаю диагностику системы.wav b/Jarvis Sound Pack/Отключаю питание, начинаю диагностику системы.wav new file mode 100644 index 0000000..8213635 Binary files /dev/null and b/Jarvis Sound Pack/Отключаю питание, начинаю диагностику системы.wav differ diff --git a/Jarvis Sound Pack/Отслеживание звонка не завершено.wav b/Jarvis Sound Pack/Отслеживание звонка не завершено.wav new file mode 100644 index 0000000..ccffbfd Binary files /dev/null and b/Jarvis Sound Pack/Отслеживание звонка не завершено.wav differ diff --git a/src/src/stupid.wav b/Jarvis Sound Pack/Очень тонкое замечание сэр.wav similarity index 100% rename from src/src/stupid.wav rename to Jarvis Sound Pack/Очень тонкое замечание сэр.wav diff --git a/Jarvis Sound Pack/Поздравляю сэр.wav b/Jarvis Sound Pack/Поздравляю сэр.wav new file mode 100644 index 0000000..6b208b2 Binary files /dev/null and b/Jarvis Sound Pack/Поздравляю сэр.wav differ diff --git a/Jarvis Sound Pack/Предлагаемый элемент может стать безвредной заменой палладию.wav b/Jarvis Sound Pack/Предлагаемый элемент может стать безвредной заменой палладию.wav new file mode 100644 index 0000000..5f1bb10 Binary files /dev/null and b/Jarvis Sound Pack/Предлагаемый элемент может стать безвредной заменой палладию.wav differ diff --git a/Jarvis Sound Pack/Приближается мисс поттс =).wav b/Jarvis Sound Pack/Приближается мисс поттс =).wav new file mode 100644 index 0000000..15486f8 Binary files /dev/null and b/Jarvis Sound Pack/Приближается мисс поттс =).wav differ diff --git a/Jarvis Sound Pack/Проверка завершена.wav b/Jarvis Sound Pack/Проверка завершена.wav new file mode 100644 index 0000000..298e96f Binary files /dev/null and b/Jarvis Sound Pack/Проверка завершена.wav differ diff --git a/Jarvis Sound Pack/Район Нью-Йорка, Манхэттэн и окрестности.wav b/Jarvis Sound Pack/Район Нью-Йорка, Манхэттэн и окрестности.wav new file mode 100644 index 0000000..7320b88 Binary files /dev/null and b/Jarvis Sound Pack/Район Нью-Йорка, Манхэттэн и окрестности.wav differ diff --git a/Jarvis Sound Pack/Рассказ про Ивана Ванко.wav b/Jarvis Sound Pack/Рассказ про Ивана Ванко.wav new file mode 100644 index 0000000..1ebf233 Binary files /dev/null and b/Jarvis Sound Pack/Рассказ про Ивана Ванко.wav differ diff --git a/Jarvis Sound Pack/Реактор не предназначен для длительных полетов.wav b/Jarvis Sound Pack/Реактор не предназначен для длительных полетов.wav new file mode 100644 index 0000000..86a75da Binary files /dev/null and b/Jarvis Sound Pack/Реактор не предназначен для длительных полетов.wav differ diff --git a/Jarvis Sound Pack/Реактор принял модифицированное ядро.wav b/Jarvis Sound Pack/Реактор принял модифицированное ядро.wav new file mode 100644 index 0000000..d515510 Binary files /dev/null and b/Jarvis Sound Pack/Реактор принял модифицированное ядро.wav differ diff --git a/Jarvis Sound Pack/Сканирование макета завершено.wav b/Jarvis Sound Pack/Сканирование макета завершено.wav new file mode 100644 index 0000000..ff1c34d Binary files /dev/null and b/Jarvis Sound Pack/Сканирование макета завершено.wav differ diff --git a/Jarvis Sound Pack/Создать визуальный образ по новым спецификациям.wav b/Jarvis Sound Pack/Создать визуальный образ по новым спецификациям.wav new file mode 100644 index 0000000..46539d8 Binary files /dev/null and b/Jarvis Sound Pack/Создать визуальный образ по новым спецификациям.wav differ diff --git a/Jarvis Sound Pack/Сохранить его в центральной базе данных Stark Industries.wav b/Jarvis Sound Pack/Сохранить его в центральной базе данных Stark Industries.wav new file mode 100644 index 0000000..f0a0e41 Binary files /dev/null and b/Jarvis Sound Pack/Сохранить его в центральной базе данных Stark Industries.wav differ diff --git a/Jarvis Sound Pack/Судя по всему, использование костюма железного человека усугубляет ваше состояние.wav b/Jarvis Sound Pack/Судя по всему, использование костюма железного человека усугубляет ваше состояние.wav new file mode 100644 index 0000000..52a2ead Binary files /dev/null and b/Jarvis Sound Pack/Судя по всему, использование костюма железного человека усугубляет ваше состояние.wav differ diff --git a/Jarvis Sound Pack/Сэр, вы под прицелом, нужен обманный маневр.wav b/Jarvis Sound Pack/Сэр, вы под прицелом, нужен обманный маневр.wav new file mode 100644 index 0000000..4d1ec3d Binary files /dev/null and b/Jarvis Sound Pack/Сэр, вы под прицелом, нужен обманный маневр.wav differ diff --git a/Jarvis Sound Pack/Сэр, для реальной попытки полета не просчитаны еще террабайты данных.wav b/Jarvis Sound Pack/Сэр, для реальной попытки полета не просчитаны еще террабайты данных.wav new file mode 100644 index 0000000..73d683d Binary files /dev/null and b/Jarvis Sound Pack/Сэр, для реальной попытки полета не просчитаны еще террабайты данных.wav differ diff --git a/Jarvis Sound Pack/Сэр, не будете дергаться больно не будет.wav b/Jarvis Sound Pack/Сэр, не будете дергаться больно не будет.wav new file mode 100644 index 0000000..86b3657 Binary files /dev/null and b/Jarvis Sound Pack/Сэр, не будете дергаться больно не будет.wav differ diff --git a/Jarvis Sound Pack/Сэр, похоже его костюм может летать.wav b/Jarvis Sound Pack/Сэр, похоже его костюм может летать.wav new file mode 100644 index 0000000..c53f8c3 Binary files /dev/null and b/Jarvis Sound Pack/Сэр, похоже его костюм может летать.wav differ diff --git a/Jarvis Sound Pack/У вас на исходе и время, и варианты решения проблемы.wav b/Jarvis Sound Pack/У вас на исходе и время, и варианты решения проблемы.wav new file mode 100644 index 0000000..76ed0cd Binary files /dev/null and b/Jarvis Sound Pack/У вас на исходе и время, и варианты решения проблемы.wav differ diff --git a/Jarvis Sound Pack/Я перезагрузился сэр.wav b/Jarvis Sound Pack/Я перезагрузился сэр.wav new file mode 100644 index 0000000..78453f3 Binary files /dev/null and b/Jarvis Sound Pack/Я перезагрузился сэр.wav differ diff --git a/Jarvis Sound Pack/Я провел симуляции со всеми известными элементами.wav b/Jarvis Sound Pack/Я провел симуляции со всеми известными элементами.wav new file mode 100644 index 0000000..82985d6 Binary files /dev/null and b/Jarvis Sound Pack/Я провел симуляции со всеми известными элементами.wav differ diff --git a/_stt.py b/_stt.py new file mode 100644 index 0000000..870cc09 --- /dev/null +++ b/_stt.py @@ -0,0 +1,60 @@ +import torch +import sounddevice as sd +import speech_recognition as sr +import time +import numpy +from glob import glob + +device = torch.device('cpu') +model, decoder, utils = torch.hub.load(repo_or_dir='snakers4/silero-models', + model='silero_stt', + language='en', # en, ru + device=device) +(read_batch, split_into_batches, + read_audio, prepare_model_input) = utils + + +def callback(_r, audio): + try: + # CONVERT raw wav data to NumPy array + # wav_raw = audio.get_wav_data() + # data_s16 = numpy.frombuffer(wav_raw, dtype=numpy.int16, count=len(wav_raw) // 2, offset=0) + # np_audio = data_s16 * 0.5 ** 15 + + # Play it via sounddevice + #sd.play(np_audio, m.SAMPLE_RATE) + #time.sleep(len(np_audio) / m.SAMPLE_RATE) + #sd.stop() + + print("Распознание ...") + + # TODO: fix crutch, pass audio data directly as a model input of Silero STT + with open('speech.wav', 'wb') as f: + f.write(audio.get_wav_data()) + + test_files = glob('speech.wav') + batches = split_into_batches(test_files, batch_size=10) + input = prepare_model_input(read_batch(batches[0]), + device=device) + + output = model(input) + for example in output: + print(decoder(example.cpu())) + + # voice = recognizer.recognize_google(audio, language="ru-RU").lower() + # print("[log] Распознано: " + voice) + + except sr.UnknownValueError: + print("[log] Голос не распознан!") + + +# запуск +r = sr.Recognizer() +r.pause_threshold = 0.5 +m = sr.Microphone(device_index=1) + +with m as source: + r.adjust_for_ambient_noise(source) + +stop_listening = r.listen_in_background(m, callback) +while True: time.sleep(0.1) diff --git a/config.py b/config.py new file mode 100644 index 0000000..4f111cc --- /dev/null +++ b/config.py @@ -0,0 +1,49 @@ +VA_NAME = 'Jarvis' + +VA_VER = "3.0" + +VA_ALIAS = ('джарвис', 'кеша', 'кеш', 'инокентий', 'иннокентий', 'кишун', 'киш', 'кишаня', 'кешечка', 'кэш', 'кэша') + +VA_TBR = ('скажи', 'покажи', 'ответь', 'произнеси', 'расскажи', 'сколько') + +MICROPHONE_INDEX = 0 # ID микрофона (можете просто менять ID пока при запуске не отобразится нужный) + +CHROME_PATH = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s' + +PICOVOICE_TOKEN = "<ТУТ ТОКЕН PICOVOICE>" + +OPENAI_TOKEN = "<ТУТ ТОКЕН CHAT-GPT>" + +VA_CMD_LIST = { + "open_browser": ('открой браузер', 'запусти браузер', 'открой гугл хром', 'гугл хром'), + "open_youtube": ('открой ютуб', 'ютуб', 'запусти ютуб'), + "open_google": ('открой гугл', 'гугл', 'запусти гугл'), + + "sound_off": ('выключи звук', 'беззвучный режим', 'режим без звука', 'отключи звук'), + "sound_on": ('включи звук', 'режим со звуком', 'верни звук'), + + "thanks": ('спасибо', 'молодец', 'респект', 'ты супер', 'отличная работа', 'ты крут', 'ты большой молодец', 'ты реально крут', 'ты афигенный'), + + "stupid": ('ты дурак', 'ты дебил', 'ты глупый', 'ты тупой'), + + "gaming_mode_off": ("рабочий режим", "вернись в рабочий режим", "переключись на компьютер", "обратно на компьютер", "отключи игровой режим", "выйди из игрового режима", "вернись на компьютер", "выход с игрового режима", "рабочее пространство", "вернись в игровой режим", "выключи игровой режим"), + "gaming_mode_on": ("включи игровой режим", "перейди в игровой режим", "я хочу поиграть", "переключись на телевизор"), + + "music": ('давай музыку', 'музыка', "яндекс музыка", "включи музыку", "открой музыку", "послушаем музыку", "хочу музыку", "врубай музло", "включи что-то послушать", "давай что-то послушаем"), + "music_off": ('выключи музыку', 'отруби музыку', 'убери музыку', 'отключи музыку', 'закрой музыку', 'останови музыку', 'хватит музыки'), + "music_save": ('сохрани трек', 'мне нравится трек', 'сохрани песню', 'мне нравится песня', 'добавь трек в избранное', 'добавь песню в избранное', 'запомни мелодию', 'запомни трек', 'запомни песню', 'добавь мелодию в избранное', 'сохрани то что сейчас играет', 'добавь то что сейчас играет в избранное', 'лайкни трек', 'лайкни мелодию', 'лайкни песню'), + + "music_next": ('следующий трек', "следующая мелодия", "следующая песня", "переключи трек", "переключи музыку", "переключи мелодию", "переключи песню", "следующая музыка"), + "music_prev": ('предыдущая музыка', 'предыдущий трек', "предыдущая мелодия", "предыдущая песня", "верни трек", "верни мелодию", "верни песню", "верни прошлый трек", "верни прошлую мелодию", "верни прошлую песню", "верни прошлую музыку", "верни то что играло", "давай предыдущий трек", "переключи музыку обратно", "переключи на прошлый трек", "переключи на прошлую мелодию", "переключи на прошлую песню"), + + "switch_to_headphones": ('переключи на наушники', 'включи наушники', 'перейди на наушники', 'давай звук в наушники', 'давай звук на наушники', 'переключи звук в наушники', 'переключи звук на наушники', + 'переключи на кракены', 'включи кракены', 'перейди на кракены', 'давай звук в кракены', 'давай звук на кракены', 'переключи звук в кракены', 'переключи звук на кракены'), + "switch_to_dynamics": ('переключи на динамики', 'включи динамики', 'перейди на динамики', 'давай звук в динамики', 'давай звук на динамики', 'переключи звук в динамики', 'переключи звук на динамики', + 'переключи на колонки', 'включи колонки', 'перейди на колонки', 'давай звук в колонки', 'давай звук на колонки', 'переключи звук в колонки', 'переключи звук на колонки'), + + "off": ('выключись', "вырубись", "завершить работу", "закройся", "отключись", "заверши свою работу", "на сегодня хватит", "выгрузи себя из памяти", "ты мне надоел", "пора спать"), + + # "help": ('список команд', 'команды', 'что ты умеешь', 'твои навыки', 'навыки'), + # "ctime": ('время', 'текущее время', 'сейчас времени', 'который час'), + # "joke": ('расскажи анекдот', 'рассмеши', 'шутка', 'расскажи шутку', 'пошути', 'развесели') +} \ No newline at end of file diff --git a/src/custom-commands/Next music.ahk b/custom-commands/Next music.ahk similarity index 100% rename from src/custom-commands/Next music.ahk rename to custom-commands/Next music.ahk diff --git a/src/custom-commands/Next music.exe b/custom-commands/Next music.exe similarity index 100% rename from src/custom-commands/Next music.exe rename to custom-commands/Next music.exe diff --git a/src/custom-commands/Prev music.ahk b/custom-commands/Prev music.ahk similarity index 100% rename from src/custom-commands/Prev music.ahk rename to custom-commands/Prev music.ahk diff --git a/src/custom-commands/Prev music.exe b/custom-commands/Prev music.exe similarity index 100% rename from src/custom-commands/Prev music.exe rename to custom-commands/Prev music.exe diff --git a/src/custom-commands/Run browser.ahk b/custom-commands/Run browser.ahk similarity index 100% rename from src/custom-commands/Run browser.ahk rename to custom-commands/Run browser.ahk diff --git a/src/custom-commands/Run browser.exe b/custom-commands/Run browser.exe similarity index 100% rename from src/custom-commands/Run browser.exe rename to custom-commands/Run browser.exe diff --git a/src/custom-commands/Run google.ahk b/custom-commands/Run google.ahk similarity index 100% rename from src/custom-commands/Run google.ahk rename to custom-commands/Run google.ahk diff --git a/src/custom-commands/Run google.exe b/custom-commands/Run google.exe similarity index 100% rename from src/custom-commands/Run google.exe rename to custom-commands/Run google.exe diff --git a/src/custom-commands/Run music.ahk b/custom-commands/Run music.ahk similarity index 100% rename from src/custom-commands/Run music.ahk rename to custom-commands/Run music.ahk diff --git a/src/custom-commands/Run music.exe b/custom-commands/Run music.exe similarity index 100% rename from src/custom-commands/Run music.exe rename to custom-commands/Run music.exe diff --git a/src/custom-commands/Run youtube.ahk b/custom-commands/Run youtube.ahk similarity index 100% rename from src/custom-commands/Run youtube.ahk rename to custom-commands/Run youtube.ahk diff --git a/src/custom-commands/Run youtube.exe b/custom-commands/Run youtube.exe similarity index 100% rename from src/custom-commands/Run youtube.exe rename to custom-commands/Run youtube.exe diff --git a/src/custom-commands/Save music.ahk b/custom-commands/Save music.ahk similarity index 100% rename from src/custom-commands/Save music.ahk rename to custom-commands/Save music.ahk diff --git a/src/custom-commands/Save music.exe b/custom-commands/Save music.exe similarity index 100% rename from src/custom-commands/Save music.exe rename to custom-commands/Save music.exe diff --git a/src/custom-commands/Stop music.ahk b/custom-commands/Stop music.ahk similarity index 100% rename from src/custom-commands/Stop music.ahk rename to custom-commands/Stop music.ahk diff --git a/src/custom-commands/Stop music.exe b/custom-commands/Stop music.exe similarity index 100% rename from src/custom-commands/Stop music.exe rename to custom-commands/Stop music.exe diff --git a/src/custom-commands/Switch back to workspace.ahk b/custom-commands/Switch back to workspace.ahk similarity index 100% rename from src/custom-commands/Switch back to workspace.ahk rename to custom-commands/Switch back to workspace.ahk diff --git a/src/custom-commands/Switch back to workspace.exe b/custom-commands/Switch back to workspace.exe similarity index 100% rename from src/custom-commands/Switch back to workspace.exe rename to custom-commands/Switch back to workspace.exe diff --git a/src/custom-commands/Switch to dynamics.ahk b/custom-commands/Switch to dynamics.ahk similarity index 100% rename from src/custom-commands/Switch to dynamics.ahk rename to custom-commands/Switch to dynamics.ahk diff --git a/src/custom-commands/Switch to dynamics.exe b/custom-commands/Switch to dynamics.exe similarity index 100% rename from src/custom-commands/Switch to dynamics.exe rename to custom-commands/Switch to dynamics.exe diff --git a/src/custom-commands/Switch to gaming mode.ahk b/custom-commands/Switch to gaming mode.ahk similarity index 100% rename from src/custom-commands/Switch to gaming mode.ahk rename to custom-commands/Switch to gaming mode.ahk diff --git a/src/custom-commands/Switch to gaming mode.exe b/custom-commands/Switch to gaming mode.exe similarity index 100% rename from src/custom-commands/Switch to gaming mode.exe rename to custom-commands/Switch to gaming mode.exe diff --git a/src/custom-commands/Switch to headphones.ahk b/custom-commands/Switch to headphones.ahk similarity index 100% rename from src/custom-commands/Switch to headphones.ahk rename to custom-commands/Switch to headphones.ahk diff --git a/src/custom-commands/Switch to headphones.exe b/custom-commands/Switch to headphones.exe similarity index 100% rename from src/custom-commands/Switch to headphones.exe rename to custom-commands/Switch to headphones.exe diff --git a/src/custom-commands/nircmd.exe b/custom-commands/nircmd.exe similarity index 100% rename from src/custom-commands/nircmd.exe rename to custom-commands/nircmd.exe diff --git a/latest_silero_models.yml b/latest_silero_models.yml new file mode 100644 index 0000000..79b0281 --- /dev/null +++ b/latest_silero_models.yml @@ -0,0 +1,507 @@ +# pre-trained STT models +stt_models: + en: + latest: + meta: + name: "en_v6" + sample: "https://models.silero.ai/examples/en_sample.wav" + labels: "https://models.silero.ai/models/en/en_v1_labels.json" + jit: "https://models.silero.ai/models/en/en_v6.jit" + onnx: "https://models.silero.ai/models/en/en_v5.onnx" + jit_q: "https://models.silero.ai/models/en/en_v6_q.jit" + jit_xlarge: "https://models.silero.ai/models/en/en_v6_xlarge.jit" + onnx_xlarge: "https://models.silero.ai/models/en/en_v6_xlarge.onnx" + v6: + meta: + name: "en_v6" + sample: "https://models.silero.ai/examples/en_sample.wav" + labels: "https://models.silero.ai/models/en/en_v1_labels.json" + jit: "https://models.silero.ai/models/en/en_v6.jit" + onnx: "https://models.silero.ai/models/en/en_v5.onnx" + jit_q: "https://models.silero.ai/models/en/en_v6_q.jit" + jit_xlarge: "https://models.silero.ai/models/en/en_v6_xlarge.jit" + onnx_xlarge: "https://models.silero.ai/models/en/en_v6_xlarge.onnx" + v5: + meta: + name: "en_v5" + sample: "https://models.silero.ai/examples/en_sample.wav" + labels: "https://models.silero.ai/models/en/en_v1_labels.json" + jit: "https://models.silero.ai/models/en/en_v5.jit" + onnx: "https://models.silero.ai/models/en/en_v5.onnx" + onnx_q: "https://models.silero.ai/models/en/en_v5_q.onnx" + jit_q: "https://models.silero.ai/models/en/en_v5_q.jit" + jit_xlarge: "https://models.silero.ai/models/en/en_v5_xlarge.jit" + onnx_xlarge: "https://models.silero.ai/models/en/en_v5_xlarge.onnx" + v4_0: + meta: + name: "en_v4_0" + sample: "https://models.silero.ai/examples/en_sample.wav" + labels: "https://models.silero.ai/models/en/en_v1_labels.json" + jit_large: "https://models.silero.ai/models/en/en_v4_0_jit_large.model" + onnx_large: "https://models.silero.ai/models/en/en_v4_0_large.onnx" + v3: + meta: + name: "en_v3" + sample: "https://models.silero.ai/examples/en_sample.wav" + labels: "https://models.silero.ai/models/en/en_v1_labels.json" + jit: "https://models.silero.ai/models/en/en_v3_jit.model" + onnx: "https://models.silero.ai/models/en/en_v3.onnx" + jit_q: "https://models.silero.ai/models/en/en_v3_jit_q.model" + jit_skip: "https://models.silero.ai/models/en/en_v3_jit_skips.model" + jit_large: "https://models.silero.ai/models/en/en_v3_jit_large.model" + onnx_large: "https://models.silero.ai/models/en/en_v3_large.onnx" + jit_xsmall: "https://models.silero.ai/models/en/en_v3_jit_xsmall.model" + jit_q_xsmall: "https://models.silero.ai/models/en/en_v3_jit_q_xsmall.model" + onnx_xsmall: "https://models.silero.ai/models/en/en_v3_xsmall.onnx" + v2: + meta: + name: "en_v2" + sample: "https://models.silero.ai/examples/en_sample.wav" + labels: "https://models.silero.ai/models/en/en_v1_labels.json" + jit: "https://models.silero.ai/models/en/en_v2_jit.model" + onnx: "https://models.silero.ai/models/en/en_v2.onnx" + tf: "https://models.silero.ai/models/en/en_v2_tf.tar.gz" + v1: + meta: + name: "en_v1" + sample: "https://models.silero.ai/examples/en_sample.wav" + labels: "https://models.silero.ai/models/en/en_v1_labels.json" + jit: "https://models.silero.ai/models/en/en_v1_jit.model" + onnx: "https://models.silero.ai/models/en/en_v1.onnx" + tf: "https://models.silero.ai/models/en/en_v1_tf.tar.gz" + de: + latest: + meta: + name: "de_v1" + sample: "https://models.silero.ai/examples/de_sample.wav" + labels: "https://models.silero.ai/models/de/de_v1_labels.json" + jit: "https://models.silero.ai/models/de/de_v1_jit.model" + onnx: "https://models.silero.ai/models/de/de_v1.onnx" + tf: "https://models.silero.ai/models/de/de_v1_tf.tar.gz" + v1: + meta: + name: "de_v1" + sample: "https://models.silero.ai/examples/de_sample.wav" + labels: "https://models.silero.ai/models/de/de_v1_labels.json" + jit_large: "https://models.silero.ai/models/de/de_v1_jit.model" + onnx: "https://models.silero.ai/models/de/de_v1.onnx" + tf: "https://models.silero.ai/models/de/de_v1_tf.tar.gz" + v3: + meta: + name: "de_v3" + sample: "https://models.silero.ai/examples/de_sample.wav" + labels: "https://models.silero.ai/models/de/de_v1_labels.json" + jit_large: "https://models.silero.ai/models/de/de_v3_large.jit" + v4: + meta: + name: "de_v4" + sample: "https://models.silero.ai/examples/de_sample.wav" + labels: "https://models.silero.ai/models/de/de_v1_labels.json" + jit_large: "https://models.silero.ai/models/de/de_v4_large.jit" + onnx_large: "https://models.silero.ai/models/de/de_v4_large.onnx" + es: + latest: + meta: + name: "es_v1" + sample: "https://models.silero.ai/examples/es_sample.wav" + labels: "https://models.silero.ai/models/es/es_v1_labels.json" + jit: "https://models.silero.ai/models/es/es_v1_jit.model" + onnx: "https://models.silero.ai/models/es/es_v1.onnx" + tf: "https://models.silero.ai/models/es/es_v1_tf.tar.gz" + ua: + latest: + meta: + name: "ua_v3" + sample: "https://models.silero.ai/examples/ua_sample.wav" + credits: + datasets: + speech-recognition-uk: https://github.com/egorsmkv/speech-recognition-uk + labels: "https://models.silero.ai/models/ua/ua_v1_labels.json" + jit: "https://models.silero.ai/models/ua/ua_v3_jit.model" + jit_q: "https://models.silero.ai/models/ua/ua_v3_jit_q.model" + onnx: "https://models.silero.ai/models/ua/ua_v3.onnx" + v3: + meta: + name: "ua_v3" + sample: "https://models.silero.ai/examples/ua_sample.wav" + credits: + datasets: + speech-recognition-uk: https://github.com/egorsmkv/speech-recognition-uk + labels: "https://models.silero.ai/models/ua/ua_v1_labels.json" + jit: "https://models.silero.ai/models/ua/ua_v3_jit.model" + jit_q: "https://models.silero.ai/models/ua/ua_v3_jit_q.model" + onnx: "https://models.silero.ai/models/ua/ua_v3.onnx" + v1: + meta: + name: "ua_v1" + sample: "https://models.silero.ai/examples/ua_sample.wav" + credits: + datasets: + speech-recognition-uk: https://github.com/egorsmkv/speech-recognition-uk + labels: "https://models.silero.ai/models/ua/ua_v1_labels.json" + jit: "https://models.silero.ai/models/ua/ua_v1_jit.model" + jit_q: "https://models.silero.ai/models/ua/ua_v1_jit_q.model" +tts_models: + ru: + ru_v3: + latest: + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + package: 'https://models.silero.ai/models/tts/ru/ru_v3.pt' + sample_rate: [8000, 24000, 48000] + aidar_v2: + latest: + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + package: 'https://models.silero.ai/models/tts/ru/v2_aidar.pt' + sample_rate: [8000, 16000] + aidar_8khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_aidar_8000.jit' + sample_rate: 8000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_aidar_8000.jit' + sample_rate: 8000 + aidar_16khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_aidar_16000.jit' + sample_rate: 16000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_aidar_16000.jit' + sample_rate: 16000 + baya_v2: + latest: + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + package: 'https://models.silero.ai/models/tts/ru/v2_baya.pt' + sample_rate: [8000, 16000] + baya_8khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_baya_8000.jit' + sample_rate: 8000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_baya_8000.jit' + sample_rate: 8000 + baya_16khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_baya_16000.jit' + sample_rate: 16000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_baya_16000.jit' + sample_rate: 16000 + irina_v2: + latest: + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + package: 'https://models.silero.ai/models/tts/ru/v2_irina.pt' + sample_rate: [8000, 16000] + irina_8khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_irina_8000.jit' + sample_rate: 8000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_irina_8000.jit' + sample_rate: 8000 + irina_16khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_irina_16000.jit' + sample_rate: 16000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_irina_16000.jit' + sample_rate: 16000 + kseniya_v2: + latest: + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + package: 'https://models.silero.ai/models/tts/ru/v2_kseniya.pt' + sample_rate: [8000, 16000] + kseniya_8khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_kseniya_8000.jit' + sample_rate: 8000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_kseniya_8000.jit' + sample_rate: 8000 + kseniya_16khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_kseniya_16000.jit' + sample_rate: 16000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_kseniya_16000.jit' + sample_rate: 16000 + natasha_v2: + latest: + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + package: 'https://models.silero.ai/models/tts/ru/v2_natasha.pt' + sample_rate: [8000, 16000] + natasha_8khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_natasha_8000.jit' + sample_rate: 8000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_natasha_8000.jit' + sample_rate: 8000 + natasha_16khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_natasha_16000.jit' + sample_rate: 16000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_natasha_16000.jit' + sample_rate: 16000 + ruslan_v2: + latest: + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + package: 'https://models.silero.ai/models/tts/ru/v2_ruslan.pt' + sample_rate: [8000, 16000] + ruslan_8khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_ruslan_8000.jit' + sample_rate: 8000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_ruslan_8000.jit' + sample_rate: 8000 + ruslan_16khz: + latest: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_ruslan_16000.jit' + sample_rate: 16000 + v1: + tokenset: '_~абвгдеёжзийклмнопрстуфхцчшщъыьэюя +.,!?…:;–' + example: 'В н+едрах т+ундры в+ыдры в г+етрах т+ырят в в+ёдра +ядра к+едров.' + jit: 'https://models.silero.ai/models/tts/ru/v1_ruslan_16000.jit' + sample_rate: 16000 + en: + lj_v2: + latest: + example: 'Can you can a canned can into an un-canned can like a canner can can a canned can into an un-canned can?' + package: 'https://models.silero.ai/models/tts/en/v2_lj.pt' + sample_rate: [8000, 16000] + lj_8khz: + latest: + tokenset: '_~abcdefghijklmnopqrstuvwxyz .,!?…:;–' + example: 'Can you can a canned can into an un-canned can like a canner can can a canned can into an un-canned can?' + jit: 'https://models.silero.ai/models/tts/en/v1_lj_8000.jit' + sample_rate: 8000 + v1: + tokenset: '_~abcdefghijklmnopqrstuvwxyz .,!?…:;–' + example: 'Can you can a canned can into an un-canned can like a canner can can a canned can into an un-canned can?' + jit: 'https://models.silero.ai/models/tts/en/v1_lj_8000.jit' + sample_rate: 8000 + lj_16khz: + latest: + tokenset: '_~abcdefghijklmnopqrstuvwxyz .,!?…:;–' + example: 'Can you can a canned can into an un-canned can like a canner can can a canned can into an un-canned can?' + jit: 'https://models.silero.ai/models/tts/en/v1_lj_16000.jit' + sample_rate: 16000 + v1: + tokenset: '_~abcdefghijklmnopqrstuvwxyz .,!?…:;–' + example: 'Can you can a canned can into an un-canned can like a canner can can a canned can into an un-canned can?' + jit: 'https://models.silero.ai/models/tts/en/v1_lj_16000.jit' + sample_rate: 16000 + de: + thorsten_v2: + latest: + example: 'Fischers Fritze fischt frische Fische, Frische Fische fischt Fischers Fritze.' + package: 'https://models.silero.ai/models/tts/de/v2_thorsten.pt' + sample_rate: [8000, 16000] + thorsten_8khz: + latest: + tokenset: '_~abcdefghijklmnopqrstuvwxyzäöüß .,!?…:;–' + example: 'Fischers Fritze fischt frische Fische, Frische Fische fischt Fischers Fritze.' + jit: 'https://models.silero.ai/models/tts/de/v1_thorsten_8000.jit' + sample_rate: 8000 + v1: + tokenset: '_~abcdefghijklmnopqrstuvwxyzäöüß .,!?…:;–' + example: 'Fischers Fritze fischt frische Fische, Frische Fische fischt Fischers Fritze.' + jit: 'https://models.silero.ai/models/tts/de/v1_thorsten_8000.jit' + sample_rate: 8000 + thorsten_16khz: + latest: + tokenset: '_~abcdefghijklmnopqrstuvwxyzäöüß .,!?…:;–' + example: 'Fischers Fritze fischt frische Fische, Frische Fische fischt Fischers Fritze.' + jit: 'https://models.silero.ai/models/tts/de/v1_thorsten_16000.jit' + sample_rate: 16000 + v1: + tokenset: '_~abcdefghijklmnopqrstuvwxyzäöüß .,!?…:;–' + example: 'Fischers Fritze fischt frische Fische, Frische Fische fischt Fischers Fritze.' + jit: 'https://models.silero.ai/models/tts/de/v1_thorsten_16000.jit' + sample_rate: 16000 + es: + tux_v2: + latest: + example: 'Hoy ya es ayer y ayer ya es hoy, ya llegó el día, y hoy es hoy.' + package: 'https://models.silero.ai/models/tts/es/v2_tux.pt' + sample_rate: [8000, 16000] + tux_8khz: + latest: + tokenset: '_~abcdefghijklmnopqrstuvwxyzáéíñóú .,!?…:;–¡¿' + example: 'Hoy ya es ayer y ayer ya es hoy, ya llegó el día, y hoy es hoy.' + jit: 'https://models.silero.ai/models/tts/es/v1_tux_8000.jit' + sample_rate: 8000 + v1: + tokenset: '_~abcdefghijklmnopqrstuvwxyzáéíñóú .,!?…:;–¡¿' + example: 'Hoy ya es ayer y ayer ya es hoy, ya llegó el día, y hoy es hoy.' + jit: 'https://models.silero.ai/models/tts/es/v1_tux_8000.jit' + sample_rate: 8000 + tux_16khz: + latest: + tokenset: '_~abcdefghijklmnopqrstuvwxyzáéíñóú .,!?…:;–¡¿' + example: 'Hoy ya es ayer y ayer ya es hoy, ya llegó el día, y hoy es hoy.' + jit: 'https://models.silero.ai/models/tts/es/v1_tux_16000.jit' + sample_rate: 16000 + v1: + tokenset: '_~abcdefghijklmnopqrstuvwxyzáéíñóú .,!?…:;–¡¿' + example: 'Hoy ya es ayer y ayer ya es hoy, ya llegó el día, y hoy es hoy.' + jit: 'https://models.silero.ai/models/tts/es/v1_tux_16000.jit' + sample_rate: 16000 + fr: + gilles_v2: + latest: + example: 'Je suis ce que je suis, et si je suis ce que je suis, qu’est ce que je suis.' + package: 'https://models.silero.ai/models/tts/fr/v2_gilles.pt' + sample_rate: [8000, 16000] + gilles_8khz: + latest: + tokenset: '_~abcdefghijklmnopqrstuvwxyzéàèùâêîôûç .,!?…:;–' + example: 'Je suis ce que je suis, et si je suis ce que je suis, qu’est ce que je suis.' + jit: 'https://models.silero.ai/models/tts/fr/v1_gilles_8000.jit' + sample_rate: 8000 + v1: + tokenset: '_~abcdefghijklmnopqrstuvwxyzéàèùâêîôûç .,!?…:;–' + example: 'Je suis ce que je suis, et si je suis ce que je suis, qu’est ce que je suis.' + jit: 'https://models.silero.ai/models/tts/fr/v1_gilles_8000.jit' + sample_rate: 8000 + gilles_16khz: + latest: + tokenset: '_~abcdefghijklmnopqrstuvwxyzéàèùâêîôûç .,!?…:;–' + example: 'Je suis ce que je suis, et si je suis ce que je suis, qu’est ce que je suis.' + jit: 'https://models.silero.ai/models/tts/fr/v1_gilles_16000.jit' + sample_rate: 16000 + v1: + tokenset: '_~abcdefghijklmnopqrstuvwxyzéàèùâêîôûç .,!?…:;–' + example: 'Je suis ce que je suis, et si je suis ce que je suis, qu’est ce que je suis.' + jit: 'https://models.silero.ai/models/tts/fr/v1_gilles_16000.jit' + sample_rate: 16000 + ba: + aigul_v2: + latest: + example: 'Салауат Юлаевтың тормошо һәм яҙмышы хаҡындағы документтарҙың һәм шиғри әҫәрҙәренең бик аҙ өлөшө генә һаҡланған.' + package: 'https://models.silero.ai/models/tts/ba/v2_aigul.pt' + sample_rate: [8000, 16000] + language_name: 'bashkir' + xal: + erdni_v2: + latest: + example: 'Һорвн, дөрвн күн ирәд, һазань чиңгнв. Байн Цецн хаана һорвн көвүн күүндҗәнә.' + package: 'https://models.silero.ai/models/tts/xal/v2_erdni.pt' + sample_rate: [8000, 16000] + language_name: 'kalmyk' + tt: + dilyara_v2: + latest: + example: 'Ис+әнмесез, с+аумысез, нишл+әп кәҗәгезн+е с+аумыйсыз, әтәчег+ез күк+әй салг+ан, нишл+әп чыг+ып +алмыйсыз.' + package: 'https://models.silero.ai/models/tts/tt/v2_dilyara.pt' + sample_rate: [8000, 16000] + language_name: 'tatar' + uz: + dilnavoz_v2: + latest: + example: 'Tanishganimdan xursandman.' + package: 'https://models.silero.ai/models/tts/uz/v2_dilnavoz.pt' + sample_rate: [8000, 16000] + language_name: 'uzbek' + ua: + mykyta_v2: + latest: + example: 'К+отики - пухн+асті жив+отики.' + package: 'https://models.silero.ai/models/tts/ua/v22_mykyta_48k.pt' + sample_rate: [8000, 24000, 48000] + language_name: 'ukrainian' + multi: + multi_v2: + latest: + package: 'https://models.silero.ai/models/tts/multi/v2_multi.pt' + sample_rate: [8000, 16000] + speakers: + aidar: + lang: 'ru' + example: 'Съ+ешьте ещ+ё +этих м+ягких франц+узских б+улочек, д+а в+ыпейте ч+аю.' + baya: + lang: 'ru' + example: 'Съ+ешьте ещ+ё +этих м+ягких франц+узских б+улочек, д+а в+ыпейте ч+аю.' + kseniya: + lang: 'ru' + example: 'Съ+ешьте ещ+ё +этих м+ягких франц+узских б+улочек, д+а в+ыпейте ч+аю.' + irina: + lang: 'ru' + example: 'Съ+ешьте ещ+ё +этих м+ягких франц+узских б+улочек, д+а в+ыпейте ч+аю.' + ruslan: + lang: 'ru' + example: 'Съ+ешьте ещ+ё +этих м+ягких франц+узских б+улочек, д+а в+ыпейте ч+аю.' + natasha: + lang: 'ru' + example: 'Съ+ешьте ещ+ё +этих м+ягких франц+узских б+улочек, д+а в+ыпейте ч+аю.' + thorsten: + lang: 'de' + example: 'Fischers Fritze fischt frische Fische, Frische Fische fischt Fischers Fritze.' + tux: + lang: 'es' + example: 'Hoy ya es ayer y ayer ya es hoy, ya llegó el día, y hoy es hoy.' + gilles: + lang: 'fr' + example: 'Je suis ce que je suis, et si je suis ce que je suis, qu’est ce que je suis.' + lj: + lang: 'en' + example: 'Can you can a canned can into an un-canned can like a canner can can a canned can into an un-canned can?' + dilyara: + lang: 'tt' + example: 'Пес+и пес+и песик+әй, борыннар+ы бәләк+әй.' +te_models: + latest: + package: "https://models.silero.ai/te_models/v2_4lang_q.pt" + languages: ['en', 'de', 'ru', 'es'] + punct: '.,-!?—' + v2: + package: "https://models.silero.ai/te_models/v2_4lang_q.pt" + languages: ['en', 'de', 'ru', 'es'] + punct: '.,-!?—' diff --git a/main.py b/main.py new file mode 100644 index 0000000..88fbb1c --- /dev/null +++ b/main.py @@ -0,0 +1,331 @@ +# КЕША 3.0 (aka Jarvis) +""" + ВНИМАНИЕ!!! + Пока что это максимально сырой прототип. + Позже будет опубликована нормальная версия с удобной установкой и поддержкой всего чего только можно. + А пока что, код ниже к вашим услугам, сэр :) + + @TODO: + 0. Адекватная архитектура кода, собрать всё и переписать from the ground up. + 1. Задержка воспроизведения звука на основе реальной длительности .wav файла (прогружать при запуске?) + 2. Speech to intent? + 3. Отключать self listening protection во время воспроизведения с наушников. + 4. Указание из списка или по имени будет реализовано позже. +""" + +import os +import random + +import pvporcupine +import simpleaudio as sa +from pvrecorder import PvRecorder +from rich import print +import vosk +import sys +import queue +import json +import struct +import config +from fuzzywuzzy import fuzz +import tts +import datetime +from num2t4ru import num2text +import subprocess +import time + +from ctypes import POINTER, cast +from comtypes import CLSCTX_ALL, COMObject +from pycaw.pycaw import ( + AudioUtilities, + IAudioEndpointVolume +) + +import openai +from gpytranslate import SyncTranslator + +CDIR = os.getcwd() + +# init translator +t = SyncTranslator() + +# init openai +openai.api_key = config.OPENAI_TOKEN + +# PORCUPINE +porcupine = pvporcupine.create( + access_key=config.PICOVOICE_TOKEN, + keywords=['jarvis'], + sensitivities=[1] +) +# print(pvporcupine.KEYWORDS) + +# VOSK +model = vosk.Model("model_small") +samplerate = 16000 +device = config.MICROPHONE_INDEX +kaldi_rec = vosk.KaldiRecognizer(model, samplerate) +q = queue.Queue() + + +def gpt_answer(message): + model_engine = "text-davinci-003" + max_tokens = 128 # default 1024 + prompt = t.translate(message, targetlang="en") + completion = openai.Completion.create( + engine=model_engine, + prompt=prompt.text, + max_tokens=max_tokens, + temperature=0.5, + top_p=1, + frequency_penalty=0, + presence_penalty=0 + ) + + translated_result = t.translate(completion.choices[0].text, targetlang="ru") + return translated_result.text + + +# play(f'{CDIR}\\sound\\ok{random.choice([1, 2, 3, 4])}.wav') +def play(phrase, wait_done=True): + global recorder + filename = f"{CDIR}\\sound\\" + + if phrase == "greet": # for py 3.8 + filename += f"greet{random.choice([1, 2, 3])}.wav" + elif phrase == "ok": + filename += f"ok{random.choice([1, 2, 3])}.wav" + elif phrase == "not_found": + filename += "not_found.wav" + elif phrase == "thanks": + filename += "thanks.wav" + elif phrase == "run": + filename += "run.wav" + elif phrase == "stupid": + filename += "stupid.wav" + elif phrase == "ready": + filename += "ready.wav" + elif phrase == "off": + filename += "off.wav" + + if wait_done: + recorder.stop() + + wave_obj = sa.WaveObject.from_wave_file(filename) + wave_obj.play() + + if wait_done: + # play_obj.wait_done() + # time.sleep((len(wave_obj.audio_data) / wave_obj.sample_rate) + 0.5) + # print("END") + time.sleep(0.8) + recorder.start() + + +def q_callback(indata, frames, time, status): + if status: + print(status, file=sys.stderr) + q.put(bytes(indata)) + + +def va_respond(voice: str): + global recorder + print(f"Распознано: {voice}") + + cmd = recognize_cmd(filter_cmd(voice)) + + print(cmd) + + if len(cmd['cmd'].strip()) <= 0: + return False + elif cmd['percent'] < 70 or cmd['cmd'] not in config.VA_CMD_LIST.keys(): + # play("not_found") + # tts.va_speak("Что?") + if fuzz.ratio(voice.join(voice.split()[:1]).strip(), "скажи") > 75: + gpt_result = gpt_answer(voice) + recorder.stop() + tts.va_speak(gpt_result) + time.sleep(1) + recorder.start() + return False + else: + play("not_found") + time.sleep(1) + + return False + else: + execute_cmd(cmd['cmd'], voice) + return True + + +def filter_cmd(raw_voice: str): + cmd = raw_voice + + for x in config.VA_ALIAS: + cmd = cmd.replace(x, "").strip() + + for x in config.VA_TBR: + cmd = cmd.replace(x, "").strip() + + return cmd + + +def recognize_cmd(cmd: str): + rc = {'cmd': '', 'percent': 0} + for c, v in config.VA_CMD_LIST.items(): + + for x in v: + vrt = fuzz.ratio(cmd, x) + if vrt > rc['percent']: + rc['cmd'] = c + rc['percent'] = vrt + + return rc + + +def execute_cmd(cmd: str, voice: str): + if cmd == 'help': + # help + text = "Я умею: ..." + text += "произносить время ..." + text += "рассказывать анекдоты ..." + text += "и открывать браузер" + tts.va_speak(text) + pass + elif cmd == 'ctime': + # current time + now = datetime.datetime.now() + text = "Сейч+ас " + num2text(now.hour) + " " + num2text(now.minute) + tts.va_speak(text) + + elif cmd == 'joke': + jokes = ['Как смеются программисты? ... ехе ехе ехе', + 'ЭсКьюЭль запрос заходит в бар, подходит к двум столам и спрашивает .. «м+ожно присоединиться?»', + 'Программист это машина для преобразования кофе в код'] + + play("ok", True) + + tts.va_speak(random.choice(jokes)) + + elif cmd == 'open_browser': + subprocess.Popen([f'{CDIR}\\custom-commands\\Run browser.exe']) + play("ok") + + elif cmd == 'open_youtube': + subprocess.Popen([f'{CDIR}\\custom-commands\\Run youtube.exe']) + play("ok") + + elif cmd == 'open_google': + subprocess.Popen([f'{CDIR}\\custom-commands\\Run google.exe']) + play("ok") + + elif cmd == 'music': + subprocess.Popen([f'{CDIR}\\custom-commands\\Run music.exe']) + play("ok") + + elif cmd == 'music_off': + subprocess.Popen([f'{CDIR}\\custom-commands\\Stop music.exe']) + time.sleep(0.2) + play("ok") + + elif cmd == 'music_save': + subprocess.Popen([f'{CDIR}\\custom-commands\\Save music.exe']) + time.sleep(0.2) + play("ok") + + elif cmd == 'music_next': + subprocess.Popen([f'{CDIR}\\custom-commands\\Next music.exe']) + time.sleep(0.2) + play("ok") + + elif cmd == 'music_prev': + subprocess.Popen([f'{CDIR}\\custom-commands\\Prev music.exe']) + time.sleep(0.2) + play("ok") + + elif cmd == 'sound_off': + play("ok", True) + + devices = AudioUtilities.GetSpeakers() + interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None) + volume = cast(interface, POINTER(IAudioEndpointVolume)) + volume.SetMute(1, None) + + elif cmd == 'sound_on': + devices = AudioUtilities.GetSpeakers() + interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None) + volume = cast(interface, POINTER(IAudioEndpointVolume)) + volume.SetMute(0, None) + + play("ok") + + elif cmd == 'thanks': + play("thanks") + + elif cmd == 'stupid': + play("stupid") + + elif cmd == 'gaming_mode_on': + play("ok") + subprocess.check_call([f'{CDIR}\\custom-commands\\Switch to gaming mode.exe']) + play("ready") + + elif cmd == 'gaming_mode_off': + play("ok") + subprocess.check_call([f'{CDIR}\\custom-commands\\Switch back to workspace.exe']) + play("ready") + + elif cmd == 'switch_to_headphones': + play("ok") + subprocess.check_call([f'{CDIR}\\custom-commands\\Switch to headphones.exe']) + time.sleep(0.5) + play("ready") + + elif cmd == 'switch_to_dynamics': + play("ok") + subprocess.check_call([f'{CDIR}\\custom-commands\\Switch to dynamics.exe']) + time.sleep(0.5) + play("ready") + + elif cmd == 'off': + play("off", True) + + porcupine.delete() + exit(0) + + +# `-1` is the default input audio device. +recorder = PvRecorder(device_index=config.MICROPHONE_INDEX, frame_length=porcupine.frame_length) +recorder.start() +print('Using device: %s' % recorder.selected_device) + +print(f"Jarvis (v3.0) начал свою работу ...") +play("run") +time.sleep(0.5) + +ltc = time.time() - 1000 + +while True: + try: + pcm = recorder.read() + keyword_index = porcupine.process(pcm) + + if keyword_index >= 0: + recorder.stop() + play("greet", True) + print("Yes, sir.") + recorder.start() # prevent self recording + ltc = time.time() + + while time.time() - ltc <= 10: + pcm = recorder.read() + sp = struct.pack("h" * len(pcm), *pcm) + + if kaldi_rec.AcceptWaveform(sp): + if va_respond(json.loads(kaldi_rec.Result())["text"]): + ltc = time.time() + + break + + except Exception as err: + print(f"Unexpected {err=}, {type(err)=}") + raise diff --git a/main_old.py b/main_old.py new file mode 100644 index 0000000..fb0ae65 --- /dev/null +++ b/main_old.py @@ -0,0 +1,81 @@ +# КЕША 2.0 + +import config +import stt +import tts +from fuzzywuzzy import fuzz +import datetime +from num2t4ru import num2text +import webbrowser +import random + + +print(f"{config.VA_NAME} (v{config.VA_VER}) начал свою работу ...") + + +def va_respond(voice: str): + print(voice) + if voice.startswith(config.VA_ALIAS): + # обращаются к ассистенту + cmd = recognize_cmd(filter_cmd(voice)) + + if cmd['cmd'] not in config.VA_CMD_LIST.keys(): + tts.va_speak("Что?") + else: + execute_cmd(cmd['cmd']) + + +def filter_cmd(raw_voice: str): + cmd = raw_voice + + for x in config.VA_ALIAS: + cmd = cmd.replace(x, "").strip() + + for x in config.VA_TBR: + cmd = cmd.replace(x, "").strip() + + return cmd + + +def recognize_cmd(cmd: str): + rc = {'cmd': '', 'percent': 0} + for c, v in config.VA_CMD_LIST.items(): + + for x in v: + vrt = fuzz.ratio(cmd, x) + if vrt > rc['percent']: + rc['cmd'] = c + rc['percent'] = vrt + + return rc + + +def execute_cmd(cmd: str): + if cmd == 'help': + # help + text = "Я умею: ..." + text += "произносить время ..." + text += "рассказывать анекдоты ..." + text += "и открывать браузер" + tts.va_speak(text) + pass + elif cmd == 'ctime': + # current time + now = datetime.datetime.now() + text = "Сейч+ас " + num2text(now.hour) + " " + num2text(now.minute) + tts.va_speak(text) + + elif cmd == 'joke': + jokes = ['Как смеются программисты? ... ехе ехе ехе', + 'ЭсКьюЭль запрос заходит в бар, подходит к двум столам и спрашивает .. «м+ожно присоединиться?»', + 'Программист это машина для преобразования кофе в код'] + + tts.va_speak(random.choice(jokes)) + + elif cmd == 'open_browser': + chrome_path = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s' + webbrowser.get(chrome_path).open("http://python.org") + + +# начать прослушивание команд +stt.va_listen(va_respond) \ No newline at end of file diff --git a/pv_custom_keywords/A-Knocks_en_windows_v2_1_0.ppn b/pv_custom_keywords/A-Knocks_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..42a6564 Binary files /dev/null and b/pv_custom_keywords/A-Knocks_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Can-finger_en_windows_v2_1_0.ppn b/pv_custom_keywords/Can-finger_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..f9ec755 Binary files /dev/null and b/pv_custom_keywords/Can-finger_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Conceal_en_windows_v2_1_0.ppn b/pv_custom_keywords/Conceal_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..bf11a66 Binary files /dev/null and b/pv_custom_keywords/Conceal_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Disillusion_en_windows_v2_1_0.ppn b/pv_custom_keywords/Disillusion_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..4e9bbd6 Binary files /dev/null and b/pv_custom_keywords/Disillusion_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Expellee-aramus_en_windows_v2_1_0.ppn b/pv_custom_keywords/Expellee-aramus_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..58d4a3d Binary files /dev/null and b/pv_custom_keywords/Expellee-aramus_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/In-St-Your_en_windows_v2_1_0.ppn b/pv_custom_keywords/In-St-Your_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..f4a1980 Binary files /dev/null and b/pv_custom_keywords/In-St-Your_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Lady-also_en_windows_v2_1_0.ppn b/pv_custom_keywords/Lady-also_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..b2d8aa1 Binary files /dev/null and b/pv_custom_keywords/Lady-also_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Lumas_en_windows_v2_1_0.ppn b/pv_custom_keywords/Lumas_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..c3977d2 Binary files /dev/null and b/pv_custom_keywords/Lumas_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/Proud-to-go_en_windows_v2_1_0.ppn b/pv_custom_keywords/Proud-to-go_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..cab1453 Binary files /dev/null and b/pv_custom_keywords/Proud-to-go_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/R-Vail-leo_en_windows_v2_1_0.ppn b/pv_custom_keywords/R-Vail-leo_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..7ade6b0 Binary files /dev/null and b/pv_custom_keywords/R-Vail-leo_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/The-pool-so_en_windows_v2_1_0.ppn b/pv_custom_keywords/The-pool-so_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..f44fcfb Binary files /dev/null and b/pv_custom_keywords/The-pool-so_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/aloha-mora_en_windows_v2_1_0.ppn b/pv_custom_keywords/aloha-mora_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..19945ec Binary files /dev/null and b/pv_custom_keywords/aloha-mora_en_windows_v2_1_0.ppn differ diff --git a/pv_custom_keywords/terrifical-status_en_windows_v2_1_0.ppn b/pv_custom_keywords/terrifical-status_en_windows_v2_1_0.ppn new file mode 100644 index 0000000..0ed6f7b Binary files /dev/null and b/pv_custom_keywords/terrifical-status_en_windows_v2_1_0.ppn differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b771287 Binary files /dev/null and b/requirements.txt differ diff --git a/sound/greet1.wav b/sound/greet1.wav new file mode 100644 index 0000000..af80afc Binary files /dev/null and b/sound/greet1.wav differ diff --git a/sound/greet2.wav b/sound/greet2.wav new file mode 100644 index 0000000..0f438db Binary files /dev/null and b/sound/greet2.wav differ diff --git a/sound/greet3.wav b/sound/greet3.wav new file mode 100644 index 0000000..fd889b1 Binary files /dev/null and b/sound/greet3.wav differ diff --git a/src/src/not_found.wav b/sound/not_found.wav similarity index 100% rename from src/src/not_found.wav rename to sound/not_found.wav diff --git a/sound/off.wav b/sound/off.wav new file mode 100644 index 0000000..103b3c4 Binary files /dev/null and b/sound/off.wav differ diff --git a/sound/ok1.wav b/sound/ok1.wav new file mode 100644 index 0000000..af33414 Binary files /dev/null and b/sound/ok1.wav differ diff --git a/sound/ok2.wav b/sound/ok2.wav new file mode 100644 index 0000000..d42baf5 Binary files /dev/null and b/sound/ok2.wav differ diff --git a/sound/ok3.wav b/sound/ok3.wav new file mode 100644 index 0000000..7e163f4 Binary files /dev/null and b/sound/ok3.wav differ diff --git a/sound/ready.wav b/sound/ready.wav new file mode 100644 index 0000000..f918c76 Binary files /dev/null and b/sound/ready.wav differ diff --git a/src/src/run.wav b/sound/run.wav similarity index 100% rename from src/src/run.wav rename to sound/run.wav diff --git a/sound/stupid.wav b/sound/stupid.wav new file mode 100644 index 0000000..6db6a12 Binary files /dev/null and b/sound/stupid.wav differ diff --git a/src/src/thanks.wav b/sound/thanks.wav similarity index 100% rename from src/src/thanks.wav rename to sound/thanks.wav diff --git a/speech.wav b/speech.wav new file mode 100644 index 0000000..1b5f781 Binary files /dev/null and b/speech.wav differ diff --git a/src/app/__init__.py b/src/app/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/commands.py b/src/app/commands.py deleted file mode 100644 index 0b09896..0000000 --- a/src/app/commands.py +++ /dev/null @@ -1,165 +0,0 @@ -import os -import yaml -import time -import random -import openai -import config -import subprocess - -from .tts import cached_response, model_response - -from pycaw.pycaw import ( - AudioUtilities, - IAudioEndpointVolume -) -from ctypes import POINTER, cast -from comtypes import CLSCTX_ALL -from gpytranslate import SyncTranslator - -RESPONSES = yaml.safe_load( - open('responses.yaml'), -) -CDIR = os.getcwd() -t = SyncTranslator() -openai.api_key = config.OPENAI_TOKEN - -def execute_cmd(cmd: str): - - if cmd == 'help': - - text = ( - "Я умею: ..." - "произносить время ..." - "рассказывать анекдоты ..." - "и открывать браузер" - ) - model_response(text) - - - elif cmd == 'joke': - jokes = ['Как смеются программисты? ... ехе ехе ехе', - 'ЭсКьюЭль запрос заходит в бар, подходит к двум столам и спрашивает .. «м+ожно присоединиться?»', - 'Программист это машина для преобразования кофе в код'] - - cached_response("ok") - - model_response(random.choice(jokes)) - - elif cmd == 'open_browser': - - subprocess.Popen([f'{CDIR}\\custom-commands\\Run browser.exe']) - cached_response("ok") - - elif cmd == 'open_youtube': - - subprocess.Popen([f'{CDIR}\\custom-commands\\Run youtube.exe']) - cached_response("ok") - - elif cmd == 'open_google': - - subprocess.Popen([f'{CDIR}\\custom-commands\\Run google.exe']) - cached_response("ok") - - elif cmd == 'music': - - subprocess.Popen([f'{CDIR}\\custom-commands\\Run music.exe']) - cached_response("ok") - - elif cmd == 'music_off': - - subprocess.Popen([f'{CDIR}\\custom-commands\\Stop music.exe']) - time.sleep(0.2) - cached_response("ok") - - elif cmd == 'music_save': - - subprocess.Popen([f'{CDIR}\\custom-commands\\Save music.exe']) - time.sleep(0.2) - cached_response("ok") - - elif cmd == 'music_next': - - subprocess.Popen([f'{CDIR}\\custom-commands\\Next music.exe']) - time.sleep(0.2) - cached_response("ok") - - elif cmd == 'music_prev': - - subprocess.Popen([f'{CDIR}\\custom-commands\\Prev music.exe']) - time.sleep(0.2) - cached_response("ok") - - elif cmd == 'sound_off': - - cached_response("ok") - - devices = AudioUtilities.GetSpeakers() - interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None) - volume = cast(interface, POINTER(IAudioEndpointVolume)) - volume.SetMute(1, None) - - elif cmd == 'sound_on': - - devices = AudioUtilities.GetSpeakers() - interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None) - volume = cast(interface, POINTER(IAudioEndpointVolume)) - volume.SetMute(0, None) - - cached_response("ok") - - elif cmd == 'thanks': - - cached_response("thanks") - - elif cmd == 'stupid': - - cached_response("stupid") - - elif cmd == 'gaming_mode_on': - - cached_response("ok") - subprocess.check_call([f'{CDIR}\\custom-commands\\Switch to gaming mode.exe']) - cached_response("ready") - - elif cmd == 'gaming_mode_off': - - cached_response("ok") - subprocess.check_call([f'{CDIR}\\custom-commands\\Switch back to workspace.exe']) - cached_response("ready") - - elif cmd == 'switch_to_headphones': - - cached_response("ok") - subprocess.check_call([f'{CDIR}\\custom-commands\\Switch to headphones.exe']) - time.sleep(0.5) - cached_response("ready") - - elif cmd == 'switch_to_dynamics': - - cached_response("ok") - subprocess.check_call([f'{CDIR}\\custom-commands\\Switch to dynamics.exe']) - time.sleep(0.5) - cached_response("ready") - - elif cmd == 'off': - - cached_response("off") - exit(0) - - -def gpt_answer(message): - model_engine = "text-davinci-003" - max_tokens = 128 # default 1024 - prompt = t.translate(message, targetlang="en") - completion = openai.Completion.create( - engine=model_engine, - prompt=prompt.text, - max_tokens=max_tokens, - temperature=0.5, - top_p=1, - frequency_penalty=0, - presence_penalty=0 - ) - - translated_result = t.translate(completion.choices[0].text, targetlang="ru") - return translated_result.text \ No newline at end of file diff --git a/src/app/recorder.py b/src/app/recorder.py deleted file mode 100644 index 8934d7b..0000000 --- a/src/app/recorder.py +++ /dev/null @@ -1,32 +0,0 @@ -import logging -from queue import Queue -from sounddevice import RawInputStream - - -log = logging.getLogger('app.recorder') - -class Recorder(object): - - def __init__(self, device: int, sample_rate: int=16_000): - - self.queue = Queue() - self.stream = RawInputStream( - samplerate=sample_rate, - blocksize=8_000, - device=device, - dtype='int16', - channels=1, - callback=self._write_to_queue, - ) - - def _write_to_queue(self, data, _, __, status): - - if status: - - log.error(str(status)) - - self.queue.put(bytes(data)) - - def __call__(self): - - return self.stream diff --git a/src/app/stt.py b/src/app/stt.py deleted file mode 100644 index 164f784..0000000 --- a/src/app/stt.py +++ /dev/null @@ -1,139 +0,0 @@ -import json -import time -import yaml -import config -import logging - -from .tts import cached_response, model_response -from .commands import gpt_answer -from .recorder import Recorder - -from fuzzywuzzy import fuzz -from vosk import KaldiRecognizer - - -log = logging.getLogger('jarvis.stt') -COMMANDS = yaml.safe_load(open('responses.yaml')) - -class Dispatcher(object): - - _last_action = 0 - - def __init__(self, recorder: Recorder, vosk: KaldiRecognizer): - - self.recorder = recorder - self.vosk = vosk - - def start(self): - - log.info('Started recording') - - with self.recorder(): - - while True: - - data = self.recorder.queue.get() - - if not self.vosk.AcceptWaveform(data): - - continue - - text = json.loads(self.vosk.Result())['text'] - - if self._last_action < time.time() - 10: - - self.check_input(text) - - else: - - self.dispatch(text) - - - def check_input(self, text: str): - - if not text: - - return - - for word in text.split(): - - if fuzz.ratio(word, 'джарвис') >= 60: - - cached_response('ok') - self._last_action = time.time() - return self.dispatch(text) - - - def dispatch(self, text: str): - - if text and self.va_respond(text): - - self._last_action = time.time() - - - def va_respond(self, voice: str): - - log.info('Распознано: ') - - cmd = self.recognize_cmd(voice) - - if len(cmd['cmd'].strip()) <= 0: - - return False - - elif cmd['percent'] < 70 or cmd['cmd'] not in config.VA_CMD_LIST.keys(): - - if fuzz.ratio(voice.join(voice.split()[:1]).strip(), "скажи") > 75: - - gpt_result = gpt_answer(voice) - model_response(gpt_result) - - return False - - else: - - cached_response("not_found") - - return False - - else: - - self.execute_cmd() - return True - - - def respond(self, phrase: str): - - self.recorder.stream.stop() - cached_response(phrase) - self.recorder.stream.stop() - - - @staticmethod - def filter_cmd(raw_voice: str): - cmd = raw_voice - - for x in config.VA_ALIAS: - cmd = cmd.replace(x, "").strip() - - for x in config.VA_TBR: - cmd = cmd.replace(x, "").strip() - - return cmd - - - @classmethod - def recognize_cmd(cls, cmd: str): - - cmd = cls.filter_cmd(cmd) - - rc = {'cmd': '', 'percent': 0} - for c, v in COMMANDS.items(): - - for x in v: - vrt = fuzz.ratio(cmd, x) - if vrt > rc['percent']: - rc['cmd'] = c - rc['percent'] = vrt - - return rc diff --git a/src/app/tts.py b/src/app/tts.py deleted file mode 100644 index 966d1bf..0000000 --- a/src/app/tts.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import re -import torch -import random -import sounddevice - -from pydub import AudioSegment, playback - - -device = torch.device('cpu') -model, _ = torch.hub.load( - repo_or_dir='snakers4/silero-models', - model='silero_tts', - language='ru', - speaker='ru_v3', -) -model.to(device) - -def from_wav(path: str) -> None: - """ - Play an audiofile - - :param str path: File path - """ - - with open(path, 'rb') as file: - - audio = AudioSegment.from_wav(file) - - playback.play(audio) - - -def cached_response(keyword: str, basedir: str='src', ext: str='wav') -> None: - - files = os.listdir(basedir) - regexp = re.compile( - r'%s\d{0,}\.%s' % ( - keyword, ext, - ), - ) - filename = random.choice([ - filename for filename in files - if re.match(regexp, filename) - ]) - - return from_wav( - os.path.join(basedir, filename), - ) - - -def model_response(text: str): - - audio: torch.Tensor = model.apply_tts( - text=text + "..", - speaker='aidar', - sample_rate=24000, - put_accent=True, - put_yo=True, - ) - sounddevice.play(audio, 24000, blocking=True) diff --git a/src/config.py b/src/config.py deleted file mode 100644 index 3d61dd4..0000000 --- a/src/config.py +++ /dev/null @@ -1,13 +0,0 @@ -VA_NAME = 'Jarvis' - -VA_VER = "3.0" - -VA_ALIAS = ('джарвис', 'кеша', 'кеш', 'инокентий', 'иннокентий', 'кишун', 'киш', 'кишаня', 'кешечка', 'кэш', 'кэша') - -VA_TBR = ('скажи', 'покажи', 'ответь', 'произнеси', 'расскажи', 'сколько') - -MICROPHONE_INDEX = 0 # ID микрофона (можете просто менять ID пока при запуске не отобразится нужный) - -CHROME_PATH = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s' - -OPENAI_TOKEN = "<ТУТ ТОКЕН CHAT-GPT>" diff --git a/src/main.py b/src/main.py deleted file mode 100644 index be21067..0000000 --- a/src/main.py +++ /dev/null @@ -1,32 +0,0 @@ -import logging - -from app import tts -from app.stt import Dispatcher -from app.recorder import Recorder - -from vosk import KaldiRecognizer, Model, SetLogLevel - - -log = logging.getLogger('jarvis.main') - -def main(): - - log.info('Starting up...') - - tts.cached_response('run') - logging.basicConfig( - level=logging.INFO, - format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", - ) - - SetLogLevel(-1) - vosk = KaldiRecognizer(Model("model_small"), 16000) - recorder = Recorder(9) - - dp = Dispatcher(recorder, vosk) - dp.start() - - -if __name__ == '__main__': - - main() \ No newline at end of file diff --git a/src/requirements.txt b/src/requirements.txt deleted file mode 100644 index 35b2f9c..0000000 --- a/src/requirements.txt +++ /dev/null @@ -1,11 +0,0 @@ -pvporcupine == 2.2.0 -sounddevice == 0.4.6 -pydub == 0.25.1 -pycaw == 20230407 -pyyaml == 6.0 -python-levenshtein == 0.20.9 -vosk == 0.3.45 -torch == 2.0.0 -omegaconf == 2.3.0 -gpytranslate == 1.5.1 -openai == 0.27.4 \ No newline at end of file diff --git a/src/responses.yaml b/src/responses.yaml deleted file mode 100644 index dadf398..0000000 --- a/src/responses.yaml +++ /dev/null @@ -1,157 +0,0 @@ -gaming_mode_off: -- рабочий режим -- вернись в рабочий режим -- переключись на компьютер -- обратно на компьютер -- отключи игровой режим -- выйди из игрового режима -- вернись на компьютер -- выход с игрового режима -- рабочее пространство -- вернись в игровой режим -- выключи игровой режим -gaming_mode_on: -- включи игровой режим -- перейди в игровой режим -- я хочу поиграть -- переключись на телевизор -music: -- давай музыку -- музыка -- яндекс музыка -- включи музыку -- открой музыку -- послушаем музыку -- хочу музыку -- врубай музло -- включи что-то послушать -- давай что-то послушаем -music_next: -- следующий трек -- следующая мелодия -- следующая песня -- переключи трек -- переключи музыку -- переключи мелодию -- переключи песню -- следующая музыка -music_off: -- выключи музыку -- отруби музыку -- убери музыку -- отключи музыку -- закрой музыку -- останови музыку -- хватит музыки -music_prev: -- предыдущая музыка -- предыдущий трек -- предыдущая мелодия -- предыдущая песня -- верни трек -- верни мелодию -- верни песню -- верни прошлый трек -- верни прошлую мелодию -- верни прошлую песню -- верни прошлую музыку -- верни то что играло -- давай предыдущий трек -- переключи музыку обратно -- переключи на прошлый трек -- переключи на прошлую мелодию -- переключи на прошлую песню -music_save: -- сохрани трек -- мне нравится трек -- сохрани песню -- мне нравится песня -- добавь трек в избранное -- добавь песню в избранное -- запомни мелодию -- запомни трек -- запомни песню -- добавь мелодию в избранное -- сохрани то что сейчас играет -- добавь то что сейчас играет в избранное -- лайкни трек -- лайкни мелодию -- лайкни песню -'off': -- выключись -- вырубись -- завершить работу -- закройся -- отключись -- заверши свою работу -- на сегодня хватит -- выгрузи себя из памяти -- ты мне надоел -- пора спать -open_browser: -- открой браузер -- запусти браузер -- открой гугл хром -- гугл хром -open_google: -- открой гугл -- гугл -- запусти гугл -open_youtube: -- открой ютуб -- ютуб -- запусти ютуб -sound_off: -- выключи звук -- беззвучный режим -- режим без звука -- отключи звук -sound_on: -- включи звук -- режим со звуком -- верни звук -stupid: -- ты дурак -- ты дебил -- ты глупый -- ты тупой -switch_to_dynamics: -- переключи на динамики -- включи динамики -- перейди на динамики -- давай звук в динамики -- давай звук на динамики -- переключи звук в динамики -- переключи звук на динамики -- переключи на колонки -- включи колонки -- перейди на колонки -- давай звук в колонки -- давай звук на колонки -- переключи звук в колонки -- переключи звук на колонки -switch_to_headphones: -- переключи на наушники -- включи наушники -- перейди на наушники -- давай звук в наушники -- давай звук на наушники -- переключи звук в наушники -- переключи звук на наушники -- переключи на кракены -- включи кракены -- перейди на кракены -- давай звук в кракены -- давай звук на кракены -- переключи звук в кракены -- переключи звук на кракены -thanks: -- спасибо -- молодец -- респект -- ты супер -- отличная работа -- ты крут -- ты большой молодец -- ты реально крут -- ты афигенный diff --git a/stt.py b/stt.py new file mode 100644 index 0000000..e4aa125 --- /dev/null +++ b/stt.py @@ -0,0 +1,30 @@ +import vosk +import sys +import sounddevice as sd +import queue +import json + +model = vosk.Model("model_small") +samplerate = 16000 +device = 2 + +q = queue.Queue() + + +def q_callback(indata, frames, time, status): + if status: + print(status, file=sys.stderr) + q.put(bytes(indata)) + + +def va_listen(callback): + with sd.RawInputStream(samplerate=samplerate, blocksize=8000, device=device, dtype='int16', + channels=1, callback=q_callback): + + rec = vosk.KaldiRecognizer(model, samplerate) + while True: + data = q.get() + if rec.AcceptWaveform(data): + callback(json.loads(rec.Result())["text"]) + #else: + # print(rec.PartialResult()) \ No newline at end of file diff --git a/stt_google.py b/stt_google.py new file mode 100644 index 0000000..c1413d4 --- /dev/null +++ b/stt_google.py @@ -0,0 +1,34 @@ +import speech_recognition as sr +from rich import print +from utils.benchmark import Benchmark + +# import speech_recognition as sr +# for index, name in enumerate(sr.Microphone.list_microphone_names()): +# print("Microphone with name \"{1}\" found for `Microphone(device_index={0})`".format(index, name)) +# exit(1) + +# obtain audio from the microphone +r = sr.Recognizer() +r.pause_threshold = 0.5 +with sr.Microphone(device_index=2) as source: + print("Say something!") + audio = r.listen(source) + +bench = Benchmark() + +# recognize speech using Google Speech Recognition +try: + # for testing purposes, we're just using the default API key + # to use another API key, use `r.recognize_google(audio, key="GOOGLE_SPEECH_RECOGNITION_API_KEY")` + # instead of `r.recognize_google(audio)`\ + while True: + bench.start() + recognized_text = r.recognize_google(audio) + end_time = bench.end() + print(f"[light_sea_green]Google Speech Recognition thinks you said[/]: [dodger_blue1]{recognized_text}[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + print() +except sr.UnknownValueError: + print("Google Speech Recognition could not understand audio") +except sr.RequestError as e: + print("Could not request results from Google Speech Recognition service; {0}".format(e)) \ No newline at end of file diff --git a/stt_picovoice.py b/stt_picovoice.py new file mode 100644 index 0000000..f3fbf02 --- /dev/null +++ b/stt_picovoice.py @@ -0,0 +1,146 @@ +import time + +import pvporcupine +from pvrecorder import PvRecorder +from rich import print +from utils.benchmark import Benchmark +import keyboard +from utils.time import sleep + +porcupine = pvporcupine.create( + access_key='H2JhXpfLdGYG2wMqvc61tipo0uKZQvwkEfA26CAQQe5n1y7zfZGneQ==', + # keywords=['picovoice', 'bumblebee', 'aloha mora'], + keyword_paths=["./pv_custom_keywords/aloha-mora_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/Expellee-aramus_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/Lumas_en_windows_v2_1_0.ppn", + + "./pv_custom_keywords/Proud-to-go_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/A-Knocks_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/In-St-Your_en_windows_v2_1_0.ppn", + + "./pv_custom_keywords/The-pool-so_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/Lady-also_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/R-Vail-leo_en_windows_v2_1_0.ppn", + + "./pv_custom_keywords/Conceal_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/terrifical-status_en_windows_v2_1_0.ppn", + "./pv_custom_keywords/Disillusion_en_windows_v2_1_0.ppn", + + "./pv_custom_keywords/Can-finger_en_windows_v2_1_0.ppn" + ], + sensitivities=[1] * 13 +) + +# `-1` is the default input audio device. +recorder = PvRecorder(device_index=0, frame_length=porcupine.frame_length) +recorder.start() +print('Using device: %s' % recorder.selected_device) + +bench = Benchmark() + +while True: + bench.start() + pcm = recorder.read() + keyword_index = porcupine.process(pcm) + end_time = bench.end() + + if keyword_index == 0: + print("[gold1]Aloha mora[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("f") + elif keyword_index == 1: + print("[bright_red]Expelliarmus[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F1") + sleep(0.05) + keyboard.press_and_release("2") + elif keyword_index == 2: + print("[gold1]Lumos[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F1") + sleep(0.05) + keyboard.press_and_release("1") + + elif keyword_index == 3: + print("[dodger_blue2]Protego[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press("q") + sleep(1/2) + keyboard.release("q") + + elif keyword_index == 4: + print("[gold1]Nox[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F1") + sleep(0.05) + keyboard.press_and_release("1") + + elif keyword_index == 5: + print("[bright_red]Incendio[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F2") + sleep(0.05) + keyboard.press_and_release("1") + + elif keyword_index == 6: + print("[dodger_blue2]Depulso[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F1") + sleep(0.05) + keyboard.press_and_release("4") + + elif keyword_index == 7: + print("[gold1]Levioso[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F1") + sleep(0.05) + keyboard.press_and_release("3") + + elif keyword_index == 8: + print("[dodger_blue2]Revelio[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("R") + + elif keyword_index == 9: + print("[dodger_blue2]Accio[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F2") + sleep(0.05) + keyboard.press_and_release("3") + + elif keyword_index == 10: + print("[bright_red]Petrificus Totalus[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("f") + + elif keyword_index == 11: + print("[dodger_blue2]Disillusionment Spell[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F2") + sleep(0.05) + keyboard.press_and_release("2") + + elif keyword_index == 12: + print("[bright_red]Confringo Spell[/]") + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + + keyboard.press_and_release("F2") + sleep(0.05) + keyboard.press_and_release("4") + + #if keyword_index >= 0: + # break + +porcupine.delete() diff --git a/stt_vosk.py b/stt_vosk.py new file mode 100644 index 0000000..eef8f63 --- /dev/null +++ b/stt_vosk.py @@ -0,0 +1,50 @@ +import vosk +import queue +import json +import sys +import sounddevice as sd +from rich import print +from utils.benchmark import Benchmark + +# import speech_recognition as sr +# for index, name in enumerate(sr.Microphone.list_microphone_names()): +# print("Microphone with name \"{1}\" found for `Microphone(device_index={0})`".format(index, name)) +# exit(1) + +bench = Benchmark() + + +def va_respond(voice: str): + print(f"[light_sea_green]Vosk thinks you said[/]: [dodger_blue1]{voice}[/]") + + +model = vosk.Model("model_small") +samplerate = 16000 +device = 2 + +q = queue.Queue() + + +def q_callback(indata, frames, time, status): + if status: + print(status, file=sys.stderr) + q.put(bytes(indata)) + + +def va_listen(callback): + with sd.RawInputStream(samplerate=samplerate, blocksize=8000, device=device, dtype='int16', + channels=1, callback=q_callback): + + rec = vosk.KaldiRecognizer(model, samplerate) + while True: + bench.start() + data = q.get() + if rec.AcceptWaveform(data): + callback(json.loads(rec.Result())["text"]) + end_time = bench.end() + print(f"[grey37]This took[/] [red]{end_time[1]}[/]") + #else: + # print(rec.PartialResult()) + +# начать прослушивание команд +va_listen(va_respond) \ No newline at end of file diff --git a/tts.py b/tts.py new file mode 100644 index 0000000..a48b47e --- /dev/null +++ b/tts.py @@ -0,0 +1,35 @@ +import torch +import sounddevice as sd +import time + +language = 'ru' +model_id = 'ru_v3' +sample_rate = 48000 # 48000 +speaker = 'aidar' # aidar, baya, kseniya, xenia, random +put_accent = True +put_yo = True +device = torch.device('cpu') # cpu или gpu +text = "Хауди Хо, друзья!!!" + +model, _ = torch.hub.load(repo_or_dir='snakers4/silero-models', + model='silero_tts', + language=language, + speaker=model_id) +model.to(device) + + +# воспроизводим +def va_speak(what: str): + audio = model.apply_tts(text=what+"..", + speaker=speaker, + sample_rate=sample_rate, + put_accent=put_accent, + put_yo=put_yo) + + sd.play(audio, sample_rate * 1.05) + time.sleep((len(audio) / sample_rate) + 0.5) + sd.stop() + +# sd.play(audio, sample_rate) +# time.sleep(len(audio) / sample_rate) +# sd.stop() \ No newline at end of file diff --git a/utils/benchmark.py b/utils/benchmark.py new file mode 100644 index 0000000..008ab36 --- /dev/null +++ b/utils/benchmark.py @@ -0,0 +1,27 @@ +import time + + +class Benchmark: + __marks = {} # {0: [result, point1, point2, ...]} + + def start(self, point_name=None) -> float: + if point_name is None: + point_name = 0 + + self.__marks[point_name] = [0, ((time.time_ns() / 1000000) / 1000)%60, 0] + # print(f"start: {self.__marks}") + + return self.__marks[point_name] + + def end(self, point_name=None) -> tuple: + if point_name is None: + point_name = 0 + + # print(self.__marks) + self.__marks[point_name][2] = ((time.time_ns() / 1000000) / 1000)%60 + self.__marks[point_name][0] = self.__marks[point_name][2] - self.__marks[point_name][1] + + return self.__marks[point_name][0], f"{int(1E3 * self.__marks[point_name][0])}ms" + + def clear_points(self): + self.__marks = {} diff --git a/utils/time.py b/utils/time.py new file mode 100644 index 0000000..a93bde0 --- /dev/null +++ b/utils/time.py @@ -0,0 +1,15 @@ +import time + + +def sleep(duration, get_now=time.perf_counter): + """ + Custom sleep function that works more accurate then time.sleep does. + Taken from: https://stackoverflow.com/a/60185893/3684575 + :param duration: Duration to sleep (in seconds). + :param get_now: Function to retrieve current time (time.perf_counter by default) + :return: + """ + now = get_now() + end = now + duration + while now < end: + now = get_now()