Разработать одноголосный синтезатор звука под ESP32 I2S в Arduino

800 руб.за час
22 декабря 2019, 15:42 • 4 отклика • 51 просмотр
Задача программы - циклически воспроизводить файл (звуковой фрагмент) на порт I2S, ресемплируя его согласно переданному параметру частоты и амплитуды. Плата - ESP32 с 36 контактами.

Как я это представляю: в буфер воспроизведения подается каждый n-й семпл звукового фрагмента, n вычисляется в зависимости от переданной частоты и размера файла. Проблемы с артефактами воспроизведения решаем высоким оверсепмлингом исходников. Тестовый файл пришлю на почту.

Фрагменты загружаются как 16-битные массивы, каждый - в отдельном файле.

synth.setWave(id,double periods) - передаем ссылку на один из загруженных семплов
synth.trigger(bool) - запуск или остановка воспроизведения.Каждый следующий trigger запускает воспроизведение с нулевой позиции.

Следующие функции срабатывают мгновенно и не прерывают воспроизведение семпла
synth.setPitch(220.25) - передаем ожидаемое значение частоты. Частота определяет, сколько раз в секунду нужно проиграть семпл, деленный на periods.
synth.setEnvelope(envID) - передает указатель на функцию envelope, принимающую миллисекунды с момента запуска trigger и запуска самого setEnvelope, и возвращающую множитель для проигрываемого семпла в диапазоне 0...1.

Для избежания щелчков воспроизведения, функций envelope в каждый момент времени может использоваться две: служебная и пользовательская
Например, событие trigger включает служебный envelope fadeIN(startTime)
setEnvelope также запускает еще один служебный envelope, который некоторое небольшое время интерполирует разницу между множителем последнего и текущего envelope.