aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-09-12 15:25:06 -0400
committerhistoria <historiavg@proton.me>2026-09-12 15:25:06 -0400
commit464edbc4fd658728f06d3a7d98340aa28ff3e3ec (patch)
treea182f62ef0365f2c2143f88436de78a03d752367 /README.md
parent1bbe59f78be9a8355bb0bee2bc8ab14ca42ac71c (diff)
downloadproducer-464edbc4fd658728f06d3a7d98340aa28ff3e3ec.tar.gz
feat: slop web gui
Diffstat (limited to 'README.md')
-rw-r--r--README.md205
1 files changed, 190 insertions, 15 deletions
diff --git a/README.md b/README.md
index 1d43285..348b7e3 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,15 @@
# Producer
-Local speech cleanup and mastering for voice recordings. Noise removal uses `DeepFilterNet3`. Filtering, dynamics and loudness normalization are `FFmpeg`.
+Local speech cleanup and mastering for voice recordings. Noise removal uses
+ClearVoice or DeepFilterNet3; speech-aware pause silencing uses Silero VAD.
+Filtering, dynamics and loudness normalization use FFmpeg. Audio stays local.
`producer.sh` bootstraps its own managed Python environments and downloads
dependencies and models automatically.
## Requirements
-- glibc
+- glibc >= 2.28 for AI denoising and speech detection
- `uv` (or Python 3)
- NVidia driver and toolkit (optional)
@@ -15,7 +17,7 @@ dependencies and models automatically.
```bash
git clone https://git.historia.vg/git/producer
-./producer.sh setup
+./producer.sh setup --denoiser clearvoice
./producer.sh recording.wav
```
@@ -47,12 +49,18 @@ LUFS with a -1.5 dBTP true-peak ceiling**.
./producer.sh recording.wav --denoiser fft
./producer.sh recording.wav --no-denoise
-# Use the ClearVoice MossFormer2_SE_48K denoiser instead of DeepFilterNet3
-# (larger download; preserves word attacks noticeably better at high strength)
+# Compare ClearVoice MossFormer2_SE_48K with DeepFilterNet3
+# (larger download; speech preservation depends on the recording)
./producer.sh recording.wav --denoiser clearvoice
./producer.sh setup --denoiser clearvoice --device cpu
-# Shorten long gaps between takes (speech is never attenuated)
+# Silence pauses without changing the timing (enabled in config.toml)
+./producer.sh recording.wav --pause-silence --no-trim-silence
+
+# Bypass pause silencing for an A/B comparison
+./producer.sh recording.wav --no-pause-silence --output-dir comparison
+
+# Optionally shorten long gaps between takes (a separate pacing edit)
./producer.sh recording.wav --trim-silence --max-gap-s 1.5 --gap-pad-s 0.6
# LibriVox-style delivery file: 44.1 kHz, 128 kbps CBR, -19 LUFS, mono
@@ -63,6 +71,134 @@ LUFS with a -1.5 dBTP true-peak ceiling**.
Edit default settings in `config.toml`
+## Optional local browser GUI
+
+```bash
+./producer.sh gui --root /path/to/recordings
+# Optional alternate loopback port:
+./producer.sh gui --root /path/to/recordings --port 8766
+```
+
+The browser studio guides you through **Choose recording → Try a short passage
+→ Compare sound → Export full recording**. Use a current desktop browser
+(Chromium tested); JavaScript is required. No Node/npm build, CDN, telemetry,
+or cloud audio service is used. The launcher installs the optional
+FastAPI/uvicorn extra only when `gui` is requested. Existing CLI commands do
+not need it. Direct package installs can use `producer[gui]` and need system
+FFmpeg or the `bundled-ffmpeg` extra for processing.
+
+1. Browse folders beneath your chosen root and select a mono WAV. The overview
+ is a streaming scan reduced to 2,048 peak bins, not a full recording loaded
+ into the browser. You can enter times before scanning finishes.
+2. Click or drag the waveform, or enter exact `HH:MM:SS.sss` start/end times
+ (seconds also work). Zoom enlarges the same coarse overview; exact times
+ are best for fine selection on multi-hour recordings.
+3. Start with noise cleanup, quiet pauses, tone and even volume. Expand **All
+ settings & advanced controls** for every other setting and its units/help.
+ Disabled effects retain their knob values. Nothing renders per keystroke,
+ and no dependent effect is silently enabled. Click **Render sound comparison**.
+4. Play/loop the passage and switch A/B without losing your place. Optional
+ matching attenuates the louder snippet for fair listening. File loudness
+ and peak readings are separate from monitoring gain, not quality scores
+ or full-export measurements. Changes pause playback and mark older renders;
+ late jobs never replace the visible comparison after you edit the selection.
+5. Choose an existing output folder, review the frozen current settings and
+ confirm **Export full recording**. This processes the entire original even
+ if you selected only a few seconds. Completed local paths appear in the
+ export panel; find the files with your operating system's file manager.
+
+Open the printed `http://127.0.0.1:.../#token=...` URL on the same machine and
+keep it private. The server binds only to loopback, rejects untrusted
+Host/Origin headers, and requires the session credential for every API read
+or mutation. Do not expose it through a proxy or port-forwarding service.
+`--root` bounds browsing and output directories, including resolved symlinks;
+its default is the current working directory. There are no recording uploads
+or arbitrary host-file download endpoints. Stop the server with Ctrl-C.
+
+**Containers/remote shells:** loopback belongs to the machine/network namespace
+running Producer. A browser on the host cannot normally reach a container's
+`127.0.0.1`; publishing a container port does not change this loopback-only
+binding. The simplest supported setup is to run `./producer.sh gui` directly
+on the machine with your browser and recordings. This development container
+has no GUI. Do not change the bind to `0.0.0.0`, disable the Host/Origin checks,
+or expose the token through a proxy to work around access. No insecure
+container-host access mode is provided.
+
+Settings use the same strict resolver and configuration precedence as the CLI.
+The initial controls include your launch TOML and CLI overrides. **Restore
+launch settings** resets edits. **Apply profile & launch defaults** resets
+through that precedence too: explicit launch values still win. Changing only
+the profile name keeps your other explicit knob values. TOML import instead
+loads standalone settings (package defaults/profile plus the imported TOML).
+
+Save up to 20 named settings presets and 12 immutable comparison snapshots per
+root in this browser. Snapshots retain the source identity, excerpt times and
+requested settings, never audio. **Restore & render** explicitly recreates a
+comparison; a changed source file must be re-selected. Download/import small
+TOML presets to move settings between browsers. Local browser storage can be
+cleared or disabled and is specific to the loopback address/port; use TOML for
+backup. Session credentials are never saved in presets or comparison snapshots.
+
+Waveform scans and jobs run in the background, one at a time, with up to three
+waiting. Activity shows per-stage progress, frozen snapshots and cancellation.
+Cancellation is cooperative: a model download may take up to 60 seconds to
+reach a safe callback, and files already published can remain. There is no
+total recording-duration cap; typical 1–4 hour and longer recordings still need
+sufficient processing time and temporary disk space. Inputs must be readable
+mono WAVs; stereo needs an explicit downmix outside Producer first.
+
+First AI noise cleanup or pause silencing use downloads dependencies/models;
+processing stays local afterwards. For a quick no-model trial, launch with
+`./producer.sh gui --root /path/to/recordings --no-denoise --no-pause-silence`.
+These explicit flags establish initial controls, not hidden permanent bypasses.
+Reload retains the credential in the same tab and reconnects to recent jobs,
+but does not automatically restore/play old audio. If Producer restarts, open
+its newly printed private URL. If a connection drops during an export request,
+check Activity before submitting another export; the first may have succeeded.
+
+Sound-comparison previews select up to 120 seconds anywhere in a recording,
+process with up to 10 seconds of context on each side, then crop to the selected
+interval. They are **approximate, not exact export previews**: chapter-level
+normalization and inference context differ. Pacing edits are not previewed;
+comparisons preserve timing even when export gap trimming is selected.
+Normalization and other effects are never forced on for comparison. Optional
+loudness matching is playback-only attenuation, not a change to export settings.
+
+Exports process the whole original with the requested settings into a new,
+non-clobbering `producer-export-*` folder in the chosen output directory:
+`master.wav`, optional `master.mp3`, and `logs/master.report.json`. The API
+returns persistent local paths, **not browser blobs of multi-hour exports**.
+The browser only fetches bounded preview snippets. TOML presets can be imported
+as text or downloaded; no preset or source recording is rewritten by the API.
+The server retains at most eight repeated-result cache entries and 128 MiB of
+artifacts; expired previews must be rendered again. Job history is limited to
+24 entries and is lost when the server stops, while completed output files
+persist. Browser preview WAVs are bounded to about 11.6 MB per side (120 seconds
+of mono PCM16 at 48 kHz). Full exports never become browser Blobs. These are
+generic WAV/MP3 delivery files, not delivery-platform compliance certification.
+
+### GUI development checks (optional)
+
+The application itself needs no browser automation or Node dependencies. With
+an external test environment containing `producer[gui,test]`, use:
+
+```bash
+python -m pytest lib/project/tests -q
+node --check lib/project/src/producer/web/app.js
+node --test lib/project/tests/gui_state.test.mjs
+# Optional real headless browser checks, no AI models:
+python -m pip install playwright
+python -m playwright install chromium
+PRODUCER_BROWSER_TESTS=1 python -m pytest lib/project/tests/test_gui_browser*.py -q
+```
+
+Playwright may need OS-specific browser shared libraries in the test container;
+these are not application runtime dependencies. Browser checks generate a
+short test WAV, exercise real scan/preview/export and cancellation, and mock a
+bounded four-hour overview. They do not claim a four-hour AI processing run.
+Screenshots default to `/tmp/producer-browser-smoke`; set
+`PRODUCER_BROWSER_ARTIFACTS` to keep them elsewhere.
+
## Profiles
| Profile | Sound |
@@ -72,13 +208,51 @@ Edit default settings in `config.toml`
| `radio` | Stronger compression, more warmth/presence, tighter range |
| `cleanup-only` | Denoise + highpass only; no EQ, dynamics or normalization |
-AI denoisers soften word attacks to some degree; `clearvoice`
-(MossFormer2_SE_48K) was measured to leave onsets essentially untouched,
-while `deepfilter` ducks them a couple of percent even at reduced strength.
-Denoisers also never reach true digital silence: a noise floor remains in
-blank sections. `--trim-silence` addresses both properly - long gaps are
-shortened to `--gap-pad-s` of untouched room tone with a sample-exact cut,
-so speech is never gated or attenuated.
+## Speech starts and silent pauses
+
+Denoising and pause silencing are different jobs. Pushing a denoiser harder
+can damage quiet consonants without eliminating all room tone. Compression
+and normalization then raise the remaining noise. The shipped `config.toml`
+uses ClearVoice at 0.85 strength, speech-aware pause silencing, and **no gap
+trimming**. Bare package defaults leave pause silencing off (opt in with
+`--pause-silence`).
+
+Pause silencing detects speech on the **pre-denoise** audio using pinned
+Silero VAD v5.1 ONNX weights. First use downloads a separate CPU runtime and
+~2.3 MB model; it needs no GPU or cloud service. After EQ/dynamics, gaps
+outside protected speech fade to zero before loudness normalization. This
+keeps the timeline unchanged unless you separately enable `--trim-silence`.
+32-bit export uses no dither so silent cores can remain digital zero;
+resampling/filter tails may extend slightly into their edges. MP3 need not
+retain sample-exact silence near speech boundaries.
+
+Defaults protect 120 ms before and after detections, use 10 ms fades, and
+require an additional 80 ms silent core. Shorter gaps are left alone rather
+than risking chopped words. Controls:
+
+- `--pause-threshold 0.25`: lower = preserve more possible speech.
+- `--pause-pre-ms 180`: protect more of quiet sentence starts.
+- `--pause-post-ms 200`: keep longer word tails and decay.
+- `--pause-min-ms 40`: allow shorter silent cores after margins and fades.
+- `--no-pause-silence`: bypass this stage; no detector download. Combine with
+ `--no-denoise` to avoid all AI model/runtime downloads.
+
+The detector can miss whispers, breaths, or unusual speech. If it detects
+**no speech**, cleanup fails open with a warning instead of muting the file.
+Other detector failures stop processing, not silently switch to a level gate.
+Reports in `logs/` include the attenuated intervals on the original,
+pre-trim timeline for inspection. With VAD enabled, optional trimming only
+shortens near-zero cores; without it, legacy `gap_threshold_db` trimming can
+mistake quiet speech for silence.
+
+This stage does **not** restore consonants a denoiser has already removed.
+Compare denoisers and try `--denoise-strength 0.65` if attacks remain soft;
+a dry/wet blend trades some noise reduction for speech preservation.
+A low, consistent room tone can sound more natural than dead silence.
+Professional quality requires listening for artifacts, breaths, sibilance,
+clipping and reverb, not just checking a meter. LUFS targets here are not
+ACX RMS/noise-floor certification; no one-click chain guarantees every
+recording meets a delivery specification.
Test the difference on your own audio before committing:
@@ -103,5 +277,6 @@ Test the difference on your own audio before committing:
[0BSD](LICENSE).
-Upstream components (DeepFilterNet, PyTorch, FFmpeg, uv)
-carry their own licenses
+Upstream components (ClearVoice, DeepFilterNet, Silero VAD, ONNX Runtime,
+PyTorch, FFmpeg, uv) carry their own licenses. Silero VAD is MIT-licensed:
+https://github.com/snakers4/silero-vad/tree/v5.1