Wednesday, February 25, 2026

.bashrc function to toggle function keys from being media keys to being regular fn keys on linux mint


fnkeys() {
    FN="/sys/module/hid_apple/parameters/fnmode"

    if [ ! -f "$FN" ]; then
        echo "Fn control not available."
        return 1
    fi

    current=$(cat "$FN")

    if [ "$current" -eq 2 ]; then
        sudo sh -c "echo 1 > $FN"
        echo "Switched to media keys (fnmode=1)"
    else
        sudo sh -c "echo 2 > $FN"
        echo "Switched to F1–F12 keys (fnmode=2)"
    fi
}

Saturday, February 21, 2026

fasttracker2 on ipad

under:

  • quickmenu
  • core options
  • general

force output fps set to 60 stopped the stuttering

Tuesday, February 17, 2026

reaper midi looping custom action

combine these 7 actions into a macro you can trigger with a shortcut or add to a toolbar

  • Transport: Record
  • Take: Switch items to previous take
  • Take: Crop to active take in items
  • Track: Duplicate tracks
  • Item: Select all items in track
  • Item: Remove items
  • Transport: Record

Monday, February 16, 2026

you can toggle between mt32 and soundfonts using sysex in mt32-pi

mt32-pi-control on github

to find ports use aplaymidi or aconnect then use this as the info for the -p option

aplaymidi -l



-g to change to soundfont


mt32-pi-ctl -p 128:0 -g

-s to change --soundfont specify the number


mt32-pi-ctl -p 128:0 -s 1

-m to change to mt32


mt32-pi-ctl -p 128:0 -m

-b to change romset: old, new, cm32l


mt32-pi-ctl -p 128:0 -b cm32l

Saturday, February 14, 2026

making midis in reaper and playing them over udp


#!/usr/bin/env python3
import time
from socket import AF_INET, SOCK_DGRAM, socket
import mido
import threading
import signal
import sys

# MT32-Pi UDP target
UDP_HOST = "192.168.0.100"
UDP_PORT = 1999

sock = socket(AF_INET, SOCK_DGRAM)

# MIDI file path
midi_file = "/home/bweew/Desktop/midi_export.mid"

# Shared variable for dynamic CC91
dynamic_cc91 = [64] * 16  # default reverb level per channel

# Track currently sounding notes per channel
active_notes = {ch: set() for ch in range(16)}

def cc91_input():
    global dynamic_cc91
    while True:
        try:
            raw = input("Set CC91 (format: channel,value e.g., 0,80): ")
            ch, val = map(int, raw.split(','))
            if 0 <= ch < 16 and 0 <= val <= 127:
                dynamic_cc91[ch] = val
                sock.sendto(bytes([0xB0 | ch, 91, val]), (UDP_HOST, UDP_PORT))
        except Exception:
            print("Invalid input. Format: channel,value")

def send_note_offs():
    for ch, notes in active_notes.items():
        for note in notes:
            sock.sendto(bytes([0x80 | ch, note, 0]), (UDP_HOST, UDP_PORT))
    for ch in range(16):
        sock.sendto(bytes([0xB0 | ch, 123, 0]), (UDP_HOST, UDP_PORT))

def signal_handler(sig, frame):
    print("\nAborting playback, sending note-offs...")
    send_note_offs()
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

# start thread for dynamic CC91 input
threading.Thread(target=cc91_input, daemon=True).start()

print(f"Playing {midi_file} to {UDP_HOST}:{UDP_PORT}... (Ctrl-C to stop)")

while True:
    mid = mido.MidiFile(midi_file)
    active_notes = {ch: set() for ch in range(16)}  # reset notes

    for msg in mid:
        time.sleep(msg.time)

        if msg.type == 'note_on':
            sock.sendto(bytes([0x90 | msg.channel, msg.note, msg.velocity]), (UDP_HOST, UDP_PORT))
            if msg.velocity > 0:
                active_notes[msg.channel].add(msg.note)
            else:
                active_notes[msg.channel].discard(msg.note)
        elif msg.type == 'note_off':
            sock.sendto(bytes([0x80 | msg.channel, msg.note, msg.velocity]), (UDP_HOST, UDP_PORT))
            active_notes[msg.channel].discard(msg.note)
        elif msg.type == 'program_change':
            sock.sendto(bytes([0xC0 | msg.channel, msg.program]), (UDP_HOST, UDP_PORT))
        elif msg.type == 'control_change':
            val = dynamic_cc91[msg.channel] if msg.control == 91 else msg.value
            sock.sendto(bytes([0xB0 | msg.channel, msg.control, val]), (UDP_HOST, UDP_PORT))

    send_note_offs()
    print("Looping playback...")

Friday, February 13, 2026

playing soundfonts on mt32-pi over udp

my udp.py
#in the config disabled dhcp and set fixed ip
cranked the gain from 0.2 to 0.8, disabled reverb and chorus
(you need to edit the .cfg files for individual soundfonts because those will overide the main config
didn't get rtp working but udp works pretty ok.
midi over wifi can sometimes be a bit wonky but the latency isnt bad.
was hoping to make use of my other midi keyboard in my closet but the notes would get stuck


#!/usr/bin/env python3

from signal import SIGINT, signal
from socket import AF_INET, SOCK_DGRAM, socket
from threading import Event

from rtmidi import MidiIn

UDP_HOST = "192.168.0.100"
UDP_PORT = 1999
MIDI_PORT_NAME = "mt32-pi UDP socket"

sock = socket(AF_INET, SOCK_DGRAM)
midiin = MidiIn()
midiin.open_virtual_port(MIDI_PORT_NAME)

signal(SIGINT, lambda *_: exit(1))

print(
    f"Listening for MIDI on port '{MIDI_PORT_NAME}' and sending to"
    f" {UDP_HOST}:{UDP_PORT} (Ctrl-C to exit)..."
)

midiin.ignore_types(False, False, False)
midiin.set_callback(lambda msg, _: sock.sendto(bytes(msg[0]), (UDP_HOST, UDP_PORT)))
Event().wait()

Sunday, February 8, 2026

fluidsynth for octamed

you can make midi templates for sunvox and fl studio also
here i use linux mint autostart to run the bash script
and run the render command
- path must be like /home/user/Desktop/ not
~/Desktop/
also drag and drop wont work
it will try to open in celluloid so you must type it out.


#fluidsynth from terminal
fluidsynth -is -p "FluidSynth-GS" -g 0.7 ~/Documents/sf2/GeneralUser-GS.sf2

#bash for autostart
#!/bin/bash
gnome-terminal -- bash -c 'fluidsynth -is -p "FluidSynth-GS" -g 0.7 ~/Documents/sf2/GeneralUser-GS.sf2; exec bash'


#rendering
read -e -p "MIDI file path: " f; f=${f%\"}; f=${f#\"}; fluidsynth -is -p "FluidSynth-GS" -g 0.7 -R 0 -C 0 -F ~/Desktop/"$(basename "$f" .mid)".wav ~/Documents/sf2/GeneralUser-GS.sf2 "$f"; echo "Rendered ~/Desktop/$(basename "$f" .mid).wav"

# using jack instead for cadence to record in audacity
#!/bin/bash
gnome-terminal -- bash -c 'fluidsynth -a jack -m alsa_seq -is -p "FluidSynth-GS" -g 0.7 ~/Documents/sf2/GeneralUser-GS.sf2; exec bash'

# optional monitoring to find port use jack_lsp
jack_connect "FluidSynth-GS:audio_L" "system:playback_1"
jack_connect "FluidSynth-GS:audio_R" "system:playback_2"

# jack and monitoring
#!/bin/bash
gnome-terminal -- bash -c '
fluidsynth -a jack -m alsa_seq -is -p "FluidSynth-GS" -g 0.7 ~/Documents/sf2/GeneralUser-GS.sf2 &
until jack_lsp | grep -q "fluidsynth:left"; do sleep 0.5; done
jack_connect fluidsynth:left system:playback_1
jack_connect fluidsynth:right system:playback_2
wait
exec bash'

Wednesday, February 4, 2026

Tuesday, February 3, 2026

samplerbox raspberry pi

samplerbox

program your own screenless rompler. write is disabled on the os making it safe for the sd to be undamaged by unplugging. (idk about the usb with the sounds though? I guess its fine as long as your not in the middle of transferring files)

defle distilled

made a cheatsheet for learning deflemask.

  • distilled 53 pages down to 1 front and back.

dropbox link to pdf

Monday, February 2, 2026

deflemask

running deflemask on ipad with a logitech k480
the keyboard os modes matter bigtime!
the 2 modes: pc, i.

in I (ios mode)

  • cmd h for home, cmd tab for switching apps

in pc mode

  • fn left / right = home / end
  • fn up / down = pgup pgdown

turn off follow

in the right panel so you can use f7 to play from line
otherwise it keeps going. ESSENTIAL!

  • ctrl 123456789 mute channels
  • ctrl left / right switch tracks
  • ctrl w/e shrink expand
  • ctr b = paste and mix (ctrl v is regular paste)
  • switching octave is done on screen because /* is numpad only
  • note off is tab
  • interpolate = ctrl i
  • transposing = ctrl f1/f2,f3/f4

work from the top

instead of working from 0-64 top down work horizontally in 16 line chunks to make use of the f5 playback and f7 playbacks for the best of both worlds. copy and paste each 1/4 pattern horizontally and ctrl 123456789 to mute the previous until you complete all four quarters of a pattern to re assemble them.

vitracker a tracker with vim bindings?

vitracker releases on github

fasttracker2 as a vst3 plugin

juho's github
has a new xm2 format supporting curved envelopes.