В современном мире технологии распознавания речи используются очень широко. Например, они нашли применение в системах управления умным домом, в устройствах IoT, при управлении различным оборудованием, роботехническими игрушками и конечно, в обучающих проектах. Наличие в микрокомпьютере порта GPIO позволяет управлять физическими устройствами голосом.
В этой статье рассказано о том, как настроить локальное (автономно работающее) распознавание речи в реальном времени на микрокомпьютере отечественного Российского производства Repka-Pi 4 Optimal, на борту у которого есть всего 2 Гбайт оперативной памяти. Вскоре ожидается появление Repka Pi 4 Pro с большим количеством оперативной памяти, а так же старшей модели Repka Pi 5 и там будет до 32 Гб ОЗУ. Но пока работаем с тем, что уже есть на рынке на февраль 2026 года, да и зачем больше и дороже, если может работать и решать требуемые задачи на имеющемся. Больше памяти нужно если есть необходимость использовать более сложные модели нейронных сетей, это уже отдельный пласт задач, но подход будет тот же самый.
Пара видео с Рутуба, чтобы сразу посмотреть как это выглядит. Краткий вариант в виде "истории" или "шортса" - ссылка раз, и вариант поподробнее с полноценным видео - ссылка два. Хотелось поставить сразу медиаэлемент с плеером, но что то он работает криво, как оказалось.
При ограниченных ресурсах приходится использовать модели небольшого объема. В этой статье показано применение модели Vosk на базе Kaldi с поддержкой русского языка vosk-model-small-ru-0.22. Она «весит» всего 45 Мбайт, что позволяет использовать её на микрокомпьютерах с небольшим объёмом памяти. Конечно, для получения высокого качества распознавания речи лучше использовать модели покрупнее. На момент написания статьи для Vosk это модель vosk-model-ru-0.42 объёмом 1.8 Гбайт. Она предназначена для серверов, но возможно будет удовлетворительно работать и на микрокомпьютере Repka-Pi 5 с большим объёмом оперативной памяти, который, как уже было сказано, на момент написания статьи готовится к производству. Версии моделей Vosk постоянно обновляются. Вы можете отслеживать их на странице моделей.
В статье показано, как настраивать работу с микрофоном, приведёны и разобраны исходники программы распознавания голосовых команд, изменяющих состояние одного из пинов интерфейса GPIO микрокомпьютера. Вы можете подключить к этому пину, например, реле для управления светильником. По команде «лампа» этот светильник будет зажигаться, а по команде «погасить» — выключаться. Разумеется, эти команды можно изменить или добавить новые.
Важно, что для распознавания команд не нужно проводить никакого обучения — заранее обученная нейросеть распознает команды, произнесённые любым разборчивым голосом.

Для удобства навигации по статье вот её содержание со ссылками:
Установка Repka OS
Скачайте прошивку Repka OS на сайте Repka-Pi и запишите её на карту SD, например, с помощью программы balenaEtcher. Перед включением питания Repka-Pi 4 вставьте карту в соответствующий разъём микрокомпьютера и загрузите Repka OS.
Подключитесь к Repka-Pi как пользователь root и обновите пакеты следующей командой:
sudo apt update
Внимание! Не запускайте после обновления команду apt upgrade!
Для обновления Repka OS используйте программу repka-config (рис. 1).

Выполните установку необходимых программ и библиотек:
apt install -y alsa-utils python3 python3-pip g++ portaudio19-dev libasound2-dev
Теперь можно переходить к работе с микрофоном.
Проверка и настройка микрофона
Качество распознавания речи очень сильно зависит от микрофона и его настроек. Я использовал микрофон, встроенный в Web-камеру Logitech, подключенную к разъёму USB микрокомпьютера Repka-Pi (рис. 2).

Поиск микрофона
Прежде всего найдите микрофон и посмотрите его настройки. Для поиска микрофона используйте такую команду:
root@Repka-Pi:~# arecord -l **** Список CAPTURE устройств **** карта 0: ac200audio [ac200-audio], устройство 0: 508f000.i2s-ac200-dai ac200-dai-0 [508f000.i2s-ac200-dai ac200-dai-0] Подустройства: 1/1 Подустройство №0: subdevice #0 карта 2: U0x46d0x825 [USB Device 0x46d:0x825], устройство 0: USB Audio [USB Audio] Подустройства: 0/1 Подустройство №0: subdevice #0
Микрофон, подключенный к USB, был обнаружен на карте 2, устройство 0.
Тестирование обнаруженного микрофона
Чтобы проверить найденный микрофон, запустите команду arecord и скажите что-нибудь в микрофон:
arecord -D plughw:2,0 -f S16_LE -r 16000 -c 1 test.wav
Команда выведет на консоль параметры записываемого звукового файла:
Запись WAVE 'test.wav' : Signed 16 bit Little Endian, Частота 16000 Гц, Моно
Для распознавания речи нам потребуется монофонический поток звуковых данных с частотой дискретизации 16000 Гц. Именно такой звуковой файл и будет записан приведённой выше командой.
Параметр -D plughw:2,0 задаёт адрес нашего микрофона — карта 2, устройство 0. Формат данных указывается параметром -f, частота дискретизации параметром -r, а длительность записи в секундах — параметром -c.
После завершения записи прослушайте результат командой aplay:
aplay test.wav
Вы должны услышать четкую и громкую запись.
Настройка уровней записи и воспроизведения
Если качество записи с микрофона невысокое, запустите программу alsamixer для настройки уровней записи и воспроизведения.
По умолчанию откроется управление встроенным аудиовыходом HDMI (рис. 3).

Нажмите клавишу F6 и выберите ваше устройство. Я выбрал микрофон, подключенный к USB (рис. 4).

После выбора микрофона нажмите клавишу F4, чтобы перейти в режим регулировки усиления (рис. 5).

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

Итак, если микрофон работает хорошо, можно переходить к запуску программы распознавания речи.
Программы распознавания речи на Python
Далее я расскажу о двух программах, первая из которых с названием recognizer.py распознаёт речь в сигнале от микрофона в реальном времени и выводит результаты распознавания на консоль. Вторая программа recognizer-gpio.py управляет голосовыми командами состоянием одного из контактов интерфейса GPIO.
Скачайте программу распознавания речи в реальном времени recognizer.py из репозитория Github и запустите её в консоли на Repka-Pi 4:
# python3 recognizer.py
Программа автоматически определит микрофон, подключенный к разъёму USB микрокомпьютера, и выведет приглашение «Говорите» на экран:
LOG (VoskAPI:ReadDataFiles():model.cc:213) Decoding params beam=10 max-active=3000 lattice-beam=2\ LOG (VoskAPI:ReadDataFiles():model.cc:216) Silence phones 1:2:3:4:5:6:7:8:9:10 LOG (VoskAPI:RemoveOrphanNodes():nnet-nnet.cc:948) Removed 0 orphan nodes. LOG (VoskAPI:RemoveOrphanComponents():nnet-nnet.cc:847) Removing 0 orphan components. LOG (VoskAPI:ReadDataFiles():model.cc:248) Loading i-vector extractor from model/ivector/final.ie LOG (VoskAPI:ComputeDerivedVars():ivector-extractor.cc:183) Computing derived variables for iVector extractor LOG (VoskAPI:ComputeDerivedVars():ivector-extractor.cc:204) Done. LOG (VoskAPI:ReadDataFiles():model.cc:282) Loading HCL and G from model/graph/HCLr.fst model/graph/Gr.fst LOG (VoskAPI:ReadDataFiles():model.cc:308) Loading winfo model/graph/phones/word_boundary.int Найдено устройство: USB Device 0x46d:0x825: Audio (hw:2,0) (ID: 2) ------------------------------ Микрофон готов. Говорите...\
Говорите в микрофон с такого расстояния и с такой громкостью как при проведении тестов. Если все сделано правильно, на консоли будут появляться результаты распознавания произнесённых вами слов (рис. 7).

В целом качество распознавания на такой маленькой модели можно оценить как неплохое.
Исходной код программы recognizer.py
Расскажу о том, как устроена программа recognizer.py, способная распознавать речь в реальном времени.
В самом начале исходного кода среди прочих импортируются такие библиотеки:
import sounddevice as sd from vosk import Model, KaldiRecognizer
Библиотека sounddevice нужна для работы с потоком аудио в программах Python. Она может опрашивать список подключенных устройств, выбирать нужное и открывать поток для захвата аудиоданных в режиме реального времени.
Библиотека vosk представляет собой движок распознавания речи, основанный на инструментарии Kaldi.
Из библиотеки vosk импортируется класс Model, содержащий данные о языке, такие как звуки, слова и грамматика. Класс KaldiRecognizer сопоставляет сырые данные от sounddevice с данными из Model, превращая звуки речи в текст.
Получив управление, программа прежде всего проверяет наличие каталога, в который загружена модель:
MODEL_PATH = "model" if not os.path.exists(MODEL_PATH): print(f"Ошибка: Папка '{MODEL_PATH}' не найдена.") exit(1)
Если каталог с файлами модели на месте, программа инициализирует модель. Прежде всего, модель загружается в оперативную память:
model = Model(MODEL_PATH)
Далее создаётся объект «движка» для распознавания речи:
SAMPLE_RATE = 16000 rec = KaldiRecognizer(model, SAMPLE_RATE)
Параметр SAMPLE_RATE задаёт частоту дискретизации, равную 16000 Гц.
Далее программа вызывает функцию find_usb_microphone, задачей которой является получение идентификатора устройства микрофона, подключенного к USB:
device_id = find_usb_microphone() if device_id is None: print("USB-микрофон не найден.") exit(1)
Функция поиска микрофона получает список всех устройств с помощью d.query_devices, и если в названии устройства есть слово «USB» и это устройство ввода, то она возвращает идентификатор найденного микрофона:
def find_usb_microphone(): devices = sd.query_devices() for i, dev in enumerate(devices): if 'USB' in dev['name'] and dev['max_input_channels'] > 0: print(f" Найдено устройство: {dev['name']} (ID: {i})") return i return None
Такой подход позволяет обнаруживать микрофон, даже если его идентификатор изменился после перезапуска ОС или после переподключения микрофона.
Если микрофон найден, на консоль выводится приглашение:
print("-" 30) print("Микрофон готов. Говорите...") print("-" 30)
На следующем этапе запускается основной цикл программы.
Вначале создаётся поток для передачи «сырых» данных из микрофона в программу. Параметр callback со значением callback задаёт функцию, образующую из этих данных очередь:
with sd.RawInputStream(samplerate=SAMPLE_RATE, blocksize=8000, device=device_id, dtype='int', channels=1, callback=callback):
В главном цикле программа с помощью функции audio_queue.get дожидается получения данных из очереди:
while True: data = audio_queue.get()
Функция rec.AcceptWaveform анализирует порцию звука, отправляет эту порцию в нейросеть и возвращает значение True, если в речи пользователя появилась пауза:
if rec.AcceptWaveform(data): result = json.loads(rec.Result()) text = result.get("text", "") if text: sys.stdout.write(f"Результат: {text}\n") sys.stdout.flush() else: partial = json.loads(rec.PartialResult()) partial_text = partial.get("partial", "") if partial_text: sys.stdout.flush()
В этом случае функция result.get возвращает строку с распознанным текстом, который отображается на консоли.
Когда паузы ещё нет, программа получает черновик распознавания функцией rec.PartialResult и тоже выводит её на консоль.
Программа голосового управления GPIO
Для демонстрации возможности голосового управления оборудованием при помощи распознавания речи на микрокомпьютере Repka-Pi я подготовил программу recognizer-gpio.py. Она представляет собой изменённый вариант рассмотренной выше программы recognizer.py.
Программа recognizer-gpio.py анализирует распознанный текст и ищет в нём слова команд «лампа» и «погасить». Первая из этих команд устанавливает состояние 1 на физическом контакте 7 порта GPIO (GPIO04), а вторая — сбрасывает его в 0.
Сразу после запуска программы, а также после получения команды «погасить» на выходе контакта 7 устанавливается нулевое напряжение. Подключенный к этому контакту светодиод не горит (рис. 8).

После получения команды «лампа» на контакте 7 устанавливается напряжение 3.3 В и светодиод загорается (рис. 9).

Подключив к этому контакту реле, можно управлять реальным светильником. На рис. 10 показано управление светодиодом через реле.

Выводы реле DC+ и DC- подключены, соответственно, к +5 В (физический контакт 2 микрокомпьютера Repka Pi) и к земле (физический контакт 6).
Сигнал управления подается на контакт IN4 реле (четвертое реле из блока) с физического контакта 7 микрокомпьютера.
Нормально разомкнутые контакты ТС4 и COM4 четвёртого реле подключены к светодиоду и источнику питания 5 В через резистор 1 КОм.
Разумеется, вы можете подключить к реле более серьёзную нагрузку, чем светодиод. В интернете есть даташит на реле, установленные в этом блоке. Там вы найдёте предельные значения напряжения и тока, которые может коммутировать такое реле.
В процессе распознавания и выполнения команд программа recognizer-gpio.py выводит сообщения о своих действиях на консоль (рис. 11).

Теперь я расскажу, чем программа recognizer-gpio.py отличается от recognizer.py. Главное отличие заключается в добавлении кода управления портом GPIO и кодом обнаружения команд в распознанном тексте.
Для управления состоянием пинов порта GPIO используется модуль RepkaPi.GPIO:
import RepkaPi.GPIO as GPIO
Этот модуль описан в статье «Первые шаги: Моргаем светодиодом на python с помощью библиотеки RepkaPi.GPIO SysFS».
Я использовал для наглядности физическую нумерацию контактов GPIO на плате микрокомпьютера. Здесь я задал для управления контакт с номером 7:
LED_PIN = 7
Далее программа выполняет инициализацию и выключает напряжение на контакте 7:
GPIO.setmode(GPIO.BOARD) GPIO.setup(LED_PIN, GPIO.OUT) GPIO.output(LED_PIN, GPIO.LOW)
После запуска программа выводит на консоль команды управления нашим контактом:
print("-" 30) print("Система готова.") print("Команды: 'лампа' - включить, 'погасить' - выключить.") print("-" 30)
Логика управления при помощи команд реализована в главном цикле программы:
while True: data = audio_queue.get() if rec.AcceptWaveform(data): result_json = json.loads(rec.Result()) text = result_json.get("text", "").lower() if text: print(f"Результат: {text}") if "лампа" in text: print(">>> Исполняю: ВКЛЮЧИТЬ СВЕТ") GPIO.output(LED_PIN, GPIO.HIGH) elif "погасить" in text: print(">>> Исполняю: ВЫКЛЮЧИТЬ СВЕТ") GPIO.output(LED_PIN, GPIO.LOW) else: # Промежуточный результат (динамическое отображение) partial = json.loads(rec.PartialResult()) partial_text = partial.get("partial", "") if partial_text: sys.stdout.write(f"\r Слушаю: {partial_text}...\033[K") sys.stdout.flush()
В процессе анализа этот код переводит полученный текст в нижний регистр для надёжности. Получив текст, программа выводит его на консоль и смотрит, содержит ли этот текст слова команд «лампа» и «погасить».
Если обнаружено слово «лампа», программа устанавливает на контакте 7 состояние единицы (напряжение 3.3 В):
GPIO.output(LED_PIN, GPIO.HIGH)
При этом зажигается светодиод или лампа, подключенная к контакту 7.
При обнаружении внутри строки распознанного текста слова «погасить» программа устанавливает на контакте 7 состояние нуля (напряжение 0 В):
GPIO.output(LED_PIN, GPIO.LOW)
Перед завершением своей работы программа сбрасывает порт GPIO в начальное состояние:
GPIO.output(LED_PIN, GPIO.LOW) GPIO.cleanup()
Полный исходный текст программы recognizer-gpio.py есть в моём репозитории на Github.
Программа распознавания речи на C++
Учитывая, что многие программы для встраиваемых систем разрабатывают на C++, я подготовил для Repka-Pi 4 программу распознавания речи на языке C++. Далее я приведу описание программы, а также расскажу о том, как её собрать и запустить.
Описание программы
В самом начале программы подключаются все необходимые библиотеки:
#include <iostream> #include <vector> #include <string> #include <cstring> #include <portaudio.h> #include "vosk_api.h"
Библиотека iostream нужна для вывода данных в консоль.
С помощью библиотеки vector программа создаёт контейнер для временного хранения фрагментов записанного звука.
Для разбора JSON-ответов нейросети и поиска нужного микрофона в списке устройств программа использует библиотеки string и cstring. А вот общение с микрофоном выполняет библиотека захвата звука portaudio.h.
И, наконец, библиотека vosk_api.h предоставляет доступ к API уже знакомой вам библиотеке Vosk.
Макрос CHECK_PA_ERROR нужен для проверки ошибок PortAudio и корректного завершения работы программы при обнаружении таких ошибок:
#define CHECK_PA_ERROR(err) if(err != paNoError && err != paInputOverflowed) { \ std::cerr << "PortAudio error: " << Pa_GetErrorText(err) << std::endl; \ return -1; \ }
В программе используется функция print_recognized_text, предназначенная для безопасного извлечения текста из JSON строки Vosk:
void print_recognized_text(const char* json_raw) { std::string res = json_raw; std::string key = "\"text\" : \""; size_t startPos = res.find(key); if (startPos != std::string::npos) { startPos += key.length(); size_t endPos = res.find("\"", startPos); if (endPos != std::string::npos) { std::string text = res.substr(startPos, endPos - startPos); if (!text.empty()) { std::cout << "\r>>> РАСПОЗНАНО: " << text << std::endl; } } } }
В самом начале функции main выполняется инициализация vosk и загрузка модели:
int main() { VoskModel model = vosk_model_new("model"); if (!model) { std::cerr << "ОШИБКА: Не удалось загрузить модель из папки 'model'!" << std::endl; return -1; } VoskRecognizer recognizer = vosk_recognizer_new(model, SAMPLE_RATE);
Далее программа сканирует устройства ввода, в названии которых есть слова «USB» или «Audio»:
CHECK_PA_ERROR(Pa_Initialize()); int numDevices = Pa_GetDeviceCount(); int inputDevice = -1; for (int i = 0; i < numDevices; i++) { const PaDeviceInfo* deviceInfo = Pa_GetDeviceInfo(i); if (deviceInfo->maxInputChannels > 0 && (strstr(deviceInfo->name, "USB") || strstr(deviceInfo->name, "Audio"))) { std::cout << "Найдено устройство: " << deviceInfo->name << " (ID: " << i << ")" << std::endl; inputDevice = i; break; } }
Если микрофон найти не удалось, для ввода используется системный вход аудио:
if (inputDevice == -1) { std::cout << "USB микрофон не найден, использую стандартный вход." << std::endl; inputDevice = Pa_GetDefaultInputDevice(); }
На следующем этапе программа задаёт настройки для библиотеки PortAudio:
PaStreamParameters inputParameters; inputParameters.device = inputDevice; inputParameters.channelCount = 1; inputParameters.sampleFormat = paInt16; inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultHighInputLatency; inputParameters.hostApiSpecificStreamInfo = NULL;
Здесь указывается:
идентификатор обнаруженного микрофона inputParameters.device;
монофонический режим inputParameters.channelCount;
разрядность звуковых данных inputParameters.sampleFormat (целые 16-битные числа);
задержку по умолчанию для устройства;
поле специфических настроек inputParameters.hostApiSpecificStreamInfo для конкретных типов ОС
На следующем этапе программа поток с помощью функции Pa_OpenStream выводит на консоль приглашение для начала процесса распознавания речи с микрофона:
PaStream *stream; CHECK_PA_ERROR(Pa_OpenStream(&stream, &inputParameters, NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, NULL, NULL)); CHECK_PA_ERROR(Pa_StartStream(stream)); std::cout << "\n--- СИСТЕМА ГОТОВА. ГОВОРИТЕ... (Ctrl+C для выхода) ---\n" << std::endl;
Ниже я привёл описание параметров функции Pa_OpenStream:
&stream — указатель созданный поток;
&inputParameters — указатель на настройки для библиотеки PortAudio;
NULL — параметры для выхода, не используются;
SAMPLE_RATE — частота дискретизации 16000 Гц;
FRAMES_PER_BUFFER — размер звукового фрагмента (2048 фреймов) для обработки за один раз;
paClipOff — флаг, отключающий автоматическое ограничение амплитуды (клиппинг), чтобы данные поступали в нейросеть «как есть»;
NULL, NULL — параметры, задающие Callback-функции для обработки звука в реальном времени. Наша программа использует метод прямого чтения из буфера, поэтому они не нужны
В буфере buffer находится временное хранилище образцов звука:
std::vector buffer(FRAMES_PER_BUFFER);
Далее программа запускает основной цикл обработки:
while (true) { PaError err = Pa_ReadStream(stream, buffer.data(), FRAMES_PER_BUFFER); if (err != paNoError && err != paInputOverflowed) { std::cerr << "Критическая ошибка аудио: " << Pa_GetErrorText(err) << std::endl; break; } int is_final = vosk_recognizer_accept_waveform_s(recognizer, buffer.data(), FRAMES_PER_BUFFER); if (is_final) { print_recognized_text(vosk_recognizer_result(recognizer)); } }
Здесь программа читает аудиоданные функцией Pa_ReadStream и передаёт их в нейросеть, вызывая функцию vosk_recognizer_accept_waveform_s.
Если эта функция определила конец фразы (по паузе), данные выводятся на консоль функцией print_recognized_text.
Если пользователь прерывает выполнение программы, нажав комбинацию клавиш Ctrl+C, программа выполняет очистку и завершает свою работу:
Pa_StopStream(stream); Pa_CloseStream(stream); Pa_Terminate(); vosk_recognizer_free(recognizer); vosk_model_free(model); return 0;
В этом фрагменте кода функция Pa_StopStream прекращает захват звука, функция Pa_CloseStream удаляет объект потока и очищает буферы драйвера, а функция Pa_Terminate полностью выгружает библиотеку PortAudio из памяти.
Освобождение ресурсов vosk выполняют функции vosk_recognizer_free и vosk_model_free. Первая из них удаляет экземпляр распознавателя, а вторая — выгружает нейросетевую модель из оперативной памяти.
Сборка и запуск программы
Перед сборкой установите необходимые зависимости:
apt install -y g++ portaudio19-dev libasound2-dev
Создайте каталог asr-cpp для сборки программы и сделайте его текущим:
mkdir asr-cpp cd asr-cpp
Загрузите и распакуйте библиотеку vosk-linux-aarch64-0.3.45.zip:
wget https://github.com/alphacep/vosk-api/releases/download/v0.3.45/vosk-linux-aarch64-0.3.45.zip unzip vosk-linux-aarch64-0.3.45.zip
Перенесите результаты распаковки в каталог libvosk и запустите сборку программы:
mv vosk-linux-aarch64-0.3.45 libvosk g++ main.cpp -I./libvosk -L./libvosk -lvosk -lportaudio -o speech_rec
Запуск программы выполните с помощью следующих команд:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/libvosk ./speech_rec
После запуска на консоли появится множество сообщений об ошибках от ALSA, которые вы можете игнорировать:
root@Repka-Pi:~/asr-cpp# ./speech_rec LOG (VoskAPI:ReadDataFiles():model.cc:213) Decoding params beam=10 max-active=3000 lattice-beam=2 LOG (VoskAPI:ReadDataFiles():model.cc:216) Silence phones 1:2:3:4:5:6:7:8:9:10 LOG (VoskAPI:RemoveOrphanNodes():nnet-nnet.cc:948) Removed 0 orphan nodes. LOG (VoskAPI:RemoveOrphanComponents():nnet-nnet.cc:847) Removing 0 orphan components. LOG (VoskAPI:ReadDataFiles():model.cc:248) Loading i-vector extractor from model/ivector/final.ie LOG (VoskAPI:ComputeDerivedVars():ivector-extractor.cc:183) Computing derived variables for iVector extractor LOG (VoskAPI:ComputeDerivedVars():ivector-extractor.cc:204) Done. LOG (VoskAPI:ReadDataFiles():model.cc:282) Loading HCL and G from model/graph/HCLr.fst model/graph/Gr.fst LOG (VoskAPI:ReadDataFiles():model.cc:308) Loading winfo model/graph/phones/word_boundary.int ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.1.pcm.front.0:CARD=1' ALSA lib conf.c:5178:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5701:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM front ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.1.pcm.surround51.0:CARD=1' ALSA lib conf.c:5178:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5701:(snd_config_expand) Evaluate error: No such file or directory snd_func_refer returned error: No such file or directory
Эти сообщения возникают в процессе опроса устройств с целью поиска микрофона. Не все эти устройства существуют, отсюда и ошибки.
Когда микрофон будет обнаружен, на экране появится приглашение и результаты распознавания текста:
Найдено устройство: USB Device 0x46d:0x825: Audio (hw:2,0) (ID: 2) --- СИСТЕМА ГОТОВА. ГОВОРИТЕ... (Ctrl+C для выхода) --- >>> РАСПОЗНАНО: раз два три четыре пять >>> РАСПОЗНАНО: вышел зайчик погулять >>> РАСПОЗНАНО: ехали медведи на велосипеде
Подведем итоги
Микрокомпьютер Repka Pi 4 вполне пригоден для распознавания речи. Причём не только как агент, передающий звук от микрофона на сервер с GPU, но и для локального распознавания в реальном времени. Из-за небольшого объёма оперативной памяти, установленной на Repka Pi 4, приходится использовать самую маленькую модель Vosk. Но и такая модель показала хорошие результаты для русского языка. Можно предположить, что следующая модель Repka-Pi 5, которая уже готовится к производству, позволит использовать большие модели. Это обеспечит более качественное распознавание.
Используя Repka-Pi 4 и Vosk, уже сейчас можно создавать локальные системы голосового управления различными устройствами, подключенными к порту GPIO микрокомпьютера.
Используя реле и оборудование, подключенное через контакты GPIO, через I2C и UART можно выдавать команды на самое разнообразное оборудование. Например, можно организовать голосовое управление умным домом, станками и тому подобными устройствами.
Следует также заметить, что качество распознавания в большой степени зависит от микрофона. Сейчас в продаже есть активные микрофоны, оборудованные системами автоматической регулировкой усиления, настраиваемыми фильтрами и эквалайзерами, позволяющими оптимизировать звук для распознавания.
Если Вам нравятся подобные эксперименты с распознаванием речи на Repka-Pi 4, пишите в отзывах, о чём вам было бы ещё интересно узнать по этой теме.
Авторы материала @AlexandreFrolov и @RyabovA
