Голосовой коммуникатор на базе микроконтроллера Nuvoton M451LG6
Важнейшим элементом современной промышленной и бытовой автоматики являются системы диспетчеризации, обеспечивающие взаимодействие пользователя не только с автоматизированными центрами управления и контроля, но и непосредственно c человеком — представителем поставщика услуг. Это особенно важно в экстремальных ситуациях, когда предпочтительнее человеческое общение, предоставляющее возможность оперативно согласовывать нестандартные решения, не предусмотренные алгоритмами штатного функционирования компьютерных систем. Основой коммуникации между людьми выступает речь, позволяющая им наиболее эффективно обмениваться информацией. Голосовая телефония сегодня считается одним из наиболее распространенных видов связи и не собирается уступать свои позиции, несмотря на широкое развитие альтернативных способов обмена информацией.
Передача голоса по цифровым линиям связи требует от последних достаточной полосы пропускания, определяющей такие важные характеристики голосового канала, как разборчивость и сохранение индивидуальных речевых характеристик. Существует множество алгоритмов цифровой обработки речи, подавляющее большинство из них основано на использовании статистических особенностей человеческого голоса. Некоторые кодеки могут сжимать речь, достигая скорости передачи данных 300 бит/с. Платой за высокую степень сжатия становится снижение качества речи, обычно проявляющееся сначала в потере индивидуальных характеристик, а затем и в некоторой потере разборчивости. Так, алгоритм MELPE, применяемый в системах связи военного назначения, позволяет генерировать поток 600–2400 бит/с, сохраняя хорошую разборчивость, но речь принимает характерный «английский оттенок» из-за перетренированности используемых кодовых таблиц. Лучшим и, наверное, самым популярным в системах связи общего назначения является алгоритм AMR-NB (Adaptive Multi-Rate Narrow Band), разработанный ETSI (European Telecommunica-tions Standards Institute) в 1999 году [2]. В зависимости от настроек AMR работает на скоростях 4,75; 5,15; 5,9; 6,7; 7,4; 7,95; 10,2 или 12,2 кбит/с, сохраняя высокую разборчивость и индивидуальные оттенки голоса. Кодек использует дискретизацию аудиосигнала 13 бит с частотой 8000 Гц и сжимает аудиофрейм из 160 отсчетов (20 мс голоса) в блок размером 12–31 байт, в зависимости от выбранного режима работы. Допускается смена режима «на лету», позволяющая динамически адаптировать алгоритм к текущим характеристикам канала передачи данных. Кодек AMR также имеет встроенный детектор голоса (Voice active detector, VAD), позволяющий обнаруживать речевые паузы и не включать их в поток передаваемых данных, в результате чего снижается общая нагрузка на действующий канал связи. Кодек AMR базируется на алгоритме MR-ACELP (Multi-Rate Algebraic Code Excited Linear Prediction) — алгебраическом линейном предсказании с несколькими скоростями [3]. Такая реализация требует не менее 20 MIPS быстродействия и 4 кбайт оперативной память при идеальной оптимизации под платформу, в реальных условиях требования обычно в несколько раз выше.
До недавнего времени цифровая обработка сигнала (Digital Signal processing, DSP) выполнялась исключительно на DSP-процессорах с набором соответствующих аппаратных средств и предусматривала специфические подходы к созданию кода, доступные только узкому кругу программистов, специализирующихся в данной отрасли. Но с появлением недорогих мощных процессоров широкого назначения ситуация радикально изменилась. Современные процессоры имеют систему команд, расширенную так называемыми DSP-инструкциями, и поддерживают аппаратные операции с числами с плавающей точностью. Сегодня реализация DSP-алгоритмов вполне возможна на ARM-ядрах, начиная с Cortex-M4, при использовании исходных кодов на языке С и минимальной адаптации к платформе, а современные стандартные компиляторы обеспечивают хорошую оптимизацию по скорости.
В качестве примера рассмотрим решение на базе бюджетного микроконтроллера Nuvoton M451LG6AE стоимостью всего около $2,5, в режиме реального времени обеспечивающее дуплексную передачу речевого аудиосигнала, сжатого до 4750 бит/с, через последовательный порт с возможностью горячего подключения, компенсацией неравномерности транспортных задержек и неточности частот дискретизации. Встроенный голосовой детектор останавливает передачу во время речевых пауз. Поток данных фрагментируется на пакеты по 12 байт, следующие с периодом 20 мс, и может передаваться по любым каналам связи с достаточной пропускной способностью, например через Ethernet или GPRS, c использованием соответствующих транспортных модулей, подключаемых по интерфейсу UART.
Серия Nuvoton M451 Base представлена микроконтроллерами на базе ядра Cortex-M4F, работающими на частоте 72 МГц [4]. Периферию (рис. 1) составляют четыре 32‑битных таймера, модули PDMA и RTC, пять UART с 16‑байтовыми буферами FIFO, три контроллера SPI с поддержкой 4‑битного режима для работы со скоростными SD-картами, два контроллера I2C с поддержкой протоколов SMBus и PMBus, два контроллера I2S, два модуля LIN, модули CAN-шины, интерфейсов ISO‑7816-3, полноскоростного USB OTG и USB-DEVICE, интерфейс EBI для расширения оперативной памяти, 16‑канальный 12‑разрядный ADC со скоростью преобразования до 1 MSPS со встроенным модулем формирования опорного напряжения (VREF), 12‑разрядный DAC, два аналоговых компаратора и датчик температуры. Особенностью серии является наличие модуля PWM с разрешением до 144 МГц. В сочетании с 4‑канальным драйвером PWM обеспечивает аппаратную защиту от торможения и функции захвата импульсов для экономии вычислительной нагрузки процессора при управлении двигателем. Также следует отметить функцию VAI (Voltage Adjustment Interface), позволяющую использовать уровни логических сигналов на выводах 1,8–5,5 В для экономии дополнительных затрат на согласование напряжений интерфейса периферийных компонентов.
Используемый в проекте микроконтроллер Nuvoton M451LG6AE имеет постоянную память 256 кбайт, оперативную память 32 кбайт и выполнен в корпусе LQFP48 [5, 6]. Из многочисленной периферии в проекте были задействованы модули 12‑битного аналого-цифрового и цифро-аналогового преобразователей (ADC и DAC), модуль UART, таймеры и контроллер DMA для обеспечения записи и проигрывания аудио.
Следует заметить, что хорошей альтернативой ADC и DAC служит применение I2S-интерфейса, также имеющегося в микроконтроллере, совместно с внешним аудио-кодеком, например Nuvoton NAU8810. Такой аудиокодек содержит микрофонный усилитель с автоматической регулировкой усиления и выходной усилитель мощностью 1 Вт [7].
Для удобства разработки производитель предоставляет отладочную плату NuTiny-EVB-M451 со встроенным программатором Nu-Link (рис. 2).
В качестве альтернативы можно собрать минимальную конфигурацию самостоятельно, существенно снизив бюджет проекта. Так, в нашем проекте микроконтроллер был запаян на стандартную плату-переходник QFN48, а необходимая обвязка включала лишь кварцевый резонатор 12 МГц и блокировочный конденсатор 1 мкФ (рис. 3).
Разработка велась в среде Keil μVision IDE. Компания Nuvoton обеспечивает программную поддержку своей продукции, предоставляя установочный пакет для Keil Nuvoton, NuMicro_DFP [8] и программный пакет M451 Series_BSP [9], содержащий CMSIS, HAL и многочисленные примеры работы с периферией. По аналогии с STM32CubeMX (продуктом от STMicroelectronics) производитель предлагает графические утилиты NuTool-PinConfig (рис. 4) и NuTool-ClockConfig (рис. 5), позволяющие быстро настроить используемую периферию и выбрать нужные режимы ее тактирования. Следует заметить, что в отличие от STM32CubeMX, сразу создающего пустой проект, указанные утилиты генерируют фрагменты С‑кода, подключаемые в ваш проект вручную.
Заливка программы в микроконтроллер и полнофункциональная аппаратная отладка осуществлялись с помощью подключенного по SWD-интерфейсу бюджетного клона программатора ST-Link v2 непосредственно из среды разработки Keil µVision IDE. Для этого в меню Options > Debug был указан ST-Link Debbugger и в подменю Settings > Flash Download был выбран драйвер M451 256kB Flash AP, предоставляемый в пакете поддержки Nuvoton, а также скорректирован размер оперативной памяти, резервируемый для размещения драйвера: RAM for Algorithm = 0x1000.
Для реализации кодека использовался референс-код алгоритма AMR на языке С, использующий арифметику с плавающей точкой [10]. В среде Keil был создан новый проект и подключены исходные файлы кодека: sp_enc.c, sp_dec.c, interf_enc.c, interf_dec.c и amr_speech_importance.c. В соответствии с требованиями кодека к объему памяти в файле startup_M451Series.s были установлены значения Stack_Size EQU 0x00002000 и Heap_Size EQU 0x00004000.
Адаптация исходного кода в основном заключалась в замене всех математических функций, по умолчанию использующих числа с плавающей точкой двойной точности, на соответствующие функции одинарной точности (fabsf, sqrtf, sinf, cosf и др.). Также была выполнена замена типов double на float и добавление ко всем десятичным константам модификатора f (0.0f; и т. п.). Такая правка позволила в полной мере реализовать аппаратные ресурсы процессора Cortex M4F, поддерживающего вычисления с плавающей точкой лишь одинарной точности. При выполнении подобной адаптации необходимо особо внимательно вычитывать код, чтобы не пропустить использование любых значений двойной точности, поскольку даже единственное такое значение снизит скорость выполнения кода за счет программной эмуляции подобных вычислений.
Дискретизация аудиосигнала производилась 12‑битным модулем ADC. В качестве триггера, запускающего преобразование, выступал таймер, работающий в режиме TIMER_PERIODIC_MODE на фиксированной частоте 8000 Гц. 12‑битный результат преобразования выдавался в знаковом виде благодаря установке значения DMOF_TWOS_COMPLEMENT. Для сохранения в памяти фрейма из 160 результатов преобразования использовался двойной буфер: пока один фрейм формировался с помощью DMA, второй обрабатывался кодеком. В результате кодирования получали 12‑байтный блок с флагом VAD. Транслировались только голосовые блоки, передача данных во время речевых пауз не производилась. В итоге 12‑байтный блок c помощью DMA выдавался через UART.
Прием 12‑байтных блоков данных из UART также осуществлялся с помощью DMA. Синхронизация приемника выполнялась во время речевых пауз. По состоянию VAD-флага определялось наличие речевой паузы непосредственно перед принятым блоком. Затем данные записывались в кольцевой буфер, вмещающий 32 блока, который необходим для компенсации спонтанных задержек в канале связи (джиттера). Такой буфер вносил определенную латентность в канал, обеспечивая равномерное извлечение данных и тем самым предупреждая перерывы в воспроизведении голоса. Для нормальной работы проигрывателя важно поддерживать оптимальное наполнение буфера: как можно меньшее для снижения латентности, но достаточное для компенсации неравномерности доставки блоков данных. Неравномерность постоянно оценивалась в процессе приема, и на основе этой оценки обновлялось значение уровня наполнения буфера, оптимальное для данных условий связи.
Поддержка оптимального заполнения буфера производилась двумя способами. При непрерывной речи уровень заполнения буфера регулировался подстройкой скорости воспроизведения и изменением периода соответствующего таймера (см. ниже). А в случае пауз с приходом первого речевого фрейма в буфер предварительно помещались фреймы тишины в количестве, необходимом для поддержки оптимального заполнения.
Формирование аудиосигнала производилось 12‑битным модулем DAC, управляемым подстраиваемым таймером. Данные на DAC пересылались с помощью DMA через двойной аудиобуфер. Заполнение неиспользуемой части двойного буфера реализовано декодером, извлекающим очередной блок данных из кольцевого буфера и преобразующим его во фрейм. В случае если кольцевой буфер был пуст, вместо декодирования происходило обнуление соответствующей половины аудиобуфера, в результате чего формировалась речевая пауза.
Цифровое эхоподавление не применялось, так как ресурсы микроконтроллера недостаточны для выполнения данной задачи. При фиксированном расположении микрофона относительно динамика (например, в составе переговорного устройства или телефонной трубки) хорошей альтернативой является аппаратная реализация эхоподавления с подачей части сигнала с выхода динамика на микрофонный вход через подобранную фазовращающую RC-цепочку.
В результате компиляции размер исполняемого кода составил 73 008 байт, табличных данных — 113 720 байт. Программа использовала 420 байт глобальных переменных в ОЗУ и еще 26 292 байт было зарезервировано для динамического выделения. Длительность процедуры кодирования составила 13 мс для голосовых фреймов и 4 мс для фреймов тишины, декодирование выполнялось за 2 мс. Таким образом, задача потребовала 75% постоянной памяти, 85% оперативной памяти и 75% вычислительной мощности контроллера, что позволяет при необходимости расширить функционал (например, использовать стойкое шифрование голосовых данных, динамическое обновление OLED-дисплея и т. п.).
Таким образом, бюджетные микроконтроллеры Nuvoton серии M45x могут быть применены для цифровой обработки речи, обеспечивая работу в режиме реального времени, хорошее качество телефонии и достаточную степень сжатия данных. Исходный код проекта открыт и доступен на github [1]. Получить консультацию по данному проекту, возможностям его модификации и кросс-платформенной реализации, а также по применению микроконтроллеров компании Nuvoton и разработке их программного обеспечения можно непосредственно у инженеров‑консультантов, поддерживающих тесный контакт с производителем для оперативного и полного решения всех технических вопросов
- The demo project of speech com-mu-nicator on Nuvoton Cortex M4F M451LG6 microcontroller.
- Сотовая связь: история, стандарты, технологии. AMR (Adaptive Multi-Rate).
- ETSI TS 126.090. Adaptive Multi-Rate (AMR) speech codec; Transcoding func-tions.
- 4. Nuvoton ARM Cortex-M4 MCUs M451 Base Series. www.nuvoton.com/hq/products/microcontrollers/arm-cortex-m4-mcus/m451-base-series/m451lg6ae/?__locale=en
- NuMicro Family M451 Series Data-sheet.
- NuMicro Family M451 Series Tech-nical Reference Manual.
- Differential/Mono Audio Codec with 2-wire Interface Control Interface.
- Nuvoton ARM Cortex-M NuMicro Family Device Support.
- Nuvoton software: M451 Series_BSP_CMSIS, NuTool-PinConfig, NuTool-Clock-Config.
- ANSI-C code for the floating-point Adaptive Multi-Rate (AMR) speech codec.