Audio instant-replay buffer for Linux
Project description
echobuf
Audio instant-replay buffer for Linux. Continuously records system audio into a rolling RAM buffer — hit a hotkey and the last N seconds are saved to a WAV file. Like ShadowPlay, but for audio.
Install
pip install echobuf
Requires Python 3.11+ and either PipeWire or PulseAudio.
Optional extras:
pip install echobuf[tray] # system tray icon
pip install echobuf[hotkey] # built-in global hotkey via pynput
pip install echobuf[dev] # pytest for development
Quick start
# Start the daemon
echobuf daemon &
# Save the last 10 seconds of audio
echobuf save
# Save with a label
echobuf save --label "cool_riff"
# Check status
echobuf status
# Stop the daemon
echobuf quit
Saved files go to ~/samples/ by default, organized by date.
Binding to your WM
The recommended way to trigger saves is by binding echobuf save in your window manager. The daemon doesn't need to know about input devices — your WM handles that better than we can.
i3 / sway:
bindsym $mod+Shift+s exec --no-startup-id echobuf save
bindsym $mod+Shift+d exec --no-startup-id echobuf save --label dialogue
bindsym $mod+Shift+m exec --no-startup-id echobuf save --label "$(rofi -dmenu -p tag)"
GNOME: Settings → Keyboard → Custom Shortcuts → add echobuf save
KDE: System Settings → Shortcuts → Custom Shortcuts → add echobuf save
Configuration
Config lives at ~/.config/echobuf/config.toml. Created with defaults on first use via the tray icon, or create it manually:
[buffer]
seconds = 10 # rolling buffer length
post_seconds = 0 # extra seconds captured after save
[capture]
backend = "auto" # auto | pipewire | pulse
source = "system" # system | app:<name>
sample_rate = 48000
channels = 2
[output]
directory = "~/samples"
template = "%(date)s/%(time)s_%(counter)03d.%(ext)s"
format = "wav"
sanitize = true
[hotkey]
binding = "" # e.g. "<ctrl>+<shift>+s" (requires echobuf[hotkey])
[notifications]
enabled = true
sound = true
[logging]
level = "info"
Output templates
File paths use yt-dlp–style tokens:
| Token | Example | Description |
|---|---|---|
%(date)s |
2026-04-08 |
Local date |
%(time)s |
143052 |
Local time (HHMMSS) |
%(timestamp)s |
1744128652 |
Unix epoch |
%(iso)s |
2026-04-08T14:30:52 |
Full ISO 8601 |
%(app)s |
spotify |
Source app name |
%(source)s |
system |
Capture source |
%(device)s |
default |
Output device |
%(duration)d |
10 |
Captured seconds |
%(counter)03d |
001 |
Auto-incrementing counter |
%(label)s |
drum_fill |
Label from --label flag |
%(ext)s |
wav |
File extension |
Default values: %(label|untitled)s falls back to untitled when no label is given.
CLI reference
echobuf daemon Run the capture daemon in foreground
echobuf save [--label NAME] Trigger a save
echobuf status Print daemon status (backend, buffer, saves)
echobuf sources List available capture sources (system + apps)
echobuf set-source <spec> Switch source: "system" or "app:<name>"
echobuf pause Pause capture (daemon keeps running)
echobuf resume Resume capture
echobuf quit Stop the daemon
echobuf tray Launch the system tray icon
Per-app capture
Capture audio from a specific application instead of the full system mix:
# Via config
[capture]
source = "app:firefox"
# At runtime
echobuf set-source app:spotify
echobuf set-source system # switch back
On PipeWire, per-app capture uses native graph linking — the app's audio is tapped without any routing changes, so there's no latency penalty and the user keeps hearing audio normally.
On PulseAudio, a null sink + loopback is created. The user still hears audio, but through a loopback with ~30ms latency.
System tray
echobuf tray
Requires echobuf[tray]. Provides a menu to save, pause/resume, open the save folder, edit config, and quit the daemon.
systemd service
A unit file is included at contrib/echobuf.service. To install:
cp contrib/echobuf.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now echobuf
The tray icon should be started separately via your desktop environment's autostart.
Architecture
┌──────────────────────────────────────────────┐
│ echobuf daemon │
│ │
│ Audio Source ──▶ Ring Buffer ──▶ WAV Writer │
│ (parec/pw-record) (numpy) (on trigger) │
│ │
│ IPC Server (Unix socket, JSON) │
└──────────┬───────────────────────────────────┘
│
CLI / Tray / WM binding
- Ring buffer: preallocated NumPy array, ~22 MB for 60s of 48kHz stereo
- Backends: PipeWire (pw-record) auto-detected, PulseAudio (parec) fallback
- IPC: Unix socket at
$XDG_RUNTIME_DIR/echobuf.sock, line-delimited JSON - Output: 16-bit PCM WAV via libsndfile
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file echobuf-0.4.0.tar.gz.
File metadata
- Download URL: echobuf-0.4.0.tar.gz
- Upload date:
- Size: 50.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b995d240c2472423ff6e988bb4803b7db498a3fcc649c633a597bcfe8312488
|
|
| MD5 |
44d1ef97bb296965a17575876b4d8a54
|
|
| BLAKE2b-256 |
626ff2be72ae4b151a1142e96018b46db985518ed3fc6775cad843f797c6d15f
|
File details
Details for the file echobuf-0.4.0-py3-none-any.whl.
File metadata
- Download URL: echobuf-0.4.0-py3-none-any.whl
- Upload date:
- Size: 24.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
153147d4c2327a357d28a2872c592083e8b33d0abafa7744c345cd0a17b4556a
|
|
| MD5 |
ae7b2fade3eba7eec0c64a12f0aad64d
|
|
| BLAKE2b-256 |
74db783f8bee2555eaa62c8b7665510b38b25f415eddf6f37aaebd2d6803c30b
|