Если ты читаешь это, скорее всего ты уже знаешь, что такое эквалайзер, и хочешь собрать его сам — на реальной железке, а не в симуляции. Teensy 4.1 для этой задачи подходит почти идеально: мощный ARM Cortex-M7 на 600 МГц, встроенный аудио-кодек через дополнительную плату, и готовая библиотека Audio Library, которая серьёзно упрощает жизнь. Разберёмся, как это всё собрать и заставить работать.
Почему именно Teensy 4.1
Обычные Arduino не тянут обработку звука в реальном времени — у них слишком мало мощности и нет аппаратной поддержки I2S. Teensy 4.1 — это другой мир. 600 МГц, 1 МБ оперативки, аппаратный I2S, поддержка 32-битной аудиообработки с плавающей точкой в библиотеке. Ты можешь сделать 10-полосный эквалайзер с минимальной задержкой, и процессор при этом не будет задыхаться.
Важный момент: сама Teensy 4.1 не имеет аудио-выхода. Нужна дополнительная плата — Teensy Audio Board. Без неё ты сможешь обрабатывать цифровой сигнал, но не сможешь подключить наушники или колонки.
Что понадобится для сборки
- Teensy 4.1
- Teensy Audio Board (версия с чипом SGTL5000 или WM8731)
- USB-кабель для прошивки
- Наушники или активные колонки (3.5 мм джек)
- Источник звука: линейный выход, другой аудио-плеер, или можно организовать петлю для тестирования
- Arduino IDE с установленным Teensyduino
Audio Board подключается к Teensy напрямую через разъём — никаких проводов и пайки для базовой конфигурации. Убедись, что плата вставлена правильно: контакты Audio Board совпадают с портом SPI на Teensy 4.1.
Установка инструментов
- Скачай Arduino IDE с официального сайта (версия 1.8 или 2.x — обе работают).
- Установи Teensyduino — это расширение для Arduino IDE, которое добавляет поддержку Teensy. Скачать с сайта pjrc.com.
- В Arduino IDE выбери плату: Tools → Board → Teensy 4.1.
- Убедись, что в Tools → USB Type выбрано Serial + MIDI + Audio — это нужно, чтобы Teensy определялась как аудио-устройство.
Как устроен эквалайзер в библиотеке Teensy Audio
Библиотека Audio работает по принципу блоков, соединённых между собой. Каждый блок — это узел, который делает что-то со звуком: усиливает, фильтрует, задерживает. Ты создаёшь нужные блоки и соединяешь их в цепочку.
Для эквалайзера основной строительный блок — это AudioFilterStateVariable или AudioEffectEnvelope, но удобнее всего использовать AudioFilterBiquad для полочных фильтров или готовый подход через несколько фильтров, каждый на своей частоте.
Типичная цепочка выглядит так: источник звука → несколько полосовых фильтров → сумматор → выход. Каждый фильтр отвечает за свою частотную полосу, ты регулируешь усиление в каждой полосе, и всё это смешивается обратно.
Простой 3-полосный эквалайзер
Начнём с базового варианта — три полы: низкие, средние и высокие частоты. Это даёт понимание принципа, и дальше ты сможешь расширить до 5, 7 или 10 полос.
Вот скелет кода для 3-полосного эквалайзера:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// Выход через I2S на Audio Board
AudioOutputI2S i2s1;
AudioControlSGTL5000 sgtl5000_1;
// Гармонический генератор для теста (замени на реальный источник)
AudioSynthWaveformSine sine1;
// Полосовые фильтры
AudioFilterStateVariable filterLow;
AudioFilterStateVariable filterMid;
AudioFilterStateVariable filterHigh;
// Усилители для каждой полосы (коэффициент усиления)
AudioMultiply gainLow;
AudioMultiply gainMid;
AudioMultiply gainHigh;
// Сумматор
AudioMixer4 mixer1;
// Соединения
AudioConnection patchCord1(sine1, 0, filterLow, 0);
AudioConnection patchCord2(sine1, 0, filterMid, 0);
AudioConnection patchCord3(sine1, 0, filterHigh, 0);
AudioConnection patchCord4(filterLow, 0, gainLow, 0);
AudioConnection patchCord5(filterMid, 0, gainMid, 0);
AudioConnection patchCord6(filterHigh, 0, gainHigh, 0);
AudioConnection patchCord7(gainLow, 0, mixer1, 0);
AudioConnection patchCord8(gainMid, 0, mixer1, 1);
AudioConnection patchCord9(gainHigh, 0, mixer1, 2);
AudioConnection patchCord10(mixer1, 0, i2s1, 0);
AudioConnection patchCord11(mixer1, 0, i2s1, 1);
void setup() {
AudioMemory(12);
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
// Низкие частоты: фильтр нижних частот на 250 Гц
filterLow.frequency(250);
filterLow.resonance(0.7);
// Средние частоты: полосовой фильтр на 1000 Гц
filterMid.frequency(1000);
filterMid.resonance(1.0);
// Высокие частоты: фильтр верхних частот на 4000 Гц
filterHigh.frequency(4000);
filterHigh.resonance(0.7);
// Начальное усиление — единица (без изменений)
gainLow.gain(1.0);
gainMid.gain(1.0);
gainHigh.gain(1.0);
// Все каналы микшера на полную
mixer1.gain(0, 1.0);
mixer1.gain(1, 1.0);
mixer1.gain(2, 1.0);
mixer1.gain(3, 0.0);
sine1.frequency(440);
sine1.amplitude(0.5);
}
void loop() {
// Здесь можно считывать потенциометры и менять усиление
}
Обрати внимание на AudioMemory(12) — это выделение памяти для аудио-буферов. Чем больше блоков и соединений, тем больше памяти нужно. Для 10-полосного эквалайзера может потребоваться 20–30 блоков памяти.
Управление с потенциометров
Чтобы эквалайзер был полезен, нужны физические ручки. Подключи три потенциометра к аналоговым входам Teensy 4.1 (пины A0, A1, A2) и в loop() считывай их положение:
void loop() {
// Потенциометр на A0 управляет низкими частотами
float lowGain = analogRead(A0) / 1023.0 * 2.0; // от 0 до 2.0
gainLow.gain(lowGain);
// A1 — средние
float midGain = analogRead(A1) / 1023.0 * 2.0;
gainMid.gain(midGain);
// A2 — высокие
float highGain = analogRead(A2) / 1023.0 * 2.0;
gainHigh.gain(highGain);
delay(10); // небольшая задержка для стабильности
}
Диапазон от 0 до 2.0 означает, что ты можешь как ослаблять полосу (0), так и усиливать в два раза (2.0). Если нужно больше усиления — увеличь верхнюю границу, но помни о клиппинге.
Сравнение подходов к реализации
Есть несколько способов сделать эквалайзер на Teensy. Выбор зависит от того, что тебе важнее: простота, качество звука или гибкость.
| Подход | Библиотечные блоки | Качество фильтров | Сложность | Задержка |
|---|---|---|---|---|
| State Variable (полочные) | AudioFilterStateVariable | Среднее, подходит для музыки | Низкая | Минимальная |
| Biquad (параметрический) | AudioFilterBiquad | Хорошее, точный контроль частоты | Средняя | Минимальная |
| FFT-фильтрация | AudioAnalyzeFFT1024 | Отличное, но сложное в настройке | Высокая | Заметная (блоки по 1024 сэмпла) |
| Внешний DSP-процессор | — | Зависит от чипа | Высокая | Минимальная |
Для первого проекта бери State Variable — он проще всего настраивается и даёт приличный результат. Если нужна точная настройка конкретной частоты — переходи на Biquad. FFT имеет смысл, когда ты делаешь визуализатор спектра параллельно с обработкой.
Расширение до 5 и 10 полос
Принцип тот же, просто добавляешь больше фильтров. Для классического 10-полосого эквалайзера стандартные частоты октавные: 31 Гц, 62 Гц, 125 Гц, 250 Гц, 500 Гц, 1 кГц, 2 кГц, 4 кГц, 8 кГц, 16 кГц.
Но есть нюанс: если ты используешь 10 фильтров State Variable, каждый из них обрабатывает весь сигнал, а не только «свою» полосу. Это значит, что суммарная характеристика не будет складываться чисто. Для более точного разделения лучше использовать Biquad с типом bandpass для средних полос и lowpass/highpass для крайних.
Пример настройки Biquad для полосы на 1 кГц:
filter1.frequency(1000);
filter1.Q(1.414); // добротность для ровной АЧХ
filter1.setBandpass(); // если поддерживается в твоей версии библиотеки
В некоторых версиях Teensy Audio Library тип фильтра задаётся через отдельный метод. Проверь документацию своей версии — библиотека обновляется, и API может отличаться.
Подключение реального источника звука
Для теста синусоидальный генератор подходит, но в реальности нужен внешний аудио-вход. Audio Board имеет линейный вход (Line In) — подключи туда выход телефона, плеера или другого источника.
В коде замени генератор на линейный вход:
AudioInputI2S i2sIn;
// Вместо sine1 используем вход
AudioConnection patchCord1(i2sIn, 0, filterLow, 0);
AudioConnection patchCord2(i2sIn, 0, filterMid, 0);
AudioConnection patchCord3(i2sIn, 0, filterHigh, 0);
Не забудь включить вход в setup():
sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
sgtl5000_1.lineInLevel(5); // уровень входа, подбирай под свой источник
Уровень входа — это частый источник проблем. Если звук хрипит, уменьши lineInLevel. Если слишком тихо — увеличь, но не выше максимального значения для твоей платы.
Частые ошибки и как их избежать
- Не хватает памяти. Если прошивка скомпилировалась, но звук тормозит или пропадает — увеличь параметр AudioMemory(). Каждый блок потребляет память, и 12 — это минимум для простых проектов.
- Неправильное питание. Teensy 4.1 может потреблять до 250 мА при полной нагрузке, плюс Audio Board. Питание через USB от компьютера обычно достаточно, но если подключаешь периферию — убедись, что USB-порт даёт достаточно тока.
- Земляные петли. Если слышен гул 50/60 Гц, это проблема с заземлением. Попробуй питать Teensy и источник звука от одного USB-хаба или используй изолированный вход.
- Клиппинг при усилении. Если усиливаешь полосу больше чем в 2 раза, цифровой сигнал может превысить максимум и начать клиппить. Лучше ослаблять ненужные полосы, чем усилить одну до предела.
- Забыл про output level. После микшера сигнал может быть слишком горячим. Добавь финальный контроль громкости через sgtl5000_1.volume() или через дополнительный блок AudioMultiply перед выходом.
Что выбрать под свою задачу
Нужен простой тонконтроль для наушников? — 3-полосный State Variable, три потенциометра, минимальный код. Соберёшь за вечер.
Хочешь параметрический эквалайзер для комнатной коррекции? — 5–7 полос с Biquad, точная настройка частот и Q. Можно даже сделать сохранение настроек в EEPROM.
Делаешь визуализатор + эквалайзер? — добавь AudioAnalyzeFFT1024 параллельно с фильтрами. FFT пойдёт на дисплей, а фильтры на выход. Учти, что FFT добавляет задержку.
Нужна минимальная задержка для живого выступления? — избегай FFT, используй только Biquad фильтры, уменьшай размер аудио-буферов (но следи за перегрузкой процессора).
Оптимизация и отладка
Библиотека Teensy Audio имеет удобный инструмент — Audio System Design Tool (веб-страница на сайте pjrc.com). Ты рисуешь схему блоков графически, а она генерирует код соединений. Это экономит кучу времени и помогает не запутаться в patchCord’ах.
Для отладки используй AudioMemoryUsage() — выводит в Serial Monitor, сколько блоков памяти занято. Если память подходит к пределу, процессор начнёт деградировать.
Ещё полезная функция — AudioProcessorUsage() — показывает загрузку процессора в процентах для каждого блока. Если какой-то фильтр жрёт больше 80%, пора оптимизировать.
Сохранение настроек и продвинутые фичи
Если хочешь, чтобы эквалайзер запоминал настройки между перезагрузками, используй EEPROM:
#include <EEPROM.h>
// Сохранение
EEPROM.put(0, lowGain);
EEPROM.put(4, midGain);
EEPROM.put(8, highGain);
// Загрузка при старте
EEPROM.get(0, lowGain);
EEPROM.get(4, midGain);
EEPROM.get(8, highGain);
Для более сложных проектов можно добавить MIDI-управление — Teensy 4.1 умеет работать как MIDI-устройство, и ты сможешь управлять полосами с контроллера или DAW. В библиотеке есть готовые классы AudioControlMidi.
Итог
Цифровой эквалайзер на Teensy 4.1 — это реальный, рабочий проект, который можно собрать за один вечер. Начни с 3-полосного варианта на State Variable фильтрах, добавь потенциометры, добейся чистого звучания. Потом расширяй до 5–10 полос, экспериментируй с Biquad, добавляй сохранение настроек и MIDI.
Главное — не пытайся сразу сделать идеальный 10-полосный параметрический эквалайзер. Сначала застави работать простой вариант, пойми, как ведут себя фильтры, как складываются полосы. Потом уже усложняй. Так ты получишь работающий проект, а не недоделанный хлам.
Если застрял — смотри примеры в самой библиотеке Teensy Audio (File → Examples → Audio). Там есть демки с фильтрами, микшерами и эффектами, которые можно комбинировать под свой проект.
