Как можно догадаться, это онлайн-редактор. Прямо из браузера. Максимально простой с одной стороны, и позволяющий редактировать поток «сырых» MIDI команд. Это важно для того, чтобы убрать разные левые команды, которые будут мешать нормальной работе движка автоаккомпанемента.
И, что хорошо, он умеет соединяться с внешними звуковыми модулями, подключенными по USB и проигрывать на них текущую мелодию. Писать мелодию надо с тем же синтезатором, на котором она будет проигрываться.
Я даже думаю, что будет правильным встраивать выбор т.н. «драмсета» (не соображу, каким должен быть русский аналог этого слова) в сам MIDI-файл.
сами платы RP2040 Zero (взял 3 штуки на всякий случай — по 167 р. за штуку)
модули SD карты (2 штуки на всякий случай — почему бы нет? Они стоят по 70 р. за штуку)
панельки для EEPROM памяти
5 микросхем EEPROM памяти на 16 kb — по 16 рублей за штуку
В микроконтроллере своей EEPROM памяти нет, надо будет лепить внешнюю.
Вообще, я для экспериментов на макетке заказал ещё спец-модуль (за 80 р.). Но он еще из Китая не выехал; почему-то почтой отправили. Однако, если дело дойдёт до написания интерфейса к EEPROM раньше, чем приедет модуль, придётся втыкать в макетку голую микросхему, и городить обвязку самому. Там несложно.
И модули преобразователя напряжения не приехали ещё. Этому микроконтроллеру надо 3.3 В. Так что 2-я версия баяна будет вся 3-х вольтовая. Регистры и датчики Холла, очень надеюсь, нормально заработают от 3 вольт (судя по даташитам, должны заработать без проблем).
Один микроконтроллер я уже распаковал и проверил. К компу подключается, прошивка в него загружается. Единственное — если грузить прошивку в него с помощью arduino-cli, то надо контроллер втыкать в USB порт с нажатой кнопкой «boot», иначе оно контроллер не видит. (Arduino IDE отлично загружает прошивку без кнопки, но я в IDE работать не люблю; у меня всё настроено в VIM-e).
В качестве проверочной программы я использовал пример кода, работающего на двух ядрах контроллера. Оно реально работает. Прикольно. Эта штука очень пригодится, потому что я намерен авто-аккомпанемент вынести на второе ядро; как раз это ресурсоёмкая изолированная задача, которую стоит отделить от основного функционала.
Вчера вороне бог послал кусочек сыра. В виде звукового модуля MB Music Pro.DX.
Я, конечно, знал, что он хорош (на сайте есть примеры звучания). Но личный опыт — это личный опыт.
Отчаянно рекомендую этот модуль всем, кто всё ещё выбирает себе синтезатор, но ещё не выбрал. В нём просто премиальный набор звуков. И даже аккордеоны там присутствуют в достаточном количестве, и даже «простой баянный» звук там есть (называется «Reed Organ», но мной этот звук воспринимается именно как баянный). Само собой, органные звуки на высоте все без исключения.
Басовые звуки — моё почтение! Контрабасов (струнных) аж три, и звучат они очень натурально.
Оно компилируется, работает, и позволяет заглянуть в потроха MIDI файлов.
Правда, оно написано но новой модной версии С++, позволяющей удивительные (для старого меня) конструкции — см. рис. 1. И требующей установить компилятор clang.
Понятно, придётся всё это адаптировать к ардуиновскому С++. Но пока я считаю, что это самый короткий путь для меня чтобы получить код, сканирующий любой MIDI файл и позволяюший мне узнать про этот файл всё, что мне надо.
Отдельное удивление вызвал факт, что программа LMMS (которую я использую для создания MIDI файлов) задаёт темп воспроизведения не в заголовке MIDI файла (как я ожидал после изучения формата MIDI файлов), а с помощью МЕТА-команды. Это несколько усложняет дело, но уже хорошо, что я знаю, как там задаётся темп на самом деле.
Ну, в общем, худшие подозрения оправдались: там нет никакого такого поля в заголовке файла, в котором бы были указаны номера использованных каналов. В MIDI файлах хранится тупо поток MIDI команд, которые «как есть» отправляются в синтезатор. А номер MIDI-канала, как известно, является частью статус-байта каждой команды. Т.е. придётся перебирать все команды (точнее все статус-байты) в записанном потоке, чтобы составить список используемых каналов. Это всё для того, чтобы проверять, что MIDI-каналы, использованные в файле авто-аккомпанемента, не пересекаются с каналами, связанными с клавиатурами баяна. (В первой версии буду просто проверять, что всегда используется 10-й канал, т.е. стандартный канал ударных инструментов.)
Осталось либо найти готовую библиотеку чтение MIDI файлов, либо писать собственный сканер. Но поиск таких библиотек — это уже будет задача на следующий вечер.
Алгоритм простейший: перебираем все 128 каналов по очереди, смотрим в каких каналах есть активность. Берём самое большое обнаруженное «окно» и выбираем канал, находящийся в самой середине этого окна. Само собой, всё происходит без участия человека.
Выбором канала будет заниматься передатчик (т.е. баян).
По моей задумке, после того, как канал для передачи выбран, передатчик начнёт в этом канале посылать спец-сигнал. А приёмник при включении будет сканировать все каналы в поисках этого сигнала. В результате должно получиться выбрать свободный канал и установить связь совсем без участия человека.
В общем-то, можно начинать писать прошивку приемника, который будет принимать байтики из баяна и отправлять их в MIDI порт.
И начать надо с алогритма поиска свободного канала (на стороне передатчика) и автоматического поиска передатчика на всех каналах (на стороне приемника). Не хочу вручную каналы связи задавать; пусть само трудится.
Те мелодии, которые встроены сейчас в прошивку v1.00, — это по сути последовательность миди-команд. Раз уж у нас будет контроллер, в котором дофига памяти, почему бы не читать MIDI-файлы с флешки?
Теоретически, можно будет вообще любые «минусовки» проигрывать, не только партию ударных.
Здесь показываю упомянутый ранее новый способ выбора инструмента.
В целом, этот экран повторяет тот же самый интерфейс, который используется в самом синтезаторе ATEMP. Можно перебирать группы инструментов, а потом выбирать инструмент внутри группы. Или же просто продолжая нажимать стрелки вправо-влево можно перебрать вообще все звуки, которые реализованы в синтезаторе.
Мне не нравится, как сейчас в текущей версии прошивки происходит выбор инструментов. Если для какого-то инструмента (номера программы в терминах MIDI) есть варианты звучания (разные «банки», переключаемые MIDI командой CC 0 vv), то надо сначала выбрать номер инструмента, а потом перебирать все доступные для него варианты звучания. И при этом видишь только номера инструментов и номера вариантов; очень много нажатий кнопок (даже в адаптированном к синтезатору варианте) и совершенно никакой наглядности.
Делаю экспериментальный вариант спец-экрана для выбора инструмента. Будет два селектора: «группа инструментов» (пианино, электронные пианино, органы, гитары, и т.п.) и «инструмент внутри группы». И чтобы перебирались не номера, которые фиг запомнишь, а нормальные названия групп и инструментов (текстом).
И беда пришла , откуда не ждал. Я, ни в чём себе не отказывая, добавил все названия всех групп инструментов на руссском, каждое название длиной до 20 символов (ширина экрана). И прошивка перестала влезать во флеш-память. 🙁 Там оставалось свободным примерно 6 килобайт флеш-памяти, и табличка с текстом заняла их все, и даже больше.
Пришлось утоптать тексты: ограничил длину названий 15-ю символами и, главное, перевёл всё обратно на английский. В результате осталось свободным примерно 2 килобайта флеша.
Этого достаточно для добавления поддержки одного синтезатора, но недостаточно для дальнейшего развития, когда понадобится поддерживать несколько синтезаторов. Ну и объём кода тоже наверняка увеличится ещё.
А значит надо менять платформу.
Изучив варианты, я думаю, что остановлюсь на RP2040-Zero (см. рис. 1). Там 2 процессора, 264 кб ОЗУ, 2 Мб флеша. И оно давно поддерживается средой Arduino IDE. У меня есть одна внешняя зависимость: библиотека подержки OLED экрана GyverOLED; так вот она, вроде, нормально компилится для RP2040 (работу пока проверить не на чем). Т.е. переход вполне реален. Надо заказать пару контроллеров и слепить прототипчик.
Там, правда, нет встроенной EEPROM памяти. И это жирный минус. Придётся лепить внешнюю микросхему AT24C256. Но это решаемо.