🎹🎶 A baremetal kernel that turns your Raspberry Pi 3 or later into a Roland MT-32 emulator and SoundFont synthesizer based on Circle, Munt, and FluidSynth.
MIDI host: Pentium II with Yamaha YMF719E-S chip (Audician 32 clone) via internal Wave Blaster connector.
Bug description
Very often (but not always) when I start a MIDI track, the "Unexp. MIDI Status!" appear, although the sounds is OK. It also happens regardless being MT-32 or FluidSynth.
Using a 5V to 3.3V level shifter to convert the TTL level of the sound card to 3.3V.
# ________ _______ __
# __ /_____ `. /____ `. /__`
# ____ ____ __/ /____ _______) / ______) / ____ ______ __
# / __ v __ `./__ _____//_____ < / _____. /____// ___ `. / /
# / / / / / / / /____ _______) // /______ / /____/ // .__
# /__/ /__/ /__/ \______//_________. /_________/ / ______. \____/
# /////////////////////////////////////////////////////// / / //// /// // /
# ```
# mt32-pi.cfg: mt32-pi configuration file.
# Default options are marked with an asterisk (*).
# -----------------------------------------------------------------------------
# System options
# -----------------------------------------------------------------------------
[system]
# Enable or disable verbose startup output.
#
# When enabled, outputs more information to the LCD when starting up.
# This may hide the boot logo on smaller graphical displays; has no effect on
# character displays.
#
# Values: on, off*
verbose = off
# Set the default synthesizer to be made active on startup.
#
# If the default synthesizer is unavailable (e.g. missing ROMs or SoundFonts),
# the first working synth is made active.
#
# Values: mt32*, soundfont
#
# mt32: Use mt32emu (Munt) for Roland MT-32 emulation
# soundfont: Use FluidSynth for SoundFont synthesis
default_synth = soundfont
# Enable or disable support for USB devices.
#
# Disable this to speed up boot time if you are not using any USB devices.
#
# Values: on*, off
usb = on
# Set the I2C baud rate/clock speed for all peripherals (Hz).
#
# Most peripherals will work fine at the default speed (400KHz "fast mode"),
# but larger LCD/OLED displays (e.g. 4-line I2C HD44780 and 64 pixel high
# SSD1306) won't be able to refresh at 60FPS at the default setting.
#
# Try increasing this value to 1000000 (1MHz) for a smoother LCD refresh rate.
# If your display doesn't work, try backing off the speed 100KHz at a time
# until it does.
#
# Values: 100000-1000000 (400000*)
i2c_baud_rate = 400000
# Set the timeout for power saving mode (seconds).
#
# After the specified number of seconds of silence, the CPU clock speed will be
# reduced, the audio device will be stopped, and and the LCD's backlight will
# be turned off to save energy (certain I2C displays only).
#
# Any MIDI activity will instantly bring the system out of power saving mode.
#
# If set to 0, power saving mode is disabled.
#
# Values: 0-3600 (300*)
power_save_timeout = 300
# -----------------------------------------------------------------------------
# MIDI options
# -----------------------------------------------------------------------------
[midi]
# Set the baud rate used for GPIO MIDI.
#
# For connecting to standard MIDI devices (i.e. via DIN cable), this should be
# left at the default rate of 31250.
#
# For connecting to PCs, set this to match the baud rate of the other host.
# SoftMPU's serial MIDI mode, for example, uses a baud rate of 38400.
#
# Values: 300-4000000 (31250*)
gpio_baud_rate = 31250
# Enable or disable software "MIDI thru" on the GPIO Tx pin.
#
# When enabled, all data received via the GPIO Rx pin will be re-transmitted
# verbatim on the Tx pin. This may be useful for debugging or for passing MIDI
# data through to another synth.
#
# Values: on, off*
gpio_thru = off
# Set the baud rate used for USB serial MIDI.
#
# The same considerations from the gpio_baud_rate setting above apply here.
#
# The range of valid baud rates may vary depending on the chipset of your USB
# serial device, so the range of values suggested below may actually be greater.
#
# Values: 9600-115200 (31250*)
usb_serial_baud_rate = 31250
# -----------------------------------------------------------------------------
# Audio options
# -----------------------------------------------------------------------------
[audio]
# Select audio output device.
#
# Values: pwm*, i2s
#
# pwm: Use the headphone jack
# hdmi: Use the HDMI port
# i2s: Use an I2S DAC
output_device = i2s
# Sample rate of audio output (Hz).
#
# mt32emu uses an internal sample rate of 32000Hz (just like the real hardware)
# which is then resampled to this value.
#
# FluidSynth renders at this sample rate directly.
#
# Values: 32000-192000 (48000*)
sample_rate = 48000
# Set audio rendering chunk size (samples).
#
# A single stereo frame of audio has two samples, and so this value is double
# the number of frames per chunk.
# The smaller the chunk size, the lower the latency, but too low a value will
# cause underruns (distortion artifacts).
#
# Latency is a function of chunk size and sample rate, for example:
# 256 samples / 2 channels / 48000Hz * 1000ms = 2.67ms of latency.
# See documentation for recommended values for various Raspberry Pi models.
#
# The minimum value varies depending on audio output device.
# For PWM, the minimum is 2, for I2S the minimum is 32.
# For HDMI, the minimum is 384, and will be rounded to the nearest multiple of
# 384.
#
# Values: 2-2048 (256*)
chunk_size = 256
# Set address (hexadecimal) of I2C DAC control interface.
#
# This will be used for the initialization sequence (see below) if enabled.
# You can find the address of your DAC by using the i2cdetect utility in Linux.
#
# Values: 00-80 (4c*)
i2c_dac_address = 4c
# Select an initialization sequence for the DAC.
#
# Some DACs require some initialization commands to be sent via I2C before they
# will produce any sound.
#
# Values: none*, pcm51xx
#
# pcm51xx: for DACs based on PCM5121 or similar (e.g. PCM5141, PCM5242)
i2c_dac_init = none
# -----------------------------------------------------------------------------
# Control options
# -----------------------------------------------------------------------------
[control]
# Set the physical control scheme.
#
# See documentation for GPIO pinouts/wiring details.
#
# Values: none*, simple_buttons, simple_encoder
#
# none: No physical controls
# simple_buttons: Simple 4-button scheme
# simple_encoder: Simple 2-button + rotary encoder scheme
scheme = simple_encoder
# Set the rotary encoder type (if used by control scheme).
#
# Different rotary encoders may complete different fractions of a Gray-code
# cycle per detent ("click").
#
# If four clicks are needed for a single movement, try "quarter".
# If two clicks are needed for a single movement, try "half".
#
# Values: quarter, half, full*
encoder_type = full
# Reverse the rotary encoder direction (if used by control scheme).
#
# Some rotary encoders may have their CLK/DAT signals swapped, resulting in
# a reversed rotation direction.
#
# Use this option to correct the direction.
#
# Values: on, off*
encoder_reversed = off
# Enable or disable the I2C MiSTer control interface.
#
# If using mt32-pi with a MiSTer FPGA system and custom hardware to interface
# with MiSTer's User Port, enable this option to allow controlling mt32-pi via
# the MiSTer's on-screen display.
#
# Values: on, off*
mister = off
# Set the timeout for switching SoundFonts (seconds).
#
# When switching SoundFonts using the physical button, there is a short delay
# before loading begins. This option allows you to set the number of seconds to
# wait before loading.
#
# Values: 0-3600 (3*)
switch_timeout = 3
# -----------------------------------------------------------------------------
# MT-32 emulator options
# -----------------------------------------------------------------------------
[mt32emu]
# Set gain factor applied to synthesizer output channels.
#
# This is independent of the master volume that can be set via MIDI SysEx or
# the volume knob.
#
# Values: 0.0-256.0 (1.0*)
gain = 1.0
# Set gain factor applied to reverb wet output channels.
#
# Values: 0.0-infinity (1.0*)
reverb_gain = 1.0
# Select quality level for the resampler.
#
# If set to none, audio output will sound wrong unless you set the sample rate
# option to 32000Hz, which is the MT-32's native sample rate.
#
# Values: none, fastest, fast, good*, best
resampler_quality = good
# Select initial MIDI channel assignment.
#
# The MT-32 uses an unusual MIDI channel assignment by default. On a real MT-32
# this is set using a button combination. Use this option to change the initial
# channel assignment on startup.
#
# Values: standard*, alternate
#
# standard: Parts 1-8 = MIDI channels 2-9, Rhythm part = MIDI channel 10
# alternate: Parts 1-8 = MIDI channels 1-8, Rhythm part = MIDI channel 10
midi_channels = standard
# Select initial ROM set to use.
#
# If multiple ROM sets are available, this option determines which set to use
# on startup. If the ROM set specified here is unavailable, the first available
# set is used instead.
#
# Values: old*, new, cm32l
rom_set = old
# -----------------------------------------------------------------------------
# SoundFont synthesizer options
# -----------------------------------------------------------------------------
[fluidsynth]
# Set the initial SoundFont to use.
#
# If multiple SoundFonts are available, this option determines which SoundFont
# to use on startup.
#
# On startup, the "soundfonts" directory is scanned for valid SoundFonts, which
# are added to a list and sorted into alphabetical order.
#
# This setting is a zero-indexed offset into that list (i.e. 0 is the first,
# 1, is the second, and so on).
#
# If the index specified is unavailable, the first available SoundFont will be
# used.
#
# Values: 0-255 (0*)
soundfont = 0
# Set the master volume gain.
#
# The default is a low value to avoid clipping when many notes are playing at
# once.
#
# The value should be a decimal value between 0.0 and 10.0. Values outside this
# range will be clamped.
#
# Values: 0.0-10.0 (0.2*)
gain = 0.2
# Set the maximum number of voices that can be played simultaneously.
#
# Depending on the complexity of your SoundFont, you may need to reduce this
# value to prevent audio buffer underruns (distortion) when playing music
# featuring lots of notes being played at once.
#
# On the other hand, Raspberry Pi 4 users may want to try raising this value as
# it has a more powerful CPU.
#
# N.B. larger file size of the SoundFont does not imply higher CPU usage.
# SoundFonts that use more real-time effects (modulators) are more likely to
# require a reduction in polyphony.
#
# Values: 1-65535 (256*)
polyphony = 256
# The following settings set the default parameters for FluidSynth's reverb and
# chorus effects.
#
# Each setting can be overridden on a per-SoundFont basis by adding extra
# sections, e.g. [fluidsynth.soundfont.x], where x is the zero-based index of
# the SoundFont. See the next section for an example.
#
# Full descriptions and valid value ranges for each setting can be found in the
# FluidSynth documentation: https://www.fluidsynth.org/api/fluidsettings.xml
reverb = on
reverb_damping = 0.0
reverb_level = 0.9
reverb_room_size = 0.2
reverb_width = 0.5
chorus = on
chorus_depth = 8.0
chorus_level = 2.0
chorus_voices = 3
chorus_speed = 0.3
# -----------------------------------------------------------------------------
# FluidSynth effects profile for SoundFont 0 (GeneralUser GS)
# -----------------------------------------------------------------------------
[fluidsynth.soundfont.0]
# The following settings are recommended for GeneralUser GS by its author.
reverb = on
reverb_damping = 0.19
reverb_level = 0.5
reverb_room_size = 0.7
reverb_width = 0.75
chorus = on
chorus_depth = 4.5
chorus_level = 0.5
chorus_voices = 3
chorus_speed = 0.35
# -----------------------------------------------------------------------------
# LCD/OLED display options
# -----------------------------------------------------------------------------
[lcd]
# Select LCD driver.
#
# Note that LCDs connected via I2C, you must also set the correct address for
# your device via the i2c_lcd_address option. Consult its datasheet, or see
# our documentation for tested models and their configurations.
#
# Values: none*, hd44780_4bit, hd44780_i2c, sh1106_i2c, ssd1306_i2c
#
# none: No LCD
# hd44780_4bit: Hitachi HD44780 or compatible (e.g. WS0010, RS0010) character
# LCD connected to GPIO pins in 4-bit mode (see documentation for
# pinout)
# hd44780_i2c: As above, but using an I2C "backpack"
# sh1106_i2c: Small I2C-based OLED graphical display (usually 1.3")
# ssd1306_i2c: Small I2C-based OLED graphical display (usually 0.96")
type = ssd1306_i2c
# Set the width of the LCD.
#
# If the display is a character display, this value is measured in characters.
# Otherwise, for a graphical display, this is measured in pixels.
#
# Note that not all dimension settings are valid; see documentation for valid
# configurations for each LCD driver.
#
# Values: 20-128 (128*)
width = 128
# Set the height of the LCD.
#
# Same characters vs. pixels considerations as for width.
#
# Values: 2-64 (32*)
height = 64
# Set address (hexadecimal) of I2C LCD.
#
# This will be used to communicate with LCDs connected via the I2C bus.
#
# Values: 00-80 (3c*) (27 para el otro)
i2c_lcd_address = 3c
# Rotate the display output (graphical LCDs only).
#
# Some graphical displays support rotation. Use this option if you need to turn
# the display around.
#
# Values: normal*, inverted
#
# normal: No rotation
# inverted: The display output is upside down
rotation = normal
# -----------------------------------------------------------------------------
# Network options
# -----------------------------------------------------------------------------
[network]
# Select the network mode.
#
# For setting your Wi-Fi SSID and encryption key, see wpa_supplicant.conf.
# Note that if using Ethernet on a Raspberry Pi 3B/3B+, USB must be enabled.
#
# off: Disable networking
# ethernet: Enable using the Ethernet interface
# wifi: Enable using the the Wi-Fi interface
#
# Values: off*, ethernet, wifi
mode = off
# Enable or disable DHCP for configuring the network.
#
# If disabled, the manual settings below will be used to configure your network
# interface instead.
#
# Values: on*, off
dhcp = on
# Manual settings for configuring the network interface.
#
# These settings will be ignored if DHCP is enabled.
#
# Values: correctly-formatted IP address/subnet mask, e.g. AAA.BBB.CCC.DDD
# (four numbers in the range 0-255 separated by periods)
ip_address = 192.168.1.100
subnet_mask = 255.255.255.0
default_gateway = 192.168.1.1
dns_server = 192.168.1.1
# Set the network hostname.
#
# Values: a valid hostname using ASCII letters 'a' to 'z', digits 0-9, and
# hyphens (*mt32-pi)
hostname = mt32-pi
# Enable or disable the RTP-MIDI/AppleMIDI server.
#
# This allows you to send MIDI data to mt32-pi over the network using macOS'
# built-in network MIDI features, or rtpMIDI by Tobias Erichsen on Windows.
#
# Values: on*, off
rtp_midi = off
Hardware and software
Bug description
Very often (but not always) when I start a MIDI track, the "Unexp. MIDI Status!" appear, although the sounds is OK. It also happens regardless being MT-32 or FluidSynth. Using a 5V to 3.3V level shifter to convert the TTL level of the sound card to 3.3V.