Как стать автором
Обновить

Распознавание речи на STM32F4-Discovery

Время на прочтение4 мин
Количество просмотров116K
image
В этой статье я хочу рассказать о том, как можно распознавать речь на микроконтроллере, используя отладочную плату STM32F4-Discovery. Поскольку распознавание речи — достаточно сложная задача даже для компьютера, то в данном случае оно проводится при помощи сервиса Google. Распознавание речи таким способом может пригодится в разных задачах, например в одном из устройств «умного дома».

Отладочная плата STM32F4-Discovery заметно отличается от нередко упоминаемой в статьях отладочной платы STM32-Discovery. На ней установлен микроконтроллер STM32F407VGT6, использующий архитектуру Cortex-M4F, имеющий 1 MB Flash и 192 KB RAM. Контроллер способен работать с тактовой частотой 168 МГц.

На отладочной плате установлен аудио-ЦАП со встроенным усилителем (его выход соединен с разъемом для наушников) и цифровой MEMS-микрофон, благодаря чему на базе STM32F4-Discovery можно легко изготовить устройство, работающее со звуком.

Распознавание речи с использованием Google Voice Search описано здесь: Статья.
Для того, чтобы распознать какую-либо сказанную фразу с использованием микроконтроллера, нужно выполнить ряд действий:

Записать звук в память контроллера.
Произвести кодирование звука.
Установить соединение с сервером Google.
Отправить на сервер POST-запрос и закодированные аудиоданные.
Принять ответ от сервера.

Запись голоса
Поскольку на плате уже есть цифровой микрофон, записывать звук будем с его помощью. В данном случае это PDM-микрофон. Он имеет только два сигнальных вывода — тактирование и данные. При наличии сигнала тактирования, на выходе данных микрофона появляется сигнал, закодированный при помощи PDM модуляции (подробнее о ней рассказано в Википедии: Pulse-density modulation). На STM32F4-Discovery микрофон соединен с SPI/I2S — для приема данных с микрофона достаточно сконфигурировать I2S на прием данных, и по прерыванию от I2S считывать из регистра полученные данные. Эти данные сохраняются в память контроллера, и после того, как будет записано достаточное количество данных, производится их фильтрация, результатом которой являются несколько семплов аудиоданных.
Работа с микрофоном описана в документе AN3998 от ST — там объясняется принцип действия микрофона, особенности его подключения и описывается работа с функцией фильтрации.

На сайте ST среди различных примеров для платы есть пример работы со звуком, вот только он достаточно навороченный — в примере показано, как воспроизводить звук из памяти контролера и с подключенной к плате USB-флешки. Так же демонстрируется запись звука на флешку. Код для воспроизведения и записи звука я брал именно оттуда. Вот только в этом коде оказалось немало ошибок и недоделок — вероятно, пример писали в спешке.

Кодирование записанного звука
Описания работы с сервисом распознавания речи уже не раз приводились в интернете. Во всех случаях авторы используют аудиокодек FLAC, так как в Google используют нестандартное кодирование Speex данных.
Это видно из кода браузера Chromium: Код, отвечающий за запись звука.
В описании POST запроса указывается, что тип данных — «audio/x-speex-with-header-byte».
Вот только на STM32 не удастся закодировать данные в формат FLAC — нет таких библиотек. А вот код Speex портирован на STM32, поэтому для кодирования я использовал именно этот кодек. Из кода Chromium довольно легко понять, в чем заключается модификация кодека — перед началом каждого фрейма закодированных аудиоданных вставляется дополнительный байт, равный длине фрейма в байтах.

Запись и кодирование звука идут одновременно — с использованием двойной буферизации: в то время, пока в один из буферов записываются 160 семплов аудиоданных, данные из другого буфера кодируются в формат Speex. Закодированные данные сохраняются в памяти контроллера. Запись идет в течении 2 секунд, в результате чего формируются 2100 байт закодированных аудиоданных. Частота дискретизации — 8 кГц.

Связь с сервером Google
image
Для соединения с интернетом используется отладочная плата с WIFI модулем — RN-XV. На ней установлен WIFI-модуль RN-171 (снизу платы), антенна, 3 сетодиода и штыревые разъемы. Связь с модулем идет через UART, так что для работы с ним достаточно 4 проводов. Стоимость платы в sparkfun, откуда я его заказывал — 35$. Сам WIFI — модуль стоит 30$. Подробнее о модуле можно прочитать на сайте sparkfun: RN-XV WiFly Module.

Для того того, чтобы передать данные на сервер, нужно подключится к нему по протоколу TCP, а затем передать запрос такого вида:

POST http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU HTTP/1.1@#Content-type: audio/x-speex-with-header-byte; rate=8000@#Connection: close@#Content-length: 2100@#@#

Символы @# программа заменяет на CRLF. После передачи запроса нужно отправить на сервер 2100 байт закодированных аудиоданных. Получив все данные, сервер производит распознавание речи, и передает распознанную строку вместе с дополнительной информацией, после чего соединение с сервером закрывается.

После того, как ответ сервера принят, программа выделяет из него распознанную строку и выводит ее через другой UART микроконтроллера. Данные из этого UART передаются на компьютер в терминал, в окне которого и появляется распознанная фраза. После этого контролер готов в запуску записи новой фразы.

Получившаяся конструкция выглядит так:
image

А вот как она работает:


Обновление:

Уже после того, как я выложил статью, я смог реализовать запуск записи при появлении громкого звука (в том числе и речи). Для этого программа постоянно ведет запись и кодирование звука. Закодированные данные помещаются в массив. После достижения его конца, данные начинают помещаться в его начало. В то же время программа постоянно проверяет, не появился ли громкий звук. При его появлении программа сохраняет значение указателя записи и ведет запись в течение 2 секунд. После остановки записи, программа копирует данные в другой буфер. Так как известно, в какой момент появился звук, можно брать данные незадолго до этого. Таким образом, первые звуки слова не теряются.

Видео работы VAD:


Программа написана в IAR.
Программа позволяет воспроизводить записанную фразу, перед тем как отправить ее на сервер. Для этого достаточно раскомментировать некоторые строки в функции main.

В приложенном архиве несколько проектов:
my_audio_test — записывает и сразу же воспроизводит звук с микрофона.
speex_out — воспроизводит звук в формате Speex, хранящийся в Flash памяти контроллера.
speex_rec — записывает и кодирует звук при помощи Speex в течение 2 секунд, после чего воспроизводит запись.
speech_wifi — сам проект распознавания речи, в этом проекте используется WIFI.
speech_wifi_vad — проект распознавания речи с VAD, в этом проекте используется WIFI.

www.dropbox.com/s/xke5rq8lzi980x5/NEW_VOICE.zip?dl=0
Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
Всего голосов 39: ↑33 и ↓6+27
Комментарии88

Публикации

Истории

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань