Saturday, June 27, 2026

mastersystem and nes on gba

sms advance

pocketnes

that means you can probably run
risa and smsggdj on the gba with these emulators.

risa tracker - a nes tracker

risa tracker

sunvox zt-2020

arduino blog post. seems fascinating earthbound objects video is off youtube I can't find it.

Friday, June 26, 2026

smsggdj by littlescale

sega mastersystem / gamegear tracker like lsdj smsggdj github releases

Thursday, June 18, 2026

joy2midi

audi etoffe's joy2midi script

for sending midi with gamepads

Sunday, June 14, 2026

lsdj wave cruncher

defensemech's blog post about it

patch in your own wavetables for lsdj. lets you do more as a wavechannel than as a sample kit.

Saturday, June 13, 2026

run multiple lsdj instances in the browser

lsdj hd

only works on desktop because you need to drag the roms in.

Friday, June 12, 2026

pico translating usbmidi to ps2 keyboard for lsdj

youtube

learn lsdj github

better than the manual for having a darkmode
learnlsdj.github

midi to lsdj js library

git

nvm it doesnt convert to a lsdjsng it just tells you how many chains and patterns to manually draw it in

arduinoboy max editor use 5.0.8 not 9

9 runs like garbage on linux and locks up use an old version instead

max runtime 5.0.8 for windows the arduinoboy max editor

Thursday, June 11, 2026

gameboy link cable breakout pcb board for 2$

palmr's blog post about it. github with the gerbers order it from oshpark

solder on some 1x6 m, f, or double male headers
I think il be able to make an arduinoboy from a promicro with just this and a link cable.
tempted to get the hobbychop one for 70 cad but its alot of money.
they have a breakout for 6$ but its US I think with tarrifs and shipping its 20$ :(
looking at cutting up my link cable and crimping on some dupont M connectors.

Tuesday, June 9, 2026

droid pad

use android tablet like a gamepad to control linux using websockets
or ble droidpad companion

could trigger keyboard shortcuts

savrepulse's lsdj tutorial

sabers yt

spessasynth web soundfont exitor

spessasus soundfont editor github
cant really use on phone but sounds like it could be interesting il have to check it out deeper. looking at android theres not any options i know of other than maybe somehow running polyphone in a linux emulator?

Monday, June 8, 2026

link to the lsdj manual

lsdj manual

getting lsd working on lenovo m8

  • retroarch with gambatte core for lsdj. had trouble showing blank directory with some file permission sanboxing. put the rom in documents and use the

  • lgpt in ppsspp shows a black screen. you have to go into settingd and change the rendering resolution every time if its 1x set it to 2X. it resets every time

Sunday, June 7, 2026

FL studio getting multiple plugins to show at once

R click in the corner and set plugins to detatched
in settings: general, uncheck auto select linked modules

lsdj patcher

lets you load custom fonts and edit colour pallates. for fonts the y2k is classic but I like the DOS, Protracker, and Renoise themes for custom. for Colour pallate I went with the solarized dark and modded it to be more greyscale and with a dusty yellow cursor instead of purple.
it exports songs as lsdprj. For lsdjsng export I think I need to use retroplug instead.

best gb emulator on linux mint 22.2

gearboy on github

went with v 3.75 ubuntu 22.04 version because sdl3 wasn't found on the lastest build.
mgba sound quality sucks, retroplug is ok but the overhead of it running within wine cranks my fan. This is the best emulator on linux iv've foudn so far. was thinking about getting gambatte but its only available on sourceforge and i don't trust like that.

lsdj converter in browser

defensemechs lsdj song to midi

I use retroplug on my computer to open lsdj songs and export .lsdjsng because it doesnt work with .sav alone

the lsdj wiki

on linux mint the web apps tool lets you launch websites like apps.

is LSDJ worth in in 2026?

playpms gas therapy

3 things got me feeling like a time traveller from the year 2000.
- ska
- microkorg
- lsdj
We have alot more options now that didn't exist back then.
I didn't have a gameboy back then. I always wanted to get into lsdj.
the costs add up.
i got a free gba with no power adapter and a swollen battery.
- flashcart 23$
- battery 10$
- charge cable 7$ + linkcable
40ish bucks just to get lsdj running.
but I want midi out. lsdj patches lets you load lofi samples but that sucks and then gba
needs another audio dongle to get 3.5mm out.
the idea of a portable handheld battery powered tracker gets less portable when a million dongles and power supplys get reqired.
the idea of repurpusing a game console for music doesn't make sense when all these costs pile up.
2 options to get midi:
- arduinoboy prebuilt 70$
- arduino leonardo + midisheild on ali 20$
could potentially save 50$
- probably have to edit the arduinoboy firmware to get the pins correct
- have to cut up a link cable (hobbychops arduinoboy comes with edge connectors)
-build a case to mechanically support the custom cable so it doesn't rip off some things that make it easeir to deal with

-gearboy
-lsdj patcher
- lsdj song to midi conversion tool to get midi out
- retroplug for audio syncing route.
wish retroplug could do it all for me but on linux its not working idk why I cant get he midi out
gearboy + the midi conversion tool is enough for me to want to get gba running again. dont need to shell out 70$ for the arduino boy

Saturday, June 6, 2026

sfizz apt repo for raspberry pi

echo 'deb http://download.opensuse.org/repositories/home:/sfztools:/sfizz/Raspbian_12/ /' | sudo tee /etc/apt/sources.list.d/home:sfztools:sfizz.list
curl -fsSL https://download.opensuse.org/repositories/home:sfztools:sfizz/Raspbian_12/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/home_sfztools_sfizz.gpg > /dev/null
sudo apt update
sudo apt install sfizz

link to sfizz repo incase it gets updated

Friday, June 5, 2026

pi 3 hifi hat i3 config auto assigned workspaces for fluidsynth and renoise


exec --no-startup-id i3-msg 'workspace1; exec renoise'
exec --no-startup-id i3-msg 'workspace2; exec lxterminal -e ~Documents/sf2/fluid.sh'

set cadence to start jack on login so fluidsynth can run properly
jack bridges have alsa to pulse to jack


  # Update software sources
sudo apt-get update

# Install required dependencies if needed
sudo apt-get install gpgv wget

# Download package file
wget https://launchpad.net/~kxstudio-debian/+archive/kxstudio/+files/kxstudio-repos_11.2.0_all.deb

# Install it
sudo dpkg -i kxstudio-repos_11.2.0_all.deb
  

Thursday, June 4, 2026

spotpear pcm5122 i2s dac install instructions

spotpears website

my fluidsynth alsa setup with m-vave bt and pico


gnome-terminal -- bash -c '
fluidsynth -C0 -R0 -l -a alsa -m alsa_seq -is -p "FluidSynth-GS" \
-o synth.polyphony=64 \
~/Documents/sf2/GeneralUser-GS.sf2 &

until aconnect -l | grep -q "FluidSynth-GS"; do sleep 0.5; done

aconnect "SINCO" "FluidSynth-GS" 2>/dev/null
aconnect "Pico"  "FluidSynth-GS" 2>/dev/null

wait
exec bash
'

my pico sends msb lsb program changes to switch sounds. the m-vave bt im using with my microkorg to play soundfonts.
this script lets me auto connect everything

wx midi

fluidsynth with rtp midi for raspberry pi

Sunday, May 31, 2026

clarinova hex midi messages

yamaha clavinova clp-820 functions

  • f7 3 is the function for
    local control disabling

  • f7 1 and 2 are midi send/ receive channels

  • f2 1 sets temperament
    1 is Equal
    2 maj
    3 min
    4 pythagorean
    5 meantone
    6 werkmeister
    7 kirnberger

Friday, May 29, 2026

midi hex channel message for drums

in loopy pro ndercustom midi messages
to pull up the drums:
B0 00 78 B0 20 00 C0 00

i forgot the last 00 at the end which is why it didn't work before.

Instrument MIDI Command

piano B0 00 00 B0 20 00 C0 01
bass B0 00 00 B0 20 00 C0 21
jazz-gt B0 00 00 B0 20 00 C0 1A

brass B0 00 00 B0 20 00 C0 3d
strings B0 00 00 B0 20 00 C0 30
tonewheelorg B0 00 00 B0 20 00 C0 10
clav B0 00 00 B0 20 00 C0 07

trombone B0 00 00 B0 20 00 C0 39
mute gt B0 00 00 B0 20 00 C0 1c
choir B0 00 00 B0 20 00 C0 34
barisax B0 00 00 B0 20 00 C0 43

Thursday, May 28, 2026

yamaha cbx-k1 stuck notes fix

press shift + tempo + 0 + enter to disable the external midi clock
had a similar problem with microkorg giving errors when trying to send patches over midi cable. I think it just sends too much data at once and gets garbled so this reduces that significantly.

Wednesday, May 27, 2026

Monday, May 25, 2026

digiwaves decent sampler

decent sampler inst on dropbox

made an insturment for the decentsampler vst that can also run on ios. Its 64 digital waves you can swap between using the modwheel. If you rename the .dslibrary file to zip and extract there is a .sfz mapping which uses the same samples but maps them differently. The soundfont has no UI but its got a lowpass filter and amp and filter egs that correspond to the mk. The sfz is monophonic while the decentsampler patch is polyhonic.

regex to get the sample name only from sfz


^.*/

this simple regex works in mousepad

Friday, May 22, 2026

Microkorg Lua Synth Definition For Renoise Guru Plugin

Guru lets you load presaved mappings for controlling hardware synths
so you dont need to reinvent the wheel and map everything out each time
on linux the scripts go in somewhere in /.config/renoise/scripts/tools
The Renoise Tool Guru


return SynthDefinition {
    id = "korg_microkorg",
    name = "Microkorg",
    author = "Bweew",

    Section {

        Group {
            name = "Filter",

            Parameter { id="filter_type", name="Type", type="cc", number=83 },
            Parameter { id="cutoff", name="Cutoff", type="cc", number=74 },
            Parameter { id="resonance", name="Resonance", type="cc", number=71 },
            Parameter { id="filter_eg_int", name="Filt EG", type="cc", number=79 },
            Parameter { id="kbd_track", name="KBD Track", type="cc", number=85 }
        },

        Group {
            name = "Filter EG",

            Parameter { id="feg_attack", name="Attack", type="cc", number=23 },
            Parameter { id="feg_decay", name="Decay", type="cc", number=24 },
            Parameter { id="feg_sustain", name="Sustain", type="cc", number=25 },
            Parameter { id="feg_release", name="Release", type="cc", number=26 }
        },

        Group {
            name = "Amp EG",

            Parameter { id="aeg_attack", name="Attack", type="cc", number=73 },
            Parameter { id="aeg_decay", name="Decay", type="cc", number=75 },
            Parameter { id="aeg_sustain", name="Sustain", type="cc", number=70 },
            Parameter { id="aeg_release", name="Release", type="cc", number=72 }
        },

        Group {
            name = "Delay",

            Parameter { id="delay_time", name="Time", type="cc", number=13 },
            Parameter { id="delay_depth", name="Depth", type="cc", number=94 }
        },

        Group {
            name = "Mod FX",

            Parameter { id="mod_speed", name="Speed", type="cc", number=12 },
            Parameter { id="mod_depth", name="Depth", type="cc", number=93 }
        },

        Group {
            name = "Mixer",

            Parameter { id="osc1_level", name="Osc1 Level", type="cc", number=20 },
            Parameter { id="osc2_level", name="Osc2 Level", type="cc", number=21 },
            Parameter { id="noise_level", name="Noise Level", type="cc", number=22 }
        },

        Group {
            name = "Osc 1",

            Parameter { id="osc1_wave", name="Wave", type="cc", number=77 },
            Parameter { id="osc1_ctrl1", name="Ctrl 1", type="cc", number=77 },
            Parameter { id="osc1_ctrl2", name="Ctrl 2", type="cc", number=15 }
        },

        Group {
            name = "Osc 2",

            Parameter { id="osc2_wave", name="Wave", type="cc", number=78 },
            Parameter { id="osc2_mod", name="Osc Mod", type="cc", number=82 },
            Parameter { id="osc2_semi", name="Semitone", type="cc", number=18 },
            Parameter { id="osc2_tune", name="Tune", type="cc", number=19 }
        },

        Group {
            name = "LFO 1",

            Parameter { id="lfo1_wave", name="Wave", type="cc", number=87 },
            Parameter { id="lfo1_freq", name="Frequency", type="cc", number=27 }
        },

        Group {
            name = "LFO 2",

            Parameter { id="lfo2_wave", name="Wave", type="cc", number=88 },
            Parameter { id="lfo2_freq", name="Frequency", type="cc", number=76 }
        },

        Group {
            name = "V Patch",

            Parameter { id="vpatch1", name="P1 Int", type="cc", number=28 },
            Parameter { id="vpatch2", name="P2 Int", type="cc", number=29 },
            Parameter { id="vpatch3", name="P3 Int", type="cc", number=30 },
            Parameter { id="vpatch4", name="P4 Int", type="cc", number=31 }
        }

    }
}

Saturday, May 16, 2026

Renoise Midi Hardware Sampler Tool

Midi Hardware Sampler Tool

been using this to sample the microkorg into renoise

Thursday, May 14, 2026

Microkorg Dashboard

Using the Dashboard Plugin In FL studio 10 I made a control surface for the Microkorg that has everything on a single page unlike the fruity midi out plugin that splits everything across several pages. I like it all on one because I find it easier to see everything and map them to hardware controllers or automate. Dropbox link

Thursday, April 9, 2026

Giant Steps

Key Giant Steps
G B D7 | G Bb7 | Eb | Am7 D7 | G Bb7 | Eb F#7 | B | Fm7 Bb7 | Eb | Am7 D7 | G | C#m7 F#7 | B | Fm7 Bb7 | Eb | C#m7 F#7
Ab C Eb7 | Ab B7 | E | Bbm7 Eb7 | Ab B7 | E G7 | C | F#m7 B7 | E | Bbm7 Eb7 | Ab | Dm7 G7 | C | F#m7 B7 | E | Dm7 G7
A C# E7 | A C7 | F | Bm7 E7 | A C7 | F G#7 | C# | Gm7 C7 | F | Bm7 E7 | A | D#m7 G#7 | C# | Gm7 C7 | F | D#m7 G#7
Bb D F7 | Bb Db7 | Gb | Cm7 F7 | Bb Db7 | Gb A7 | D | Abm7 Db7 | Gb | Cm7 F7 | Bb | Em7 A7 | D | Abm7 Db7 | Gb | Em7 A7
B D# F#7 | B D7 | G | C#m7 F#7 | B D7 | G A#7 | D# | Am7 D7 | G | C#m7 F#7 | B | Fm7 A#7 | D# | Am7 D7 | G | Fm7 A#7
C E G7 | C Eb7 | Ab | Dm7 G7 | C Eb7 | Ab B7 | E | Bbm7 Eb7 | Ab | Dm7 G7 | C | F#m7 B7 | E | Bbm7 Eb7 | Ab | F#m7 B7
Db F Ab7 | Db E7 | A | Ebm7 Ab7 | Db E7 | A C7 | F | Bm7 E7 | A | Ebm7 Ab7 | Db | Gm7 C7 | F | Bm7 E7 | A | Gm7 C7
D F# A7 | D F7 | Bb | Em7 A7 | D F7 | Bb C#7 | F# | Cm7 F7 | Bb | Em7 A7 | D | G#m7 C#7 | F# | Cm7 F7 | Bb | G#m7 C#7
Eb G Bb7 | Eb Gb7 | Bbm | Fm7 Bb7 | Eb Gb7 | Bbm D7 | G | C#m7 F#7 | Bbm | Fm7 Bb7 | Eb | Am7 D7 | G | C#m7 F#7 | Bbm | Am7 D7
E G# B7 | E G7 | C | F#m7 B7 | E G7 | C D#7 | G# | Dm7 G7 | C | F#m7 B7 | E | A#m7 D#7 | G# | Dm7 G7 | C | A#m7 D#7
F A C7 | F Ab7 | Db | Gm7 C7 | F Ab7 | Db E7 | A | Ebm7 Ab7 | Db | Gm7 C7 | F | Bm7 E7 | A | Ebm7 Ab7 | Db | Bm7 E7
F# A# C#7 | F# A7 | D | G#m7 C#7 | F# A7 | D F7 | A# | Em7 A7 | D | G#m7 C#7 | F# | Cm7 F7 | A# | Em7 A7 | D | Cm7 F7

some dx7 banks I put together

dx7 sysex patches dropbox link

Monday, March 9, 2026

deflemask triplets in 12 lines instead of 8

with a pattern length of 48 with each beat being 4 lines
set the speeds both to 2: 09-02, and 0F-02 to align with 8th note quarter notes

deflemask triplets using speed commands

in 2 columns set 09 01 and 0f 01
then to reset back 09 03 0f 03
that lets you sequence like regular quarter notes across 8 lines

Thursday, March 5, 2026

Timing Systems in the History of Music Trackers

In the history of music trackers (especially on early computers like the Commodore 64 and Commodore Amiga), timing systems evolved because different hardware offered different ways to measure time. Terms like PPQN, CIA, VBlank, NTSC, PAL, and LPB refer to how trackers scheduled musical events such as notes and effects.


1. VBlank Timing (Early Trackers)

VBlank = Vertical Blank interrupt

Early trackers synchronized playback with the screen refresh interrupt.

  • The video chip triggers an interrupt every frame.
  • The music routine runs once per frame.

Frame rates depended on TV standards

  • PAL: 50 Hz (50 interrupts per second)
  • NTSC: ~60 Hz (59.94 interrupts per second)

These standards come from analog television systems used by machines like the Commodore 64 and early Amiga 500.

Effect on tracker timing

A tracker row advanced every N frames.

Example (classic Amiga trackers):


Speed = 6
PAL 50 Hz

Row duration:
6 frames / 50 Hz = 120 ms per row

Pros

  • Simple
  • Stable with graphics

Cons

  • Different speed on PAL vs NTSC
  • Limited timing resolution

This system was used in early trackers such as Soundtracker (1987).


2. CIA Timer Timing (Amiga Precision Timing)

The Commodore Amiga had CIA chips (Complex Interface Adapters) with programmable timers.

Later trackers used CIA Timer A instead of VBlank interrupts.

Why?

CIA timers allow arbitrary interrupt rates, independent of video refresh.

Example:


Timer frequency ≈ 709379 Hz / divider

This allowed:

  • More precise BPM
  • Same playback speed on PAL and NTSC

Trackers such as ProTracker used this technique.

Pros

  • Hardware accurate timing
  • Independent from video
  • Higher precision

Cons

  • Slight CPU overhead
  • Required careful hardware programming

3. LPB (Lines Per Beat)

LPB = Lines Per Beat

This concept appeared in later trackers during the PC era.

Trackers such as FastTracker II and Impulse Tracker separated:

  • tempo (BPM)
  • pattern resolution

LPB defines how many rows equal one beat.

Example:


BPM = 125
LPB = 4

Meaning:

  • 4 rows per beat
  • 16 rows per bar (4/4)

This makes timing more musical and flexible.


4. PPQN (Pulses Per Quarter Note)

PPQN = Pulses Per Quarter Note

This timing concept comes from MIDI sequencing rather than trackers.

Common MIDI timing resolutions:


24 PPQN
96 PPQN
480 PPQN
960 PPQN

Higher PPQN values give finer timing resolution.

Later tracker-inspired software and modern trackers adopted similar high-resolution internal clocks.

Examples include modern trackers and DAWs such as Renoise and OpenMPT.


5. Relationship Between These Systems

System Used In Resolution Hardware Dependence
VBlank early Amiga / C64 trackers low tied to video
PAL / NTSC video standards defines frame rate hardware
CIA timer later Amiga trackers medium hardware timer
LPB PC trackers high software
PPQN MIDI / DAWs very high software

6. Typical Classic Tracker Timing Formula

For ProTracker-style trackers:


row_time = speed × tick_time

Where:


tick_time = 2.5 / BPM seconds

Example:


speed = 6
BPM = 125

Tick time:


2.5 / 125 = 0.02 s

Row time:


6 × 0.02 = 0.12 s

This produces the famous 125 BPM / speed 6 groove used in many Amiga modules.


7. Historical Timeline

1980s

  • VBlank timing
  • PAL/NTSC differences
  • Soundtracker era

Early 1990s

  • CIA timer timing
  • ProTracker era

Mid 1990s

  • PC trackers adopt BPM + speed system

Late 1990s

  • LPB introduced

2000s+

  • PPQN-style internal clocks

Summary

  • PAL / NTSC → video refresh standards
  • VBlank → music tick tied to screen frame
  • CIA timer → programmable hardware timer interrupts
  • LPB → musical resolution (rows per beat)
  • PPQN → MIDI timing resolution

understaning clock speeds in sunvox and deflemask

deflemask default is ntsc basetime 1 = 150bpm
sunvox default is 125 6tpl
- to match deflemask to sunvox:
set to pal, increase basetime from 1 to 2
- to match sunvox to defle:
lower tpl from 6 to 3 and increase bpm to 150

for quarter note (8 lines) to be equivalent
sunvox at 6tpl is half the speed of deflemask pal basetime 1.
increasing basetime lowers the speed
while decreasing the tpl increases the speed

Lumafusion shortcuts

triplet tuplets in trackers

  • 32 lines
    half note triplet
    00, 11, 21

  • 16 lines
    quarter note triplet
    00, 05, 11

  • 8 lines
    eighth note triplet
    00, 03, 05

  • 4 lines
    sixteenth note triplet
    00, 01, 03

  • 64 lines
    1 bar triplet
    00, 21, 43

1/16 note | 4 lines | 00 01 03
1/8 note | 8 lines | 00 03 05
1/4 note | 16 lines | 00 05 11
1/2 note | 32 lines | 00 11 21
1 bar | 64 lines | 00 21 43

Monday, March 2, 2026

converting long samples to 16bit 8000khz for deflemask using sox


for f in *.wav; do sox "$f" -r 8000 -e signed-integer -b 16 "${f%.wav}_16bit.wav"; done

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.

Tuesday, January 27, 2026

jsfx control panel for the xg plugin

syxg control panel on github

splitting files for compression for fat32

the way to go would have been to use gparted to format to exfat
fat32 has a 4gb file limitation


// for rar
rar a -r -v3900m archive.rar /path/to/folder/

// for 7zip
7z a -v3900m archive.7z /path/to/folder/

// for zip
zip -r -s 3900m archive.zip /path/to/folder/

Sunday, January 18, 2026

sunchop - a chopper for sunvox

sunchop on the sunvox forum eufex made this in pixilang. the demo vid said single sampler pitch mapping is broken but it does work for individual samples for each chop. (eggsem tool in renoise had the same problem) I prefer xrns2mod because then i can get then all self contained in one insturment.

The xrns2mod tool didn't work o. my other computer though so this is when it would come in handy.

Thursday, January 15, 2026

best way to make drum kits in subvox

xrns2mod tool

running the cli version in a vm on windows actually is great.
The linux version kept saying my project was too new or something and the renoise tool version would render a blank xm.

My old method of building kits was to use openmpt to create xis out of sfzs made in renoise of groups of samples but the tuning would be off.

the eggsem tool to convert xrns to xm works at getting the pattern data and simple 1 shot insturments but it would mangle pitches on multisampled ones so the xrns2mod cli tool is my new go to method for now.

Deflemask chip tracking strategies

It lacks some important keyboard shortcuts i use all the time in Renoise because of this i've mostly used it as a sound module for ym2612 sounds sampling it and not dealing with the sequencer but i've figured out a few tricks recently to get around that.

no f9-f12 jump 1/4 way through or play from line and return. the play from line in Deflemask just keeps going from where you left off and play pattern always jumps to the start.

my work around is do each 16 ticks on its own channel and mute each one as i move 1/4 across.
this feels similar to using block loop in Renoise.

Another alternative is to use pattern break commands to jump to line zero. it reminds me of clipping in as you climb higher up a wall.

Saturday, January 10, 2026

how to move nested wavs

Downloaded some samples that came packed into separate folders. This is annoying because there is only 1 wav in each folder making it a hassle to browse.

heres the fix:

mv -n */*.wav .

then to remove the folders

rmdir */

xm export from renoise

eggsemm

xrns2mod required something called bassmidi library which needed a license to run? tried and gave up this one actually worked for me but the pitches get screwed up in multi samples. still way better than nothing.

Sunday, January 4, 2026

sunvox midi automations

in the cc column it starts at 80
so cc1 is actually 81 (also its in hex).

  • 91 for reverb is db
  • 74 brightness (cutoff)is ca
  • 71 timbre (res) is c7

the interpolator tool can quickly create ramps for filter sweeps at a set interval like a tempo synced lfo

Saturday, January 3, 2026

ringmod sidechaining easy and free

kilohearts compactor makes that nee ring mod side chaining technique easy

Friday, January 2, 2026

chopping samples in sunvox

Easily miss this setting because its hidden in the edit menu under misc as resample new length. set the number of lines to the end of your sample and it will adjust the pitch to play out to that length.

Then you can use the 7 effect to chop on offsets of 8000
snare on 4000 etc..

yt video on choppage

making kits in sunvox

  • add your samples
  • connect a multisynth
  • options 75 7F

that sets multisynth to c5 and divides output midi note by number of inputs to spread the sounds across the keys. loading sounds it's probably easiest to use milkytracker to create .xi files and save them as meta modules.

yt link to vid explaining