Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

echobuf-0.4.0.tar.gz (50.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

echobuf-0.4.0-py3-none-any.whl (24.3 kB view details)

Uploaded Python 3

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

Hashes for echobuf-0.4.0.tar.gz
Algorithm Hash digest
SHA256 5b995d240c2472423ff6e988bb4803b7db498a3fcc649c633a597bcfe8312488
MD5 44d1ef97bb296965a17575876b4d8a54
BLAKE2b-256 626ff2be72ae4b151a1142e96018b46db985518ed3fc6775cad843f797c6d15f

See more details on using hashes here.

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

Hashes for echobuf-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 153147d4c2327a357d28a2872c592083e8b33d0abafa7744c345cd0a17b4556a
MD5 ae7b2fade3eba7eec0c64a12f0aad64d
BLAKE2b-256 74db783f8bee2555eaa62c8b7665510b38b25f415eddf6f37aaebd2d6803c30b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page