Friday, October 2, 2026

transient shaper vst - transpire

I like this one because its 32bit so it works on my old fl studio without gui issues

transpire - sonic anomaly

aaliyah - more than a woman uses the eb byzantine scale

bmaj7 emaj7 eb7 b9 and b13 as well as major 7th can be used as passing tones like in a bebop scale sometimes sharp9 is in the melody

Passion, instant
Sweat beads, fill me
Cupid's shot me
My heartbeat's racing
Tempt me (tempt me), drive me (drive me)
Feels so exciting
Thought of highly
It's yours entirely
I'll be
I'll be more than a lover
More than a woman
More than your others (I'll be)
I'll be more than a lover
More than a woman
More than enough for you (I'll be)
I'll more than a lover
More than a woman
Even more under covers (I'll be more)
I'll be more than a lover
More than a woman
More than enough for you
Midnight grindin'
Heartrate's climbin'
You go (you go)
I go
'Cause we share pillows
Chase me, leave me
There's still no separating
Morning massages
With new bones in your closet
I'll be
I'll be more than a lover
More than a woman
More than your others (I said I'll be)
I'll be more than a lover
More than a woman
More than enough for you (I'll be more)
I'll be more than a lover (more)
More than a woman
Even more under covers (I'm gonna be more)
I'll be more than a lover
More than a woman
More than enough for you
I don't think you're ready
(I don't think you're ready for this thing)
For this thing
(I don't think you're ready for this thing)
You're not ready, no, no (this thing)
(I don't think you're ready for this thing)
This thing, this thing
(I don't think you're ready for this thing)
Constant pleasures
No scale can measure
Secret treasures
Keeps on getting better, yeah
Do you wanna roll with me?
We can go to foreign lands
Your hand in my hand
Do you wanna ride with me?
We can be like Bonnie and Clyde
Me by your side
I'll be more than a lover
More than a woman
More than your others
I'll be more than a lover
More than a woman
More than enough for you (I'll be more)
More than a lover
More than a woman
Even more under covers
I'll be more than a lover
More than a woman
More than enough for you

Thursday, October 1, 2026

merging pdfs sorted alphabetically


pdfunite $(find . -maxdepth 1 -type f -name '*.pdf' ! -name 'merged.pdf' | sort) merged.pdf

Friday, September 11, 2026

Best Free Fx Plugins 2026

put down production for a while. digging through the pile these gems from tiagolr, baconpaul, and blepfx stand out.


Tiagolr

time 12
gate12 filtr

Other Tiagolr Plugins I haven't tried yet that look interesting

quadmorph filter qdelay tetra op - 4op fm wavetable synth

Blepfx

filtrr - the best filter

Baconpaul

two-filters

#the jsfx version of tiagolr for reaper
https://raw.githubusercontent.com/tiagolr/tilr_jsfx/master/index.xml

Wednesday, September 9, 2026

gba gsm audio player improved

this version allows album art.
I think it also allows you to drop in wavs? the other music player required sox conversation and I always forget the command maybe this will be easier.

gsm player

m8 tracker is ios native

40$ cad
been thinking about picking up
amber opl instead but its ipad only and I already have deflemask.

gba slideshow maker for windows

gba slideshow from gameboy advance.net

Friday, September 4, 2026

Midi Program Changer

Midi Program Changer github

Made this in python to change programs with the plus and minus keys on a qwerty keyboard. The easiest way to use is run the linux x86 build on github that I packaged together with pyinstall so you dont need to manually deal with dependencies. Otherwise if your own win/mac heres the python.


#!/usr/bin/env python3

import tkinter as tk
from tkinter import ttk, messagebox

import mido
from pynput import keyboard


# ============================================================
# GENERAL MIDI INSTRUMENTS
# ============================================================

GM_INSTRUMENTS = [
    "Acoustic Grand Piano",
    "Bright Acoustic Piano",
    "Electric Grand Piano",
    "Honky-tonk Piano",
    "Electric Piano 1",
    "Electric Piano 2",
    "Harpsichord",
    "Clavinet",
    "Celesta",
    "Glockenspiel",
    "Music Box",
    "Vibraphone",
    "Marimba",
    "Xylophone",
    "Tubular Bells",
    "Dulcimer",
    "Drawbar Organ",
    "Percussive Organ",
    "Rock Organ",
    "Church Organ",
    "Reed Organ",
    "Accordion",
    "Harmonica",
    "Tango Accordion",
    "Acoustic Guitar (nylon)",
    "Acoustic Guitar (steel)",
    "Electric Guitar (jazz)",
    "Electric Guitar (clean)",
    "Electric Guitar (muted)",
    "Overdriven Guitar",
    "Distortion Guitar",
    "Guitar Harmonics",
    "Acoustic Bass",
    "Electric Bass (finger)",
    "Electric Bass (pick)",
    "Fretless Bass",
    "Slap Bass 1",
    "Slap Bass 2",
    "Synth Bass 1",
    "Synth Bass 2",
    "Violin",
    "Viola",
    "Cello",
    "Contrabass",
    "Tremolo Strings",
    "Pizzicato Strings",
    "Orchestral Harp",
    "Timpani",
    "String Ensemble 1",
    "String Ensemble 2",
    "SynthStrings 1",
    "SynthStrings 2",
    "Choir Aahs",
    "Voice Oohs",
    "Synth Voice",
    "Orchestra Hit",
    "Trumpet",
    "Trombone",
    "Tuba",
    "Muted Trumpet",
    "French Horn",
    "Brass Section",
    "SynthBrass 1",
    "SynthBrass 2",
    "Soprano Sax",
    "Alto Sax",
    "Tenor Sax",
    "Baritone Sax",
    "Oboe",
    "English Horn",
    "Bassoon",
    "Clarinet",
    "Piccolo",
    "Flute",
    "Recorder",
    "Pan Flute",
    "Blown Bottle",
    "Shakuhachi",
    "Whistle",
    "Ocarina",
    "Lead 1 (square)",
    "Lead 2 (sawtooth)",
    "Lead 3 (calliope)",
    "Lead 4 (chiff)",
    "Lead 5 (charang)",
    "Lead 6 (voice)",
    "Lead 7 (fifths)",
    "Lead 8 (bass + lead)",
    "Pad 1 (new age)",
    "Pad 2 (warm)",
    "Pad 3 (polysynth)",
    "Pad 4 (choir)",
    "Pad 5 (bowed)",
    "Pad 6 (metallic)",
    "Pad 7 (halo)",
    "Pad 8 (sweep)",
    "FX 1 (rain)",
    "FX 2 (soundtrack)",
    "FX 3 (crystal)",
    "FX 4 (atmosphere)",
    "FX 5 (brightness)",
    "FX 6 (goblins)",
    "FX 7 (echoes)",
    "FX 8 (sci-fi)",
    "Sitar",
    "Banjo",
    "Shamisen",
    "Koto",
    "Kalimba",
    "Bagpipe",
    "Fiddle",
    "Shanai",
    "Tinkle Bell",
    "Agogo",
    "Steel Drums",
    "Woodblock",
    "Taiko Drum",
    "Melodic Tom",
    "Synth Drum",
    "Reverse Cymbal",
    "Guitar Fret Noise",
    "Breath Noise",
    "Seashore",
    "Bird Tweet",
    "Telephone Ring",
    "Helicopter",
    "Applause",
    "Gunshot",
]


# ============================================================
# CHANNEL 10 DRUM KITS
# ============================================================

DRUM_KITS = {
    1: "Standard Drum Kit",
    9: "Room Drum Kit",
    17: "Power Drum Kit",
    25: "Electric Drum Kit",
    26: "Rap TR808 Drums",
    33: "Jazz Drum Kit",
    41: "Brush Kit",
}

DRUM_PROGRAMS = list(DRUM_KITS.keys())


# ============================================================
# MIDI CC
# ============================================================

REVERB_CC = 91


# ============================================================
# APPLICATION
# ============================================================

class MidiProgramChanger:

    def __init__(self, root):

        self.root = root
        self.root.title("MIDI Program Changer")

        self.port = None
        self.keyboard_listener = None

        self.program = 1
        self.channel = 1

        self.reverb = 0

        self.matrix_var = tk.IntVar(value=self.program)
        self.reverb_var = tk.IntVar(value=self.reverb)

        self.matrix_buttons = []

        self.create_gui()
        self.refresh_ports()
        self.start_keyboard_listener()

        self.root.protocol(
            "WM_DELETE_WINDOW",
            self.close
        )


    # ========================================================
    # GUI
    # ========================================================

    def create_gui(self):

        main = ttk.Frame(
            self.root,
            padding=10
        )

        main.pack(
            fill="both",
            expand=True
        )


        # ----------------------------------------------------
        # MIDI OUTPUT
        # ----------------------------------------------------

        port_frame = ttk.LabelFrame(
            main,
            text="MIDI Output",
            padding=8
        )

        port_frame.pack(
            fill="x",
            pady=(0, 8)
        )

        self.port_var = tk.StringVar()

        self.port_combo = ttk.Combobox(
            port_frame,
            textvariable=self.port_var,
            state="readonly",
            width=55
        )

        self.port_combo.pack(
            side="left",
            fill="x",
            expand=True
        )

        ttk.Button(
            port_frame,
            text="Refresh",
            command=self.refresh_ports
        ).pack(
            side="left",
            padx=(5, 0)
        )

        ttk.Button(
            port_frame,
            text="Connect",
            command=self.connect_port
        ).pack(
            side="left",
            padx=(5, 0)
        )


        # ----------------------------------------------------
        # CHANNEL
        # ----------------------------------------------------

        channel_frame = ttk.Frame(main)

        channel_frame.pack(
            fill="x",
            pady=(0, 8)
        )

        ttk.Label(
            channel_frame,
            text="MIDI Channel:"
        ).pack(side="left")

        self.channel_var = tk.IntVar(value=1)

        self.channel_spin = tk.Spinbox(
            channel_frame,
            from_=1,
            to=16,
            textvariable=self.channel_var,
            width=5,
            command=self.channel_changed
        )

        self.channel_spin.pack(
            side="left",
            padx=(5, 0)
        )

        self.channel_spin.bind(
            "",
            lambda event: self.channel_changed()
        )

        self.channel_spin.bind(
            "",
            lambda event: self.channel_changed()
        )


        # ----------------------------------------------------
        # PROGRAM CONTROLS
        # ----------------------------------------------------

        control_frame = ttk.Frame(main)

        control_frame.pack(
            fill="x",
            pady=(0, 8)
        )

        ttk.Button(
            control_frame,
            text="Previous",
            command=self.previous_program
        ).pack(side="left")

        self.program_var = tk.IntVar(value=1)

        self.program_spin = tk.Spinbox(
            control_frame,
            from_=1,
            to=128,
            textvariable=self.program_var,
            width=6,
            command=self.program_spin_changed
        )

        self.program_spin.pack(
            side="left",
            padx=8
        )

        self.program_spin.bind(
            "",
            lambda event: self.program_spin_changed()
        )

        self.program_spin.bind(
            "",
            lambda event: self.program_spin_changed()
        )

        ttk.Button(
            control_frame,
            text="Next",
            command=self.next_program
        ).pack(side="left")


        # ----------------------------------------------------
        # INSTRUMENT NAME
        # ----------------------------------------------------

        self.instrument_label = ttk.Label(
            main,
            text="1  Acoustic Grand Piano",
            anchor="center",
            font=("TkDefaultFont", 12, "bold")
        )

        self.instrument_label.pack(
            fill="x",
            pady=(0, 8)
        )


        # ----------------------------------------------------
        # REVERB
        # ----------------------------------------------------

        reverb_frame = ttk.LabelFrame(
            main,
            text="Reverb (MIDI CC 91)",
            padding=8
        )

        reverb_frame.pack(
            fill="x",
            pady=(0, 8)
        )

        self.reverb_knob = tk.Scale(
            reverb_frame,
            from_=0,
            to=127,
            orient="horizontal",
            variable=self.reverb_var,
            command=self.reverb_changed,
            showvalue=True,
            resolution=1,
            length=300
        )

        self.reverb_knob.pack(
            fill="x"
        )


        # ----------------------------------------------------
        # SCROLLABLE PROGRAM MATRIX
        # ----------------------------------------------------

        matrix_frame = ttk.LabelFrame(
            main,
            text="Program",
            padding=5
        )

        matrix_frame.pack(
            fill="both",
            expand=True
        )


        # Canvas
        self.canvas = tk.Canvas(
            matrix_frame,
            highlightthickness=0
        )

        self.canvas.pack(
            side="left",
            fill="both",
            expand=True
        )


        # Vertical scrollbar
        scrollbar = ttk.Scrollbar(
            matrix_frame,
            orient="vertical",
            command=self.canvas.yview
        )

        scrollbar.pack(
            side="right",
            fill="y"
        )

        self.canvas.configure(
            yscrollcommand=scrollbar.set
        )


        # Frame inside canvas
        self.matrix_inner = ttk.Frame(
            self.canvas
        )

        self.canvas_window = self.canvas.create_window(
            (0, 0),
            window=self.matrix_inner,
            anchor="nw"
        )


        # Update scroll region when frame changes
        self.matrix_inner.bind(
            "",
            self.update_scroll_region
        )


        # Make inner frame follow canvas width
        self.canvas.bind(
            "",
            self.resize_matrix
        )


        # Mouse wheel
        self.canvas.bind_all(
            "",
            self.mousewheel
        )


        # Linux mouse wheel
        self.canvas.bind_all(
            "",
            self.mousewheel_linux_up
        )

        self.canvas.bind_all(
            "",
            self.mousewheel_linux_down
        )


        # ----------------------------------------------------
        # CREATE MATRIX
        # ----------------------------------------------------

        for program in range(1, 129):

            row = (program - 1) // 8
            col = (program - 1) % 8

            button = ttk.Radiobutton(
                self.matrix_inner,
                text=str(program),
                value=program,
                variable=self.matrix_var,
                command=lambda p=program:
                    self.matrix_program_selected(p)
            )

            button.grid(
                row=row,
                column=col,
                padx=2,
                pady=2,
                sticky="ew"
            )

            self.matrix_buttons.append(button)


        for col in range(8):

            self.matrix_inner.columnconfigure(
                col,
                weight=1
            )


        self.update_program_controls()
        self.update_matrix()
        self.update_label()


    # ========================================================
    # SCROLLING
    # ========================================================

    def update_scroll_region(self, event=None):

        self.canvas.configure(
            scrollregion=self.canvas.bbox("all")
        )


    def resize_matrix(self, event):

        self.canvas.itemconfigure(
            self.canvas_window,
            width=event.width
        )


    def mousewheel(self, event):

        self.canvas.yview_scroll(
            int(-1 * (event.delta / 120)),
            "units"
        )


    def mousewheel_linux_up(self, event):

        self.canvas.yview_scroll(
            -3,
            "units"
        )


    def mousewheel_linux_down(self, event):

        self.canvas.yview_scroll(
            3,
            "units"
        )


    # ========================================================
    # MIDI PORTS
    # ========================================================

    def refresh_ports(self):

        ports = mido.get_output_names()

        self.port_combo["values"] = ports

        if ports:
            self.port_combo.current(0)
        else:
            self.port_var.set("")


    def connect_port(self):

        name = self.port_var.get()

        if not name:

            messagebox.showwarning(
                "MIDI",
                "No MIDI output port selected."
            )

            return

        try:

            if self.port:
                self.port.close()

            self.port = mido.open_output(name)

            self.send_program()
            self.send_reverb()

        except Exception as e:

            self.port = None

            messagebox.showerror(
                "MIDI Error",
                str(e)
            )


    # ========================================================
    # MIDI PROGRAM CHANGE
    # ========================================================

    def send_program(self):

        if self.port is None:
            return

        midi_channel = self.channel - 1
        midi_program = self.program - 1

        try:

            self.port.send(
                mido.Message(
                    "program_change",
                    channel=midi_channel,
                    program=midi_program
                )
            )

        except Exception as e:

            print("MIDI error:", e)


    # ========================================================
    # REVERB CC 91
    # ========================================================

    def send_reverb(self):

        if self.port is None:
            return

        midi_channel = self.channel - 1

        try:

            self.port.send(
                mido.Message(
                    "control_change",
                    channel=midi_channel,
                    control=REVERB_CC,
                    value=self.reverb
                )
            )

        except Exception as e:

            print("MIDI reverb error:", e)


    def reverb_changed(self, value):

        try:
            self.reverb = int(float(value))
        except ValueError:
            return

        self.send_reverb()


    # ========================================================
    # CHANNEL
    # ========================================================

    def channel_changed(self):

        try:

            channel = int(
                self.channel_var.get()
            )

            if channel < 1 or channel > 16:
                raise ValueError

        except ValueError:

            self.channel_var.set(
                self.channel
            )

            return


        self.channel = channel


        # Channel 10 only supports the selected drum kits.
        if self.channel == 10:

            if self.program not in DRUM_KITS:

                self.program = DRUM_PROGRAMS[0]


        self.program_var.set(
            self.program
        )

        self.matrix_var.set(
            self.program
        )

        self.update_program_controls()
        self.update_matrix()
        self.update_label()

        self.send_program()
        self.send_reverb()


    # ========================================================
    # PROGRAM
    # ========================================================

    def set_program(self, program):

        if self.channel == 10:

            if program not in DRUM_KITS:
                return

        if program < 1 or program > 128:
            return

        self.program = program

        self.program_var.set(
            program
        )

        self.matrix_var.set(
            program
        )

        self.update_label()
        self.update_matrix()

        self.send_program()


    def program_spin_changed(self):

        try:

            program = int(
                self.program_var.get()
            )

        except ValueError:

            self.program_var.set(
                self.program
            )

            return


        if self.channel == 10:

            if program not in DRUM_KITS:

                program = min(
                    DRUM_PROGRAMS,
                    key=lambda p:
                        abs(p - program)
                )

        else:

            if program < 1:
                program = 1

            if program > 128:
                program = 128


        self.set_program(program)


    # ========================================================
    # PREVIOUS
    # ========================================================

    def previous_program(self):

        if self.channel == 10:

            current_index = DRUM_PROGRAMS.index(
                self.program
            )

            new_index = (
                current_index - 1
            ) % len(DRUM_PROGRAMS)

            self.set_program(
                DRUM_PROGRAMS[new_index]
            )

        else:

            if self.program <= 1:
                new_program = 128
            else:
                new_program = self.program - 1

            self.set_program(
                new_program
            )


    # ========================================================
    # NEXT
    # ========================================================

    def next_program(self):

        if self.channel == 10:

            current_index = DRUM_PROGRAMS.index(
                self.program
            )

            new_index = (
                current_index + 1
            ) % len(DRUM_PROGRAMS)

            self.set_program(
                DRUM_PROGRAMS[new_index]
            )

        else:

            if self.program >= 128:
                new_program = 1
            else:
                new_program = self.program + 1

            self.set_program(
                new_program
            )


    # ========================================================
    # MATRIX
    # ========================================================

    def matrix_program_selected(self, program):

        self.set_program(program)


    def update_matrix(self):

        if not self.matrix_buttons:
            return

        for program, button in enumerate(
            self.matrix_buttons,
            start=1
        ):

            if self.channel == 10:

                if program in DRUM_KITS:

                    button.configure(
                        text=f"{program}\n"
                             f"{DRUM_KITS[program]}",
                        state="normal"
                    )

                else:

                    button.configure(
                        text=str(program),
                        state="disabled"
                    )

            else:

                button.configure(
                    text=str(program),
                    state="normal"
                )


    # ========================================================
    # PROGRAM SPINBOX
    # ========================================================

    def update_program_controls(self):

        if self.channel == 10:

            self.program_spin.configure(
                values=tuple(
                    DRUM_PROGRAMS
                )
            )

        else:

            self.program_spin.configure(
                from_=1,
                to=128,
                values=()
            )


    # ========================================================
    # LABEL
    # ========================================================

    def update_label(self):

        if self.channel == 10:

            name = DRUM_KITS.get(
                self.program,
                "Unknown Drum Kit"
            )

        else:

            name = GM_INSTRUMENTS[
                self.program - 1
            ]

        self.instrument_label.configure(
            text=f"{self.program}  {name}"
        )


    # ========================================================
    # GLOBAL KEYBOARD
    # ========================================================

    def start_keyboard_listener(self):

        self.keyboard_listener = keyboard.Listener(
            on_press=self.key_pressed
        )

        self.keyboard_listener.start()


    def key_pressed(self, key):

        try:

            if key.char == "-":

                self.root.after(
                    0,
                    self.previous_program
                )

            elif key.char == "=":

                self.root.after(
                    0,
                    self.next_program
                )

        except AttributeError:

            pass


    # ========================================================
    # CLOSE
    # ========================================================

    def close(self):

        if self.keyboard_listener:

            self.keyboard_listener.stop()

        if self.port:

            self.port.close()

        self.root.destroy()


# ============================================================
# MAIN
# ============================================================

if __name__ == "__main__":

    root = tk.Tk()

    app = MidiProgramChanger(root)

    root.mainloop()

Saturday, August 29, 2026

fixing vgm2gbs for linux

once you make a gbs you can convert it to a gb rom using (or just do gb export in deflemask and skip all this)

gbs-master vgm2gbs github

convert.bat is great if your on windows for drag and drop but 2 problems
1 - vgm headers this script used are old and incompatable with most newer deflemask versions
2 - because im running it in wine and requires python its broken
THE FIX
Replace src/gd3.py with:

make a linux.sh and chmod +x it


#!/bin/bash
cd "$(dirname "$0")"
python3 src/main.py "$1"

import struct


class GD3:
    version: int
    track_name: str
    track_name_orig: str
    game_name: str
    game_name_orig: str
    system_name: str
    system_name_orig: str
    author: str
    author_orig: str
    release_date: str
    ripper: str
    notes: str

    def __init__(self, data: bytes):
        assert data[0:4] == b'Gd3 '

        self.version, data_length = struct.unpack_from(" str:
        return f'{self.track_name} - {self.author} - {self.game_name} ({self.ripper})'
 

making lsdj roms with lsdpack kit

lsdpack kit on github

make RGBDS="$HOME/Downloads/rgbds-0.9.1-linux-x86_64/"
rgbds I needed the older version to compile lsdj rom repo

I use v 8-5-1 stable the newer versions output a garbled mess
in the code_config.mk file i commented out
# ASFLAGS += -h


this projects cool because it lets you plop in your 160x144 album pics with your lsdj songs to make the rom for an interactive album

Friday, August 28, 2026

fixed raspberry pi lite resolution


sudo vim /boot/firmware/cmdline.txt

video=HDMI-A-1:1600x900@60

logitech f310 macros, shutdown, copy paste


from evdev import InputDevice, UInput, ecodes
import subprocess
import threading
import time

GAMEPAD = "/dev/input/by-id/usb-Logitech_Logitech_Dual_Action_DF5CB332-event-joystick"

device = InputDevice(GAMEPAD)

# Virtual keyboard
ui = UInput({
    ecodes.EV_KEY: [
        ecodes.KEY_LEFTCTRL,
        ecodes.KEY_C,
        ecodes.KEY_V,
    ]
}, name="Gamepad Virtual Keyboard")

button_292 = False
button_293 = False
shutdown_timer = None
lock = threading.Lock()


def ctrl_key(key):
    print(f"Sending Ctrl+{key}", flush=True)

    ui.write(ecodes.EV_KEY, ecodes.KEY_LEFTCTRL, 1)
    ui.write(ecodes.EV_KEY, key, 1)
    ui.write(ecodes.EV_KEY, key, 0)
    ui.write(ecodes.EV_KEY, ecodes.KEY_LEFTCTRL, 0)
    ui.syn()


def shutdown():
    time.sleep(1)

    with lock:
        if button_292 and button_293:
            print("\nBoth buttons held for 1 second — SHUTTING DOWN!", flush=True)
            subprocess.run(["systemctl", "poweroff"])


print(f"Gamepad: {device.name}", flush=True)
print("291 = Ctrl+C", flush=True)
print("290 = Ctrl+V", flush=True)
print("292 + 293 for 1 second = Shutdown", flush=True)
print("Waiting for input...\n", flush=True)


for event in device.read_loop():

    if event.type != ecodes.EV_KEY:
        continue

    with lock:

        # BTN_TOP = 291 -> Ctrl+C
        if event.code == 291 and event.value == 1:
            print("291: Ctrl+C", flush=True)
            ctrl_key(ecodes.KEY_C)

        # BTN_THUMB2 = 290 -> Ctrl+V
        elif event.code == 290 and event.value == 1:
            print("290: Ctrl+V", flush=True)
            ctrl_key(ecodes.KEY_V)

        # BTN_TOP2 = 292
        elif event.code == 292:
            button_292 = event.value == 1
            print(
                f"292: {'PRESSED' if button_292 else 'RELEASED'}",
                flush=True
            )

        # BTN_PINKIE = 293
        elif event.code == 293:
            button_293 = event.value == 1
            print(
                f"293: {'PRESSED' if button_293 else 'RELEASED'}",
                flush=True
            )

        # Start shutdown timer
        if button_292 and button_293 and shutdown_timer is None:
            print("Both shoulder buttons held — 1 second timer started.", flush=True)
            shutdown_timer = threading.Thread(
                target=shutdown,
                daemon=True
            )
            shutdown_timer.start()

        # Cancel shutdown
        elif not (button_292 and button_293):
            shutdown_timer = None

jiggler keeps your screen from falling asleep

jiggler github

pipx install jiggler


Launching Gambatte Gameboy Emulator From Terminal


retroarch -L

// if installed on linux mint using
// sudo apt install libretro-gambatte
// then it will probably be at:
/usr/lib/x86_64-linux-gnu/libretro/gambatte_libretro.so

// full command for me:
retroarch -L /usr/lib/x86_64-linux-gnu/libretro/gambatte_libretro.so /home/bweew/Documents/Syncthing/Lsdj/lsdj.gb

f for full screen f1 for settings like changing the key maps

You can make it a bash script


#!/bin/bash
retroarch -L /usr/lib/x86_64-linux-gnu/libretro/gambatte_libretro.so "$HOME/Documents/Syncthing/Lsdj/lsdj.gb"
chmod +x ~/lsdj.sh

//on raspberry pi 3 64 bit os
#!/bin/bash
retroarch -L /usr/lib/aarch64-linux-gnu/libretro/gambatte_libretro.so lsdj.gb

Wednesday, August 26, 2026

maj7b5 and 7sus4b5 inversions

1 4 b5 b7
1 b9 4 5
1 3 b5 7
1 2 5 b6

1 3 b5 7
1 2 5 b6
1 4 b5 b7
1 b9 4 5

Tuesday, August 25, 2026

python gba compilation builder scripts

gba emu comp on github

python scripts to build gba roms, emulators not included

Saturday, August 22, 2026

mediaboy - great for making music roms on gameboy easily

mediaboy releases

the music export is the most useful.
says it can do .mod and .uge but its not working for me
the gif and video exports work in sameboy but not on my flashcart or in gearboy
pcm samplerate settings:
9198 hz -GBVP2 parity yeilds best quality
DMG gives clearer images than colour it seems to mangle the image with blocky pixels
to

goomba paletted

use that with gameboy slideshow generator instead of that because it screws up the audio


making gb and gbc videos worked better flashed directly with gb flasher to a perfect dark cart instead of on the superchis gba sd cart also sameboy and bgb are more accurate usually but goomba breaks

renaming png and jpgs as numbers using bash


i=1; for f in *.png *.jpg *.jpeg; do [ -f "$f" ] || continue; mv -- "$f" "$i.${f##*.}"; ((i++)); done