[Из песочницы] Как сделать удобный синтезатор своими руками

В детстве у меня было пианино, такое настоящее, советское, киллограм на 300. Мне нравилось на нем бренчать, а после окончания музыкальной школы даже кое-что играть. Пианино — это классно, аутентично, но совершенно не практично. А чтобы совсем прям для души, нужна еще и барабанная установка, пяток примочек к электрогитаре, кларнет, ситар и сэмпловые лупы…

veoxgny2iuiv9jjfsuqyfhq9lzq.jpeg

Конечно, сейчас уже не нужно из квартиры делать гараж-студию на заначку в шесть зарплат, достаточно установить на ПК бесплатный музыкальный редактор. Но, неудобно это все.

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

Синтезатор ведь что из себя представляет? Большое устройство, с музыкальной клавиатурой, которое где-то должно занимать прилично места. В которое встроена акустика, а ведь у меня уже есть ресивер с колонками. В которое встроен плохенький ПК, а ведь у меня есть хороший ПК.

Получается, что за 40 тысяч я покупаю то, что у меня уже есть в лучшем качестве, за исключением лишь клавиатуры. Это просто какой-то максимум нерациональных расходов.

В поисках отдельной клавиатуры я набрел на такой класс устройств как USB MIDI Keyboard.
Мне всегда казалось, что MIDI это из области профессиональной музыкальной деятельности.
Но сейчас все музыку делают на ПК, в любом удобном месте, а значит, музыкантам нужны мобильные музыкальные клавиатуры, которые легко помещаются в рюкзак.

Вот оно!

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

Есть устройства побольше и поменьше, есть подороже и чуть дешевле. Я выбрал вариант за примерно 5 тыр. У него две октавы, нормального размера клавиши, кнопки для ударников, ручки настройки, то есть все, о чем может мечтать начинающий музыкант-электронщик.

Я не спец в создании музыки на ПК, поэтому было сложно искать пути реализации своей задумки. Информацию приходилось собирать по крупицам. Пазл постепенно стал складываться и получилось собрать работающее решение, которым с вами и делюсь. Как ни странно, но в стандартном дистрибутиве Raspbian/Debian нашлось все что нужно, даже не пришлось подключать внешние репозитории.

В качестве секвенсера (приложения, воспроизводящего MIDI-файлы) используется fluidsynth.
MIDI-клавиатура сразу обнаруживается через ALSA и доступна для подключения к секвенсеру.
Для воспроизведения звуков различных инструментов используются открытые базы сэмплов в формате SoundFont2. Для начала установим это все.

sudo -s
apt-get update
apt-get -y install alsa-utils fluid-soundfont-gm fluidsynth


Подключаем MIDI-клавиатуру к Raspberry и запускаем секвенсер в режиме сервера:

fluidsynth -i -s -a alsa -g 3 /usr/share/sounds/sf2/FluidR3_GM.sf2


Выполняем команду:

aconnect -o


В результате мы увидим список доступных MIDI-клиентов:

client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 20: 'VMini' [type=kernel]
    0 'VMini MIDI 1    '
    1 'VMini MIDI 2    '
client 128: 'FLUID Synth (1628)' [type=user]
    0 'Synth input port (1628:0)'


Здесь нам важно запомнить номера клиентов клавиатуры и секвенсера, чтобы затем соединить их командой:

aconnect 20:0 128:0


Теперь у нас все готово для игры на Yamaha Piano (это дефолтный инструмент). Почитайте мануал по fluidsynth, там есть много интересных команд, например, чтобы сменить инструмент на ударники или духовые, задать величину реверберации или хоруса.

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

cat > /etc/init.d/fluidsynth << EOF
#!/bin/bash
 
### BEGIN INIT INFO
# Provides:          fluidsynth
# Required-Start:    $all
# Required-Stop:     
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Fluidsynth deamon to play via MIDI-keyboard
### END INIT INFO

startDaemon() {
      sleep 30s && fluidsynth -i -s -a alsa -g 3 --load-config=/home/osmc/midi-router >/var/log/fluidsynth &
      sleep 60s && aconnect 20:0 128:0 &
}

stopDaemon() {
    pkill -9 fluidsynth &> /dev/null
}

restartDaemon() {
    stopDaemon
    startDaemon
}

case "$1" in
    start)
        startDaemon
        ;;
    stop)
        stopDaemon
        ;;
    restart)
        restartDaemon
        ;;
    status)
        ;;
    *)
        startDaemon
esac
exit 0
EOF


Регистрируем демон для автозапуска:

chmod 755 /etc/init.d/fluidsynth
update-rc.d fluidsynth defaults


Обратите внимание, теперь при старте секвенсеру передается конфигурационный файл (/home/osmc/midi-router), содержащий команды, превращающие нашу клавиатуру в настоящий синтезатор.

Тут дело вот в чем. Каждая клавиша и крутилка на клавиатуре посылает определенные события, со своим номером. Я так понял тут особенных стандартов нет, так что каждый производитель творит что хочет. Например, я хочу чтобы квадратные клавиши звучали ударными, остальные клавиши звучали пианино, ручки управляли громкостью, реверберацией и хорусом.

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

Вот пример моего конфигурационного файла, с комментариями того, что он делает.

cat > /home/osmc/midi-router << EOF
# загружаем стандартные инструменты и ударники, найденные где-то на просторах Сети
load /usr/share/sounds/sf2/FluidR3_GM.sf2
load /home/osmc/241-Drums.SF2
# связываем инструмент каждый со своим каналом
select 1 2 128 0
select 2 1 0 0
# по умолчанию звук идет на канал 0
# перенаправляем события с квадратных клавиш на канал с ударными
router_begin note
router_chan 0 0 0 1
router_par1 36 48 1 0
router_end
# события с остальных клавиш перенаправляем на канал с пианино
router_begin note
router_chan 0 0 0 2
router_par1 0 35 1 0
router_end
router_begin note
router_chan 0 0 0 2
router_par1 49 255 1 0
router_end
# события с ручек мэпим на события, которые понимает секвенсер,
# полный их список есть в документации на сайте fluidsynth
router_begin cc 
router_chan 0 0 0 2
router_par1 14 14 0 98
router_end
router_begin cc 
router_chan 0 0 0 2
router_par1 15 15 0 11
router_end
router_begin cc 
router_chan 0 0 0 2
router_par1 16 16 0 91
router_end
router_begin cc 
router_chan 0 0 0 2
router_par1 17 17 0 93
router_end
# выключаем громкость на канале 0, 
# иначе при нажатии на клавишу 
# разные инструменты будут звучать одновременнно
cc 0 7 0
EOF


Чтобы узнать какие коды генерирует именно ваше устройство, необходимо воспользоваться этой утилитой:

aseqdump -p 20:0


Она слушает и выводит на консоль события с MIDI-клавиатуры. Нажмите кнопку или покрутите ручку и вы увидите тип, канал и код события. Вы можете запрограммировать свою клавиатуру таким образом, каким захотите, а не так, как это придумали инженеры, разработавшие конкретный синтезатор. За что большое спасибо разработчикам fluidsynth, alsa, SoundFont2, Raspberry и V-Mini.

Кстати, эта тема с DIY-синтезаторами нашла отражение в нескольких изобретениях, рекомендую к изучению: раз и два.

© Geektimes