Oloopsy
A sampler, looper and drum machine that lives in the Omarchy bar.
Sample whatever is already playing on your machine — retroactively, from a rolling buffer, so you can grab a sound after you have heard it go past. Chop it across sixteen keyboard-mapped pads, layer loops with proper undo, and program beats on a synthesised 808/909 kit. Export to WAV when you are done.
No sample files ship with it. Every drum is generated live from oscillators and shaped noise, which keeps the repository small, sidesteps sample licensing entirely, and means every drum has real knobs rather than being a fixed recording.
Requirements
- Omarchy 4 with Quickshell
- PipeWire (
pw-catandpw-record, both part of a standard PipeWire install). Sources are enumerated withpactlwhere it is present and straight frompw-dumpwhere it is not, so PulseAudio compatibility is not required. - Python 3 with numpy — the
python-numpypackage on Arch
Install
omarchy plugin add https://github.com/WyattB111/omarchy-oloopsy.git
omarchy plugin enable wyatt.oloopsy right
Click the bar icon to open the instrument.
Playing it
The panel takes keyboard focus while it is open, so the pads are the keyboard. The grid is laid out the way it sits under your hands, with the core kit on the home row:
1 2 3 4 Crash Ride Cowbell Shaker
Q W E R Tom hi Tom mid Tom lo Rimshot
A S D F Kick Snare Hat CH Hat OH
Z X C V Clap · · ·
| Key | Does |
|---|---|
Space |
Play / stop |
Enter |
The loop pedal: record → overdub → commit |
⌫ |
Undo the last overdub layer |
N |
Start a new loop track |
G |
Grab the last few seconds of what you were listening to |
H |
Hold to record; releases into a new sample |
T |
Tap tempo |
M |
Metronome |
U |
Snap live hits to the grid |
B |
Beat-repeat, held |
[ ] |
Tempo down / up |
T |
Tap tempo — tap it three or four times in time |
, . |
Swing down / up |
5–8 |
Jump to pattern A–D |
Esc |
Close |
Right-clicking a step in the sequencer cycles it full → ghost → off.
The tempo box takes a nudge from the − and + buttons (hold either to run),
a vertical drag, or the scroll wheel — shift-scroll moves in fives. It is a
stepper rather than a slider on purpose: across 40–240 BPM a slider puts about
one beat under every pixel, and landing exactly on 120 becomes luck. TAP sets
it by feel instead — tap three or four times in time with whatever you are
hearing.
Sampling anything that plays
Pick a source on the SAMPLE tab. Individual applications are listed first, then microphones, then whole outputs.
Capturing a single application is the option worth reaching for: the whole-output monitors also carry Oloopsy's own sound, so sampling one while a beat is playing records that beat too. Oloopsy's own output appears in the list as well, marked feeds back — resampling your own loop is a real technique, but it should be something you chose.
Every listed source is selectable — applications, microphones and output monitors alike — and each is a direct digital tap on that node, not a re-recording of the room. Capture runs continuously once armed, keeping the last 30 seconds. Grab keeps whatever length you ask for, counting backwards from the moment you press it, so you never have to predict that a sound is coming.
Then CHOP 16 slices it — by transient, or evenly — and → ALL PADS lays the slices across the grid so you can play the thing as an instrument.
Looping
One button cycles record → overdub → commit, per track, exactly like a looper pedal. Six tracks, all locked to the same length.
Undo is exact rather than approximate. Each pass stores only the audio it added, so undoing subtracts precisely that layer — including when layer decay is turned down to fade older passes the way a tape looper does.
The looper records the pads by default. It can record everything (loops included, which layers them into each other — occasionally the point) or the sampled input directly.
Exporting
FILES renders to 24-bit WAV in ~/Music/Oloopsy, and tells you where it put
it — the confirmation line under the buttons names the file and its length. Stems writes the drums and
each loop as separate files too, so a sketch can be finished elsewhere. Projects
save the whole session — pattern, kit settings, samples and loops — as JSON plus
ordinary WAVs you can open in anything.
From a terminal
The engine is a daemon; the bar widget is only a view. Everything is reachable from the CLI, and both stay in sync because they drive the same process:
oloopsy state
oloopsy sources
oloopsy capture app:1234
oloopsy grab 8 --name break
oloopsy slice 1 --to-pads
oloopsy bpm 96 && oloopsy swing 0.67
oloopsy play
oloopsy loop # record / overdub / commit
oloopsy export --stems
Export and save are also on the IPC surface, so they can be bound to a hotkey:
omarchy-shell wyatt.oloopsy exportMix
omarchy-shell wyatt.oloopsy exportStems
omarchy-shell wyatt.oloopsy save
If something goes wrong
The engine is a daemon, so it outlives the shell on purpose — your loops
survive a reload. oloopsy quit stops it; oloopsy state shows what it is
doing. Helper processes are tagged and a starting daemon clears up any left
behind by a predecessor that was killed outright, so phantom "Oloopsy" entries
do not accumulate in the source list.
How it works, briefly
State and audio live in bin/oloopsy (a Python daemon); the QML is a view that
talks to it over a unix socket at $XDG_RUNTIME_DIR/oloopsy.sock. That
directory must be private and owned by you — there is deliberately no fallback
to a predictable path under /tmp, and Oloopsy refuses to start without one
rather than putting a command socket somewhere another user could reach. Your loops
therefore survive a shell reload, and there is one engine no matter how many
monitors show a widget.
Blocks are 256 frames (5.3 ms) and sequencer events are scheduled at sample offsets inside a block rather than being rounded to block boundaries, so swing and ratchets stay tight. Rendering measures around 0.3% of one core.
A pad hit costs about 26 ms end to end: one block to render, ~11 ms in the
pipe to PipeWire, and 10 ms in the sink. The pipe is deliberately shrunk to one
page with F_SETPIPE_SZ — left at the 64 KB default it banks up about 185 ms of
rendered-but-unheard audio, which sounds exactly like lag while showing no xruns
at all. PIPE_BYTES and OUT_LATENCY in bin/oloopsy_engine/const.py trade
that against dropout headroom if you want to push it further.
Note that quantise (U) is a separate source of delay by design: it snaps a
live hit forward onto the grid, which is up to 112 ms at 120 BPM. It is off by
default and worth turning on only while overdubbing.
The effects run as frequency-domain overlap-add with a square-root Hann window, which is why a filter can be swept by hand mid-performance without clicking — and the whole chain is bypassed when nothing is engaged, so a plain drum pattern does not pay its latency.
Licence
MIT.