Создание и синтезатор Arduino без библиотеки тонов
Я думаю о том, чтобы попытаться сделать синтезатор Arduino, используя настоящий аналоговый выход на Due. Однако я хотел бы иметь возможность воспроизводить несколько нот одновременно на одном зуммере. Возможно ли это и как мне это сделать?
@Someone, 👍1
Обсуждение2 ответа
Лучший ответ:
Вам просто нужно добавить формы волны. Например, если вы хотите играть чистых тонов (самый простой и скучный тембр), вы генерируете синус поднимите волну для каждого из них и сложите их вместе:
struct Note {
float frequency;
float phase;
bool is_active;
} notes[MAX_NOTES];
void output_sample()
{
static uint32_t previous_time;
uint32_t now = micros();
uint32_t elapsed_time = now - previous_time;
previous_time = now;
float output = 0;
for (int i = 0; i < MAX_NOTES; i++) {
Note *note = ¬es[i];
if (note->is_active) {
output += cos(note->phase);
note->phase += 2*M_PI*note->frequency*1e-6*elapsed_time;
if (note->phase >= 2*M_PI) {
note->phase -= 2*M_PI;
}
}
}
analogWrite(DAC_PIN, 2048 + round(output * (2047.0 / MAX_NOTES)));
}
Функция output_sample()
должна вызываться как можно чаще.
возможный. Вы можете изменить массив notes
в любое время, чтобы добавить, удалить или
изменить примечания.
Здесь есть место для оптимизации, например:
сохранение
2*M_PI*note->frequency*1e-6
в качестве «частоты», чтобы сохранить некоторые расчетыиспользуя волновую таблицу вместо функции
cos()
(я не знаю, как хорошо в трансцендентальной математике)заменив
elapsed_time
на константу, если вам удастся вывести образцы с фиксированной скоростью.
Правка: я написал: «Вы можете изменить массив notes
в любое время, чтобы добавить,
удалить или изменить заметки». Вот как начать или остановить ноту, т.е.
добавить или удалить его из списка активных заметок:
// Начать заметку. Возвращает индекс для использования с stop_note() или -1, если
// мы не смогли запустить заметку, потому что мы уже выводим
// максимальное количество одновременных нот.
int start_note(float frequency)
{
int i; // индекс заметки в массиве notes[]
// Находим свободный слот в массиве.
for (i = 0; i < MAX_NOTES; i++)
if (!notes[i].is_active) break; // найденный
// Не удалось найти свободный слот?
if (i == MAX_NOTES) return -1;
// Настраиваем параметры заметки.
notes[i].frequency = frequency;
notes[i].phase = 0;
notes[i].is_active = true;
return i;
}
// Остановить заметку с заданным индексом.
void stop_note(int index)
{
if (index >=0 && index < MAX_NOTES)
notes[index].is_active = false;
}
Как добавить сюда заметки? Я не особо разбираюсь в структурах., @Someone
@Someone: вы находите ячейку в массиве, где is_active имеет значение false, устанавливаете желаемую частоту и устанавливаете is_active на true., @Edgar Bonet
как добавить элемент в массив заметок?, @Someone
Звук — это не что иное, как несколько простых волн, объединенных в одну. Итак, теоретически вы можете воспроизвести столько звуков (тонов), сколько захотите, на одном контакте. Если вы хотите перейти на настоящий аналоговый сигнал, вам, вероятно, следует использовать синусоидальную волну для генерации звука. Однако в этом случае вы можете сделать следующее: Либо сделайте функцию, которая была бы способна генерировать синусоидальную волну нужной вам частоты. В случае истинного аналога это, вероятно, будет сделано путем вычисления фактических значений греха и использования map(). преобразование функций 0–1 в 0–1024 и запись на вывод. Частоту можно регулировать, изменяя задержку между каждым шагом изменения напряжения или значения DAC. Однако это не позволит использовать несколько частот. В качестве альтернативы для одновременного воспроизведения нескольких частот вам потребуется вычислить инверсию Фурье всех волн, которые вы хотите воспроизвести. воспроизвести и отправить результаты на DAC.
И вам нужно будет использовать динамик вместо зуммера, так как они могут воспроизводить один тон за раз., @Coder_fox
«_Инверсия Фурье_» — это ненужный математический жаргон для того, что представляет собой просто _сумму_ тонов., @Edgar Bonet
@EdgarBonet да, в основном это сумма., @Coder_fox
Как мне это сделать?, @Someone
@Someone Написание кода, который будет выполнять описанное выше. Я включил гиперссылки, чтобы помочь понять, что имеется в виду и как это использовать. Кроме того, посетите страницу https://www.arduino.cc/reference/en/, которая содержит много информации о том, как выполнять математические и логические операции на языке Arduino, а также о том, как управлять аппаратным обеспечением Arduino., @Coder_fox
Смешивание звуков не так просто, как их математическое суммирование (а также суммирование и усреднение для понижения уровня). Я совершил эту ошибку несколько лет назад, и результаты были дерьмовыми. Как только я нашел подходящую функцию микширования звука, я никогда не оглядывался назад..., @Majenko
- Есть ли способ воспроизводить звуки с Arduino без использования звукового экрана?
- AnalogWrite(DAC0, X), Аналоговое напряжение на выводе DAC0 выше при меньшем значении X - это нормально?
- Контакт клавиатуры как прерывание (проводка или программирование)
- SimpleAudioPlayer + функция сна
- Arduino Due vs Mega 2560
- Точность часов времени Arduino
- Регистры ввода-вывода SAM3X8E (Arduino Due)
- Как подключить ардуино к разъему для наушников?
что такое "зуммер"? .... он может воспроизводить разные тона?, @jsotola