paulgorman.org/technical

Synthesizers (music, audio, etc.)

Sat 25 Jul 2020 09:36:27 AM EDT

This is a naive exploration of synthesizers and some associated audio and music things

MIDI

Musical Instrument Ditigal Interface is a protocol created in the 80’s to let equipment from different manufacturers communicate.

A MIDI communication happens over a port and a channel. Each port has sixteen channels. Ports traditionally corresponded to physical ports on a device, but one USB connection can now carry multiple MIDI ports.

(“OMNI mode” means a MIDI device sends the same data down all channels simultaneously.)

A MIDI controller sends events (like “note on” or “note off”) to a virtual instrument that actually produces sound. There’s very often a correspondence of one MIDI channel to one VI.

In addition to note on/off messages, a MIDI controller can also send controller change (CC) messages with a controller ID and a value 0–127. CC messages often correspond to dial controls, like volume or reverb dials.

A third type of MIDI message is patch change that ask for channel 1 to switch from vibraphone, for example, to marimba.

JACK

JACK is a linux audio routing daemon.

qjackctl is a GUI control for JACK.

🐚  fortean  ~ $ systemctl --user disable pulseaudio.service pulseaudio.socket
🐚  fortean  ~ $ systemctl --user stop pulseaudio.service pulseaudio.socket
🐚  fortean  ~ $ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Generic [HD-Audio Generic], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Generic [HD-Audio Generic], device 7: HDMI 1 [HDMI 1]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Generic [HD-Audio Generic], device 8: HDMI 2 [HDMI 2]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Generic_1 [HD-Audio Generic], device 0: ALC257 Analog [ALC257 Analog]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
🐚  fortean  ~ $ jackd -d alsa -d hw:1 &
🐚  fortean  ~ $ jack_lsp -Ac
system:capture_1
   alsa_pcm:hw:1:out1
system:capture_2
   alsa_pcm:hw:1:out2
system:playback_1
   alsa_pcm:hw:1:in1
system:playback_2
   alsa_pcm:hw:1:in2
🐚  fortean  ~ $ fluidsynth -m jack -a jack /usr/share/sounds/sf3/default-GM.sf3 /usr/share/sounds/sf2/FluidR3_GS.sf2 /usr/share/sounds/sf2/OPL-3_FM_128M.sf2
🐚  fortean  ~ $ jack-keyboard
🐚  fortean  ~ $ jack_lsp -c
system:capture_1
system:capture_2
system:playback_1
system:playback_2
fluidsynth-midi:midi_00
fluidsynth-midi:left
fluidsynth-midi:right
jack-keyboard:midi_out
jack-keyboard:midi_in
🐚  fortean  ~ $ jack_connect jack-keyboard:midi_out fluidsynth-midi:midi_00
🐚  fortean  ~ $ jack_connect fluidsynth-midi:left system:playback_1
🐚  fortean  ~ $ jack_connect fluidsynth-midi:right system:playback_2
🐚  fortean  ~ $ jack_lsp -c                                         
system:capture_1
system:capture_2
system:playback_1
   fluidsynth-midi:left
system:playback_2
   fluidsynth-midi:right
fluidsynth-midi:midi_00
   jack-keyboard:midi_out
fluidsynth-midi:left
   system:playback_1
fluidsynth-midi:right
   system:playback_2
jack-keyboard:midi_out
   fluidsynth-midi:midi_00
jack-keyboard:midi_in

Fluid:

> gain 2
> prog 0 92
> noteon 0 50 124
> noteoff 0 50

To just mess with Fluidsynth on its own, without disabling pulseaudio and starting JACK, have it talk directly to ALSA:

🐚  fortean  ~ $ fluidsynth -m alsa_seq -a alsa /usr/share/sounds/sf3/default-GM.sf3 /usr/share/sounds/sf2/FluidR3_GS.sf2 /usr/share/sounds/sf2/OPL-3_FM_128M.sf2

Sending Fluidsynth MIDI input:

🐚  fortean  ~ $ aconnect -l
client 0: 'System' [type=kernel]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
        Connected From: 130:0
client 128: 'FLUID Synth (98506)' [type=user,pid=98506]
    0 'Synth input port (98506:0)'
client 129: 'VMPK Input' [type=user,pid=98571]
    0 'in              '
client 130: 'VMPK Output' [type=user,pid=98571]
    0 'out             '
        Connecting To: 14:0
🐚  fortean  ~ $ aconnect 130:0 128:0

Record MIDI input:

🐚  fortean  ~ $ arecordmidi -p 130:0 test.midi
^C

jack-keyboard

VMPK is anothter virtual keyboard, but it doesn’t connect to JACK.

# apt install jack-keyboard

Fluidsynth

# apt install fluidsynth freepats fluid-soundfont-gs fluid-soundfont-gm opl3-soundfont qsynth
🐚  fortean  ~ $ aconnect 24 128
$ man 1 fluidsynth
$ fluidsynth -m alsa_seq -a alsa
> help
> load /usr/share/sounds/sf3/default-GM.sf3
> load /usr/share/sounds/sf2/OPL-3_FM_128M.sf2
> settings
> inst font
> prog 0 11

Fluidsynth is a synthesizer back end. Qsynth is a GUI front end for it (that I never could get to work).

$ fluidsynth -m alsa_seq -a pulseaudio /usr/share/sounds/sf3/default-GM.sf3 /usr/share/sounds/sf2/FluidR3_GS.sf2 /usr/share/sounds/sf2/OPL-3_FM_128M.sf2

Also inputs and outputs:

🐚  fortean  ~ $ aconnect -i
client 0: 'System' [type=kernel]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 24: 'nanoKEY' [type=kernel,card=2]
    0 'nanoKEY MIDI 1  '
🐚  fortean  ~ $ aconnect -o
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 24: 'nanoKEY' [type=kernel,card=2]
    0 'nanoKEY MIDI 1  '
client 128: 'FLUID Synth (44822)' [type=user,pid=44822]
    0 'Synth input port (44822:0)'
🐚  fortean  ~ $ aconnect 24 128