Измерим гармонию — анализатор звукового спектра на stm32l4 discovery

Измерим гармонию — анализатор звукового спектра на stm32l4 discovery

В прошлой публикации мы подключали недорогой китайский LCD экран к плате STM32L4 Discovery. Сейчас мы попытаемся реализовать на данной комбинации что-то выходящее за рамки классического моргания светодиодом, в частности анализатор звукового спектра, что применяет имеющийся на плате микрофон. Заодно я поведаю, как пользоваться ОС FreeRTOS, и для чего она нужна, и из-за чего в нотной октаве 12 нот, и чем 53 ноты лучше, чем 12.
Смотрите кроме этого: VKworld Discovery S1 разрешит наблюдать 3D-контент без особых очков

Мода на 3D-технологии неспешно сошла на нет, и последняя только иногда напоминает о себе в кинотеатрах на протяжении выхода очередного блокбастера. Не обращая внимания на это китайский производитель смартфонов VKworld объявил выход в продажу особой новинки называющиеся VKworld Discovery S1. Как направляться из описания, экран телефона устроен так, дабы пользователь имел возможность наблюдать 3D-видео без применения особых очков.

Для этого в смартфоне употребляется панель LG с разрешением 1920х1080 пикселей с разработкой Parallax, которая и создаёт видимость глубины изображения. Диагональ экрана D

Оцифровка звукаМы желаем приобретать сигнал с микрофона, вычислять его спектр посредством стремительного преобразования Фурье (FPU нам в помощь) и показывать итог на LCD в виде ‘цветного водопада’. Силу звука будем кодировать цветом. Будем рисовать с краю дисплея строчок пикселей, где самый левый пиксель будет соответствовать минимальной частоте, а самый правый — большой, наряду с этим прошлая картина будет смещаться на одну строчок, освобождая место для новой строчка.

Отечественный микроконтроллер через чур сложен, дабы начать с нуля, исходя из этого начнем с примера из набора STM32Cube, что именуется DFSDM_AudioRecord. Что таковой DFSDM? Это Digital Filter for Sigma-Delta Modulation.

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

Сейчас в микроконтроллере имеется особый модуль для этого, и все, что требуется, — это настроить его на старте программы. Для этого возможно либо углубиться в чтение документации, либо воспользоваться готовым примером. Я отправился по второму пути. Следующая картина иллюстрирует внутреннюю структуру программы DFSDM_AudioRecord.Оцифрованный звук посредством DMA попадает в кольцевой буфер.

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

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

Другой метод — поручить управление задачами ОС, к примеру FreeRTOS. Это разрешает существенно упростить логику благодаря тому, что любая задача решается в рамках собственного цикла обработки событий, каковые взаимодействуют между собой при помощи функций ОС. К примеру, мы можем добавить задачу обработки данных в виде отдельного цикла, что будет ожидать готовности данных на синхронизационном примитиве — семафоре.

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

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

Семафоры, как и другие синхронизационные примитивы, играют роль чудесной кроличьей норы, в которую проваливается поток выполнения, дабы вынырнуть в второй задаче.Подключить FreeRTOS к собственному проекту достаточно легко. Необходимо только заменить нескончаемый цикл, которым в большинстве случаев заканчивается функция main() в микроконтроллере, на вызов osKernelStart(). Затем компилятор растолкует вам, чего как раз ему не достаточно для компиляции.

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

Вызов обработчика таймера ОС osSystickHandler() необходимо добавить в SysTick_Handler(), а две функции SVC_Handler и PendSV_Handler убрать из собственного кода, потому, что они реализованы в коде ОС. При регистрации задач принципиально важно не совершить ошибку с размером стека. Если он окажется через чур мелок, вы получите краши в самых неожиданных местах. Первым при переполнении стека страдает сама структура, обрисовывающая задачу.

В IAR имеется возможность взглянуть перечень задач. Если вы видите в нем задачу с поменянным именем, значит необходимо расширить размер стека.Вычисляем спектрДля вычисления спектра мы воспользуемся стремительным преобразованием Фурье. Соответствующая функция уже имеется в библиотеке. Она приобретает буфер, заполненный комплексными данными, и формирует итог в том месте же. Соответственно, на входе ей нужен буфер, где оцифрованный звук чередуется с нулями (комплексная часть 0).

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

Кое-какие дополнительные упрочнения нужны чтобы иметь возможность вычислять спектр в различных спектральных диапазонах. Чтобы получить спектр для низких частот, я аккумулирую эти за пара циклов чтения буфера, действенно снижая частоту дискретизации звука, которая изначально образовывает 44.1kHz. В итоге получается 6 диапазонов — 20kHz, 10kHz, 5kHz, 2600Hz, 1300Hz, 650Hz.

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

Логарифм считается довольно продолжительное время кроме того на FPU, исходя из этого я заменил настоящий логарифм кусочно-линейной аппроксимацией, которую легко взять, зная формат представления числа в float32. Старший бит — это символ. Следующие 8 бит — бинарная экспонента плюс 127. Оставшиеся биты — это дробная часть мантиссы при том, что целая часть равна 1 (нюансы денормализованных чисел для простоты опустим).

Значит, выделив из float32 экспоненту и прихватив пара старших бит мантиссы, возможно взять хорошую аппроксимацию логарифма. Полученное число мы посредством предварительно заготовленной таблицы преобразуем в RGB код для показа на LCD. Получается цветовая шкала на 90 либо 60 децибел.

Уровень громкости, соответствующий нулю данной шкалы, возможно настраивать, нажимая джойстик вверх и вниз.Выводим картину — о пользе чтения даташитовТеперь нам осталось вывести картину и оживить отечественный ‘водопад’. Прямолинейный метод сделать это — хранить картину со всего экрана в буфере, обновлять ее в том месте и перерисовывать любой раз, в то время, когда появляются новые эти. Кроме того, что это решение очень неэффективное, у нас еще и не хватает памяти, дабы хранить всю картину.

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

Команда Vertical Scrolling Start Address (0x37) разрешает задать позицию на ленте, соответствующую верхнему краю экрана. Значит, все, что нам необходимо, дабы оживить ‘водопад’ — это записать в эту позицию новый спектр и прокрутить ленту памяти. Соответствующий код был добавлен в драйвер LCD, позаимствованный у глубокоуважаемого Peter Drescher, и адаптированный как обрисовано тут. Единственный недочёт аналогичного подхода: скроллинг трудится лишь на протяжении долгой стороны экрана.

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

Легко понять, из-за чего ноты соседних октав различаются по частоте в 2 раза: тогда ноты более высокой октавы совпадают по частоте со второй гармоникой нот низкой октавы. Говорят, что наряду с этим они звучат «в унисон». Чуть сложнее разобраться в том, из-за чего в октаве 12 нот — семь главных (белые клавиши на клавиатуре фортепьяно) плюс 5 дополнительных (тёмные клавиши).

Дополнительные ноты обозначаются через главные с диезными и бемольными символами, не смотря на то, что по сути никакой отличия между ними и главными нотами нет — все 12 нот образуют геометрическую прогрессию так, что отношение частот между соседними нотами равняется корню 12-й степени из 2. Суть для того чтобы деления октавы на ноты в том, дабы для любой ноты нашлись другие ноты, отличающиеся от нее по частоте в полтора раза — такая комбинация именуется квинтой. Ноты, образующие квинту, звучат в унисон вследствие того что вторая гармоника одной ноты сходится по частоте с третьей гармоникой второй ноты.

На фото ниже продемонстрированы спектры нот До и Соль, образующих квинту, совпадающие гармоники обведены желтым.Как же оказалось, что нот 12? Потому, что ноты образуют геометрическую прогрессию, перейдем к логарифмам. ln(1.5)/ln(2) = 0.58496… Близкое значение получается у дроби 7/12 = 0.583… Другими словами, семь полутонов (промежутков между соседними нотами) оказываются очень близки к квинте — 1.498.

Примечательно, что значительно громадную точность дает дробь 31/53 = 0.58491.., так что квинта отличается от 1.5 лишь в пятом символе по окончании запятой. Данный факт не остался незамеченным, но музыкальные инструменты с 53 нотами в октаве не стали распространены. Их сложно настраивать, на них сложно играться, а процент людей, талантливых ощутить отличие с простыми инструментами, исчезающе мелок.Исходный кодЛежит тут.

Для компиляции употреблялся IAR Embedded Workbench for ARM 7.50.2. Никаких вторых библиотек для компиляции не нужно.

Случайная статья:

Анализатор звукового спектра


Похожие статьи:

Комментирование и размещение ссылок запрещено.

Обсуждение закрыто.