aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 1d4328512ea75494ec640b190f5d12a79226654b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# Producer

Local speech cleanup and mastering for voice recordings. Noise removal uses `DeepFilterNet3`. Filtering, dynamics and loudness normalization are `FFmpeg`.

`producer.sh` bootstraps its own managed Python environments and downloads
dependencies and models automatically.

## Requirements

- glibc
- `uv` (or Python 3)
- NVidia driver and toolkit (optional)

## Usage

```bash
git clone https://git.historia.vg/git/producer
./producer.sh setup
./producer.sh recording.wav
```

First run installs the runtime into `lib/runtime/` and may take a few minutes.
The `process` keyword is optional; `./producer.sh process recording.wav` is
equivalent.

The master WAV is always **mono, 32-bit PCM**, at 48 kHz (default) or 44.1
kHz; stereo inputs must be downmixed to mono first. MP3 is encoded as
constant bitrate at 192 kb/s by default. Loudness is normalized to **-19
LUFS with a -1.5 dBTP true-peak ceiling**.

### Examples
```
# Optional MP3 alongside the WAV
./producer.sh recording.wav --mp3

# Other sound profiles
./producer.sh recording.wav --profile narrator
./producer.sh recording.wav --profile radio

# Process several files at once
./producer.sh take1.wav take2.wav --mp3

# Write outputs somewhere else
./producer.sh recording.wav --output-dir delivery --mp3

# Skip AI noise removal (FFT fallback or none at all)
./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)
./producer.sh recording.wav --denoiser clearvoice
./producer.sh setup --denoiser clearvoice --device cpu

# Shorten long gaps between takes (speech is never attenuated)
./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
./producer.sh recording.wav \
  --sample-rate 44100 --mp3 --mp3-bitrate 128 \
  --target-lufs -19 --true-peak-db -1.5
```

Edit default settings in `config.toml`

## Profiles

| Profile        | Sound                                                     |
| -------------- | --------------------------------------------------------- |
| `natural`      | Mild EQ, 2:1 compression, light de-essing (default)       |
| `narrator`     | Gentler compression, slower attack, wider loudness range  |
| `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.

Test the difference on your own audio before committing:

```bash
./producer.sh preview recording.wav --start 10 --duration 30
```

## Troubleshooting

- **Bootstrap fails:** the first run needs `uv` or Python 3 with venv support
  and network access to PyPI. Install the missing tool and rerun.
- **CUDA unavailable:** run `./producer.sh doctor`, check `nvidia-smi` and the
  driver, then retry `./producer.sh setup --device cuda`. Or use `--device cpu`.
- **Sounds watery or thin:** lower the denoise strength (`--denoise-strength
  0.65`) or compare profiles with `preview`.
- **Word attacks sound soft or ramp up:** AI denoisers can soften consonant
  onsets. Try `--denoiser clearvoice` (larger non-causal model that sees more
  attack context), lower `--denoise-strength`, or compare against
  `--no-denoise` to locate the culprit.

## License

[0BSD](LICENSE).

Upstream components (DeepFilterNet, PyTorch, FFmpeg, uv)
carry their own licenses