Звуковой синтезатор на ATmega48

Мир всем, товарищи! Это опять скучающий я. Кто там меня терял? Возрадуйтесь, друзья мои, ибо ныне я здесь и хочу предложить вниманию общественности свою новую поделку, произведенную на свет по вдохновению и от скуки — синтезатор на ATmega48.

Все началось с того, что я был в существенной степени вдохновлен «маленькой фугой» Баха. Потом пришли выходные, которые, как уже известно, нагоняют на меня скуку более всех остальных дней недели, тем самым подвигая на изготовление разнообразных девайсов. И ныне я решил от нечего делать накидать на макетке маленький синтезатор, играющий маленькую фугу. Итак, к делу!

Сперва я решил определиться с диапазоном будущего инструмента, для чего спросил у мамы (она у меня музыкант ), какие октавы наиболее употребительны в большинстве мелодий. Оказалось, что их три — малая, первая и вторая. Конечно, более всего меня интересовали количественные характеристики нот, т. е. частоты. К счастью, страница со всем необходимым нашлась очень быстро. Оказалось, что самая высокая ожидаемая нота — си второй октавы — имеет частоту всего лишь 988 Гц (приблизительно), так что весь звукоряд можно с успехом генерировать ШИМ ЦАП-ом (да, это будет не прямоугольник, как в большинстве подобных конструкций, а произвольный семпл). Из этих соображений вырисовывается следующая схема:



Аппаратный канал ШИМ подключен к простейшему фильтру — интегрирующей RC-цепочке, имеющей частоту среза около полутора килогерц (на самом деле ставил то, что было под рукой — вышло удачно). Дальше стоит классический двухтактный повторитель, раскачивающий пятидесятиомный динамик (он тоже валялся в закромах с незапамятных времен). С4 удаляет постоянную составляющую, чтобы ничего ненароком не задымилось. Светодиод был воткнут для отладочных целей, да так и оставлен — теперь он отмечает считывание очередной ноты.

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

Семпл один, нот много. Как менять высоту тона? Есть два классических метода — частичная выборка из массива при неизменной частоте дискретизации и изменение частоты дискретизации при последовательной выборке. В картинках:

Выбираем каждую вторую точку, чтобы увеличить частоту в два раза:



Увеличиваем частоту дискретизации в два раза, чтобы увеличить частоту в два раза:




Очевидно, что изменять частоту в целое число раз проще всего первым методом. Но отношение нот в октаве не целое. И потому для формирования гаммы не остается ничего иного, как применить второй — частота дискретизации задается таймером, и менять ее можно гораздо свободнее. А вот для перехода между октавами вполне логично применять как раз частичную выборку из массива — ведь частоты нот в соседних октавах различаются именно в два раза. Таким образом, для проигрывания заданной ноты нужна следующая информация:

1. Инкремент счетчика массива. Выбираем каждый элемент — получаем ноту исходной октавы, выбираем каждый второй — получаем ту же ноту на октаву выше, каждый четвертый — на две октавы выше, и т. п.
2. Собственно, номер ноты. Я задал в памяти массив, где по номерам нот записаны значения задержки для таймера, контролирующего вывод значений в ЦАП.
3. Задержка до обработки следующей ноты.

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

В самой же октаве надо ореинтироваться на самую высокую ноту, и вот почему. Частота ШИМа составляет примерно 32КГц. Откуда следует, что делать частоту дискретизации выше 16КГц, в общем, бессмысленно. Но изменение частоты дискретизации используется для перехода между нотами в октаве, при этом самая высокая частота соответствует самой высокой ноте. Это и является ограничивающим фактором. Т.е., образцовый семпл надо формировать для си малой октавы. Расчет показывает, что для максимальной частоты дискретизации в районе 16КГц он должен содержать 64 точки.

Итого, я использовал три таймера: восьмибитный T/C0 используется как ШИМ-генератор, T/C2 им управляет (его период задает частоту дискретизации), а шестнадцатибитный T/C1 занимается чтением нот и конфигурированием первых двух таймеров и себя самого (устанавливает инкремент массива семпла, соответствующий октаве, нужный период для T/C2 и для себя самого). Прошивка написана на C в AVR-Studio + WinAVR (AVR-GCC).

Все в сборе (печатку не разрабатывал):



Октав я использую всего три, а нот в каждой их них (считая диезы и бемоли) двенадцать. Т.е., для нумерации и того, и другого можно уложиться в четыре бита, что дает возможность организовать примитивное сжатие, упаковав все это в один байт. А вот под длительность ноты я отдал два честных байта. Т.о., мелодия имеет вид массива, разбитого на блоки по три байта — в старшей тетраде инкремент, соответствующий октаве, в младшей номер ноты. Следующие два байта — длительность в тиках. Маркер конца — три нуля.

Однако очевидно, что руками переводить мелодию в вышеописанный формат довольно затруднительно, поэтому я написал простенький парсер, генерирующий сишный массив из упрощенной латинской записи нот (консольное приложение в Code Blocks + MinGW). Например, начало маленькой фуги выглядит так (тут мне тоже помогла мама ):

1G4 2D4 1Bb4. 1A8 
1G8 1Bb8 1A8 1G8 1F#8 1A8 1D4
1G8 1D8 1A8 1D8 1Bb8 1A16 1G16 1A8 1D8
1G8 1D16 1G16 1A8 1D16 1A16 1Bb8 1A16 1G16 1A16 1D16 2D16 2C16
1Bb16 1A16 1G16 1Bb16 1A16 1G16 1F#16 1A16 1G16 1D16 1G16 1A16 1Bb16 2C16 2D16 2E16
2F16 2E16 2D16 2F16 2E16 2D16 2C#16 2E16 2D8 1A8 2D8 2E8 …


Т.е., <октава><нота>[диез/бемоль]<длительность (знаменатель)>[точка (увеличение длительности в полтора раза)]

На выходе —

const uint8_t melody[] PROGMEM = {
0x27,0xE3,0x16,
0x42,0xE3,0x16,
0x2A,0x54,0x22,
0x29,0x71,0xB,
0x27,0x71,0xB,
0x2A,0x71,0xB,
0x29,0x71,0xB,
0x27,0x71,0xB,
0x26,0x71,0xB,
0x29,0x71,0xB,
0x22,0xE3,0x16,
0x27,0x71,0xB,
0x22,0x71,0xB,
0x29,0x71,0xB,
0x22,0x71,0xB,
0x2A,0x71,0xB,
…


Исходники/бинарники прошивки и конвертера есть в аттаче.

В общем, на сегодня все. Выражаю благодарность своей маме за помощь в музыкальных вопросах.

P.S.

Благодаря тов. Episcop'у я имею возможность вставить видео работы:

  • +4
  • 09 сентября 2011, 19:01
  • _YS_
  • 1
Файлы в топике: synth.zip

Комментарии (54)

RSS свернуть / развернуть
А где кино? :)
0
А я на ютубе не зареган. :)
0
Если есть сильное желание, могу снять и на файлообменник залить. :)
0
Обязательно требуем))) Я могу потом на свой ютуб залить, а ты ссылку вставишь в блог.
0
ОК, в ближайшее время сниму. :)
0
И схему перерисуй, там КЗ))
0
Прое… л, норм все))) Не увидел кое что))
0
Ноты предусмотрел… а паузу? )
0
Естесственно. В простоте душевной я ее тоже классифицирую как ноту. См. исходники.
0
0
  • avatar
  • _YS_
  • 09 сентября 2011, 20:37
+1
Спасибо! one sec, сейчас вкручу его…
0
класс!!!
0
И хотел сказать — однозначно +1
0
О, спасибо, спасибо! :)
0
А Мурку сможешь? :)
Молодец, +1.
0
  • avatar
  • ACE
  • 09 сентября 2011, 21:03
Все могу, парсер есть. :)
0
добавить еще один осциллятор, LFO, ADSR, фильтры и будет ништяк)
0
Скажу по секрету — изначально планировался именно многоголосный синт. Но что-то у меня не срослось в софтовом микшировании, и я урезал его до одного голоса. Но я еще подумаю над полифоническим вариантом.
0
так микшируй аппаратно. есть еще один таймер для второго канала шим?
0
Там один таймер умеет то ли два, то ли три канала. Но я все же хочу разобраться, где косяк с софтовым.
0
два
0
Кстати, как планировалось софтовое сделать?
0
Сложение с ограничением. Там был другой алгоритм работы с выборками, но все в конце концов сводилось к суммированию семплов и клипированию.
0
Круто!!:)
А клавиатура для live-выступлений не планируется?=)
0
Опционально по предзаказу. xDDDDDD
0
ахахах:D
серьёзно, было бы очень здорово)
0
Ну, если с многоголосием разберусь, то, глядишь, можно будет и клавиатуру прикручивать… :) Но вообще это планировалось как нечто самоиграющее.
0
Даёшь чиптюн в массы!))
0
Здорово очень!) Только такое ощущение, что ноты высчитываются не совсем точно.)
Помогло победить скуку?)
0
Только такое ощущение, что ноты высчитываются не совсем точно.

Угу. И светодиод не в такт мигает, хотя должен. Компрессия, походу.

Помогло победить скуку?

А то! Всю неделю бодр! :)
0
А вот под длительность ноты я отдал два честных байта.
А смысл? Вполне хватило бы 7 бит под знаменатель и бита под «точку». Заодно и структуры в массиве получились бы по 2 байта, GCC (и вообще AVR) с ними дружит получше.
0
  • avatar
  • Vga
  • 10 сентября 2011, 05:39
Насколько я понял из маминых объяснений, с длительностями в музыке может твориться нечто загадочное. xD И потому для наибольшей гибкости я оставил под длительность шетнадцатибитное число.
0
Нечто загадочное?
Я не смогу сходу назвать произведение, где не подойдет вариант Vga… В 7 бит войдет любая нота от целой до 64-ой, короче — это уже адовый хардкор, длиннее — ну тут просто одну и ту же ноту без паузы крутить
0
Короче, в музыке я ничего не понимаю, потому расширяемость — наше все. :)
0
Может кто подскажет несложную программу, с помощью которой можно составить и прослушать мелодию перед программированием мк?
0
  • avatar
  • tank
  • 10 сентября 2011, 11:48
В архиве есть исходник и exe таковой.
0
Это надо смотреть в сторону нотных редакторов, правда не припомню ни одного, который умеет экспортировать ноты в латинскую запись.

В архиве есть исходник и exe таковой.
Там, насколько я понял, только конвертер нот из одного «формата» в другой, без возможности создать и прослушать мелодию.)
0
Да, в архиве только конвертер. Конечно, более труЪ было бы написать импорт из MIDI, но чего-то мне сильно лень. :) Все-таки это делалось для развлечения. :)
0
А попросить перевести мелодию в латинскую запись можно любого музыканта. :) Я нашел партитуру маленькой фуги, и мама мне продиктовала с листа.
0
+1
Видел, видел. Хороший проект.
0
Верно ли, что хорошо звучат только те сочетания нот, частоты которых кратны друг другу (например 100 и 200 Гц)?
0
  • avatar
  • tank
  • 11 сентября 2011, 07:01
«Хорошо звучат» — понятие растяжимое и чисто субъективное.)
А ноты с кратными частотами — это одни и те же ноты, но в разных октавах.
0
Я имел в виду диссонанс
0
Консонанс и диссонанс.
Там же и интервалы указаны между нотами в консонирующих и диссонирующих созвучиях, как раз то, о чём первый вопрос был.
0
А вот интересно, можно как-нибудь для этих целей использовать динамик от старого совкового телефона? Удастся ли его раскачать скажем с помощью LM386 и какое тогда напряжение питание надо, ведь в телефонной розетке оно порядочное?
0
Сопротивление динамика?
0
Зачем? Он тихий и имеет высокое сопротивление. Да и качество не ахти, он электромагнитный.
Малогабаритные динамики нынче не редкость же.
Сопротивление динамика?
У моего ТК-67-НТ 47 Ом по постоянному току. Но у них очень высокая индуктивность.
0
  • avatar
  • Vga
  • 11 сентября 2011, 17:34
Надо будет померить сопротивление, я чисто для опытов с контроллерами, не для повседневного пользования :)
Они правда настолько плохие? И вообще, если я сделаю мини-демполату с LM386, напряжение 12В хватит?
0
Они полезны в специфических случаях. Хотя нынче ни для чего такие не нужны, единственное современное применение, где я видел электромагнитные излучатели — это пищалки типа «толстая таблетка с дыркой», которые все дружно путают с пьезиками. У них еще часто генераторы встроены. Основной плюс — у них высокое сопротивление и катушка на неподвижной части (подвижна только металлическая мембрана), так что надежность наверно повыше.
Используй обычный электродинамический излучатель, он же «динамик». С 12В оно туда несколько ватт вкачать может (подробней даташит).
0
  • avatar
  • Vga
  • 11 сентября 2011, 18:36
Ого, несколько ватт — это не хило! Мне просто влом идти в магазин и тратить деньги на динамик, тем более это баловство :)
0
На электромагнитный оно столько не даст. Динамик можно много где найти, да и в магазине простые полсотни стоят.
0
  • avatar
  • Vga
  • 11 сентября 2011, 20:33
Извините, я правильно понял: ч-та квантования 16 кГц, значит макс ч-та синуса 8 кГц?
И на какой тактовой работает данная схема?
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.