Русский
Русский
English
Статистика
Реклама

Из однобитной музыки мяубитную

Прошлая статья, посвящённая обучающей плате Meowbit и реализациям Python для неё, завершалась упоминанием неспособности CircuitPython проигрывать музыку одновременно с игрой: писать на Python обработчики прерываний CircuitPython не позволяет, а без этого задержка на время перерисовки экрана (порядка 0.15 с) подвешивает звук. Тем не менее, фоновый звук бывает нужен достаточно часто, и для большинства поддерживаемых плат (100 из 189) CircuitPython включает модуль audioio либо audiopwmio, реализующий фоновый звук родными для платы способами. К сожалению, для Meowbit (и вообще для плат на основе STM32) не реализован ни тот ни другой модуль; но в opensource-проекте это дело поправимое :)


Найдите пасхалку в фото

Прежде всего: почему для проигрывания звука есть два разных модуля с полностью одинаковыми API, и на разных платах поддерживается либо тот, либо другой?

Вот как в аудиоредакторе (например Audacity) выглядит секунды обычного (16-битного)
WAV-файлa:


Значение плавно меняется в пределах примерно от 0.2 до +0.2 условной единицы. Если таким же образом менять напряжение, подаваемое на электродинамический громкоговоритель, то так же плавно будет колебаться мембрана примерно от 0.2 своего максимально возможного отклонения в одну сторону, до 0.2 отклонения в другую сторону. Модуль audioio реализует именно такое проигрывание звука через ЦАП плавно меняет напряжение на выводе, соединённом с динамиком.

Но в Meowbit вместо динамика стоит дешёвая пьезопищалка, неспособная отклонять мембрану в промежуточные положения: она из одного крайнего положения очень быстро переходит в другое крайнее, и остаётся там до следующего перехода. Это можно представить как звук с разрешением в один бит на сэмпл:


Таким способом невозможно передавать изменение громкости звука, но теоретически возможно передать все имеющиеся в нём гармоники если параллельно с 32768-кратным понижением разрешения увеличить во столько же раз (т.е. до сотен мегагерц) частоту дискретизации. Маловероятно, что мембрана пьезопищалки сможет колебаться с такой частотой; но это можно использовать и в свою пользу если научиться переключать напряжение на пищалке, когда мембрана на полпути, то можно издавать звуки промежуточной громкости! Поиск по патентам подтверждает, что люди действительно исследуют возможности использовать пьезопищалку таким образом. Мы в эти дебри углубляться не будем, и оставим обычную для WAV частоту дискретизации в десятки килогерц. Для музыки, где основные гармоники в районе килогерца, этого достаточно; речь, однако, превращается в едва разборчивый шум. Можете сравнить, как воспринимается использованный мной восьмисекундный образец звука, воспроизведённый на однобитной пьезопищалке: вначале оригинал, затем однобитная версия, затем запись Meowbit-а микрофоном.


Модуль audiopwmio реализует проигрывание звука через цифровой вывод посредством ШИМ: однобитная аудиозапись превращается в последовательность задержек между переключением
вывода на противоположное значение.

Итак, общий план реализации audiopwmio для Meowbit таков:

  1. Переводим переданную пользователем аудиозапись в ШИМ-формат (список задержек между переключениями);
  2. В обработчике прерывания от таймера переключаем вывод и настраиваем таймер на задержку до следующего переключения. Этот код можно с минимальными изменениями позаимствовать из стандартного модуля pulseio, реализующего в точности то, что нам нужно переключение вывода в соответствии с переданным списком задержек но не позволяющего коду на Python выполняться параллельно с переключением.

Не сразу было очевидно, что надо позаботиться ещё об одном аспекте реализации буферизации аудио. Мой тестовый восьмисекундный образец занимает 8220502 340 КБ это втрое больше, чем всё ОЗУ Meowbit; следовательно, загружать его в память придётся по кускам. Стандартная реализация audiocore.WaveFile загружает WAV-файл кусочками по 256 байт, что соответствует 128 сэмплам или 5.8 мс времени проигрывания. Это значит, что в среднем каждые 5.8 мс audiopwmio должен будет запрашивать повторное наполнение буфера; нет выхода, кроме как разместить этот вызов в том же самом обработчике прерывания от таймера иначе перерисовка экрана может задержать наполнение буфера на добрую сотню миллисекунд. Проблему это, однако, не решает до конца: что произойдёт, если прерывание от таймера случится во время перерисовки экрана? Экран Meowbit подключён через шину SPI, флеш-диск через неё же, значит обращение ко флешу во время перерисовки экрана всё равно невозможно!

В результате получилась реализация audiopwmio, способная воспроизводить аудиозаписи из памяти (или процедурно генерируемые) в максимально достижимом на Meowbit качестве; но аудиозаписи из файлов воспроизводятся только при отсутствии одновременных с этим обращений к экрану и ко флешу. Для звукового сопровождения несложных игр этого вполне хватит. PR с моей реализацией уже больше недели дожидается ревью, и когда audiopwmio для Meowbit появится в официальной версии CircuitPython неизвестно; но это не мешает любым желающим самостоятельно скомпилировать себе CircuitPython с моей добавкой.



Источник: habr.com
К списку статей
Опубликовано: 27.03.2021 16:18:35
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании ruvds.com

Python

Старое железо

Diy или сделай сам

Шим

Circuitpython

Музыка

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru