noisetool 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. noisetool-1.0.0/LICENSE +21 -0
  2. noisetool-1.0.0/PKG-INFO +497 -0
  3. noisetool-1.0.0/README.md +460 -0
  4. noisetool-1.0.0/pyproject.toml +80 -0
  5. noisetool-1.0.0/setup.cfg +4 -0
  6. noisetool-1.0.0/src/noise/__init__.py +36 -0
  7. noisetool-1.0.0/src/noise/__main__.py +4 -0
  8. noisetool-1.0.0/src/noise/analysis.py +176 -0
  9. noisetool-1.0.0/src/noise/cli.py +1439 -0
  10. noisetool-1.0.0/src/noise/completion.py +65 -0
  11. noisetool-1.0.0/src/noise/config.py +212 -0
  12. noisetool-1.0.0/src/noise/effects.py +292 -0
  13. noisetool-1.0.0/src/noise/eqviz.py +69 -0
  14. noisetool-1.0.0/src/noise/formats.py +66 -0
  15. noisetool-1.0.0/src/noise/generator.py +284 -0
  16. noisetool-1.0.0/src/noise/interactive.py +214 -0
  17. noisetool-1.0.0/src/noise/lufs.py +154 -0
  18. noisetool-1.0.0/src/noise/preview.py +87 -0
  19. noisetool-1.0.0/src/noise/py.typed +0 -0
  20. noisetool-1.0.0/src/noise/ui.py +92 -0
  21. noisetool-1.0.0/src/noise/utils.py +39 -0
  22. noisetool-1.0.0/src/noisetool.egg-info/PKG-INFO +497 -0
  23. noisetool-1.0.0/src/noisetool.egg-info/SOURCES.txt +44 -0
  24. noisetool-1.0.0/src/noisetool.egg-info/dependency_links.txt +1 -0
  25. noisetool-1.0.0/src/noisetool.egg-info/entry_points.txt +2 -0
  26. noisetool-1.0.0/src/noisetool.egg-info/requires.txt +16 -0
  27. noisetool-1.0.0/src/noisetool.egg-info/top_level.txt +1 -0
  28. noisetool-1.0.0/tests/test_analysis.py +87 -0
  29. noisetool-1.0.0/tests/test_cli.py +274 -0
  30. noisetool-1.0.0/tests/test_dsp.py +54 -0
  31. noisetool-1.0.0/tests/test_effects.py +83 -0
  32. noisetool-1.0.0/tests/test_eqviz.py +28 -0
  33. noisetool-1.0.0/tests/test_filters.py +57 -0
  34. noisetool-1.0.0/tests/test_formats.py +46 -0
  35. noisetool-1.0.0/tests/test_formats_ogg.py +25 -0
  36. noisetool-1.0.0/tests/test_generator.py +174 -0
  37. noisetool-1.0.0/tests/test_info.py +12 -0
  38. noisetool-1.0.0/tests/test_integration.py +186 -0
  39. noisetool-1.0.0/tests/test_interactive.py +45 -0
  40. noisetool-1.0.0/tests/test_loop.py +29 -0
  41. noisetool-1.0.0/tests/test_lufs.py +64 -0
  42. noisetool-1.0.0/tests/test_mix.py +48 -0
  43. noisetool-1.0.0/tests/test_naming.py +21 -0
  44. noisetool-1.0.0/tests/test_preview.py +49 -0
  45. noisetool-1.0.0/tests/test_silent.py +9 -0
  46. noisetool-1.0.0/tests/test_stereo.py +71 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 mrMaxwellTheCat
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,497 @@
1
+ Metadata-Version: 2.4
2
+ Name: noisetool
3
+ Version: 1.0.0
4
+ Summary: High-quality noise generator (white, pink, brown, blue, violet, grey) with LUFS normalization
5
+ Author-email: mrMaxwellTheCat <mrMaxwellTheCat@users.noreply.github.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/mrMaxwellTheCat/noisetool
8
+ Project-URL: Repository, https://github.com/mrMaxwellTheCat/noisetool
9
+ Project-URL: Issues, https://github.com/mrMaxwellTheCat/noisetool/issues
10
+ Keywords: noise,audio,white-noise,pink-noise,brown-noise,blue-noise,violet-noise,grey-noise,lufs,sound-synthesis
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: End Users/Desktop
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Sound Synthesis
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: numpy>=2.0
23
+ Requires-Dist: soundfile>=0.12
24
+ Requires-Dist: rich>=13.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=8.0; extra == "dev"
27
+ Requires-Dist: pytest-cov>=6.0; extra == "dev"
28
+ Requires-Dist: ruff>=0.9.0; extra == "dev"
29
+ Requires-Dist: mypy>=1.14.0; extra == "dev"
30
+ Requires-Dist: pre-commit>=4.0; extra == "dev"
31
+ Requires-Dist: pyyaml>=6.0; extra == "dev"
32
+ Requires-Dist: sounddevice>=0.4; extra == "dev"
33
+ Provides-Extra: build
34
+ Requires-Dist: build>=1.0; extra == "build"
35
+ Requires-Dist: twine>=6.0; extra == "build"
36
+ Dynamic: license-file
37
+
38
+ # noisetool
39
+
40
+ [![CI](https://github.com/mrMaxwellTheCat/noisetool/actions/workflows/ci.yml/badge.svg)](https://github.com/mrMaxwellTheCat/noisetool/actions/workflows/ci.yml)
41
+ [![PyPI version](https://img.shields.io/pypi/v/noisetool)](https://pypi.org/project/noisetool/)
42
+ [![Python versions](https://img.shields.io/pypi/pyversions/noisetool)](https://pypi.org/project/noisetool/)
43
+ [![License](https://img.shields.io/pypi/l/noisetool)](https://github.com/mrMaxwellTheCat/noisetool/blob/master/LICENSE)
44
+ [![Codecov](https://codecov.io/gh/mrMaxwellTheCat/noisetool/branch/master/graph/badge.svg)](https://codecov.io/gh/mrMaxwellTheCat/noisetool)
45
+
46
+ **High-quality noise generator** — Generate white, pink, brown, blue, violet, and grey noise audio files with LUFS loudness normalization, audio effects, analysis tools, and parallel batch processing.
47
+
48
+ ## Features
49
+
50
+ - **6 noise types** — White, pink (1/f), brown (1/f²), blue (√f), violet (f), grey (psychoacoustic)
51
+ - **Multi-format output** — WAV, FLAC, AIFF, OGG Vorbis, and raw PCM, in any combination
52
+ - **Stereo & mono** — Generate both simultaneously or pick one
53
+ - **ITU-R BS.1770-4 LUFS** — Loudness measurement and normalization to streaming/broadcast/podcast targets
54
+ - **Peak & RMS normalization** — Target peak dB level or RMS dBFS
55
+ - **16 audio effects** — DC blocker, fade-in/out, reverse, phase invert, low/high/band-pass filter, ADSR envelope, stereo width, pan, tremolo, bitcrush, dither, compressor
56
+ - **Analysis tools** — ASCII waveform preview, ASCII spectrum, EQ visualization, detailed stats table, JSON/CSV export
57
+ - **Audio playback** — Play generated audio through system output
58
+ - **File analysis** — Inspect existing audio files with `--info`
59
+ - **Custom blends** — Mix multiple noise types with weighted ratios
60
+ - **Loop mode** — Generate seamless looping noise with crossfade
61
+ - **Parallel generation** — Multi-threaded batch processing for all types/formats/channels
62
+ - **Continuous mode** — Generate noise indefinitely until Ctrl+C
63
+ - **Reproducible** — Set `--seed` or `--seeds` (comma-separated) for deterministic output
64
+ - **Custom filename patterns** — Use `{type}`, `{channels}`, `{format}`, `{sr}`, `{bits}`, `{seed}` variables
65
+ - **Interactive wizard** — Step-by-step UI with quick presets or full custom configuration
66
+ - **Config files** — JSON and YAML configs for repeatable batch generation
67
+ - **Shell completion** — Tab-completion for bash, zsh, fish
68
+ - **Dry-run mode** — Preview file list without writing anything
69
+ - **Benchmark** — Measure noise generator performance
70
+ - **Doctor** — System diagnostics (`--doctor`)
71
+ - **Docker** — Containerized execution
72
+ - **Rich terminal UI** — Color-coded output, progress bars, banners, and tables
73
+
74
+ ## Installation
75
+
76
+ ### pip (recommended)
77
+
78
+ ```bash
79
+ pip install noisetool
80
+ ```
81
+
82
+ ### pip with dev dependencies
83
+
84
+ ```bash
85
+ pip install "noisetool[dev]"
86
+ ```
87
+
88
+ ### From source
89
+
90
+ ```bash
91
+ git clone https://github.com/mrMaxwellTheCat/noisetool.git
92
+ cd noise
93
+ pip install -e ".[dev]"
94
+ ```
95
+
96
+ ### Docker
97
+
98
+ ```bash
99
+ docker build -t noisetool .
100
+ ```
101
+
102
+ See the [Docker section](#docker) below for usage.
103
+
104
+ ## Quick Start
105
+
106
+ ### Wizard mode (no arguments — interactive)
107
+
108
+ ```bash
109
+ noisetool
110
+ ```
111
+
112
+ Launches an interactive wizard. Choose **quick mode** (pick a preset: streaming, broadcast, podcast, quick, loop) or **custom mode** (select noise types, channels, duration, format, sample rate, loudness target, output folder).
113
+
114
+ ### CLI mode (with arguments)
115
+
116
+ ```bash
117
+ # Explicit CLI mode (pass any argument to skip the wizard)
118
+ noisetool --type white --mono -f wav --lufs -14
119
+
120
+ # Generate white noise only, mono, WAV, normalized to -14 LUFS
121
+ noisetool --type white --mono -f wav --lufs -14
122
+
123
+ # Generate pink noise at 96 kHz, 60 seconds, with seed for reproducibility
124
+ noisetool --type pink --duration 60 --sample-rate 96000 --seed 42
125
+
126
+ # Measure loudness without saving files
127
+ noisetool --measure
128
+
129
+ # Generate brown noise normalized to broadcast standard (-23 LUFS)
130
+ noisetool --type brown --lufs -23
131
+
132
+ # Apply fade and reverse effect
133
+ noisetool --type pink --fade-in 2 --fade-out 2 --reverse
134
+
135
+ # Show stats and spectrum visualization
136
+ noisetool --type white --stats --spectrum --duration 5
137
+
138
+ # List available noise types
139
+ noisetool --list
140
+
141
+ # Dry run (preview what would be generated)
142
+ noisetool --dry-run
143
+
144
+ # Verbose output for debugging
145
+ noisetool -v
146
+
147
+ # Generate all types in parallel with multiple workers
148
+ noisetool --parallel --workers 4
149
+
150
+ # Mix two noise types
151
+ noisetool --mix pink=0.7,white=0.3
152
+
153
+ # Inspect an existing audio file
154
+ noisetool --info audio/pink_noise.wav
155
+
156
+ # Run benchmark
157
+ noisetool --benchmark
158
+
159
+ # System diagnostics
160
+ noisetool --doctor
161
+ ```
162
+
163
+ ## Full CLI Reference
164
+
165
+ ### Noise Generation
166
+
167
+ | Argument | Description | Default |
168
+ |----------|-------------|---------|
169
+ | `-t, --type` | Noise type: `all`, `white`, `pink`, `brown`, `blue`, `violet`, `grey` | `all` |
170
+ | `-d, --duration` | Duration in seconds | `30` |
171
+ | `-r, --sample-rate` | Sample rate in Hz | `44100` |
172
+ | `--mono` | Generate mono audio only | stereo + mono |
173
+ | `--stereo` | Generate stereo audio only | stereo + mono |
174
+ | `--mix` | Mix multiple noise types with weights (e.g., `pink=0.7,white=0.3`) | off |
175
+ | `--seed` | Random seed for reproducible generation | random |
176
+ | `--seeds` | Generate with multiple seeds, comma-separated (e.g., `42,123,456`) | off |
177
+ | `--pattern` | Custom filename pattern (variables: `{type}`, `{channels}`, `{format}`, `{sr}`, `{bits}`, `{seed}`) | default naming |
178
+ | `-o, --output-dir` | Output directory | `audio/` |
179
+
180
+ ### Audio Format
181
+
182
+ | Argument | Description | Default |
183
+ |----------|-------------|---------|
184
+ | `-f, --format` | Output format: `all`, `wav`, `flac`, `aiff`, `ogg`, `raw` | `all` (wav + flac) |
185
+ | `--bit-depth` | Bit depth: `16`, `24`, `32` | `24` |
186
+ | `--loop` | Generate seamless looping noise (cross-fade start/end to avoid clicks) | off |
187
+
188
+ ### Loudness & Level
189
+
190
+ | Argument | Description | Default |
191
+ |----------|-------------|---------|
192
+ | `--lufs TARGET` | Target loudness in LUFS (e.g., `-14` for streaming, `-23` for broadcast) | off |
193
+ | `--peak LEVEL` | Peak normalize to target level in dB (e.g., `-1.0` to prevent clipping) | off |
194
+ | `--normalize TARGET` | Convenience: set loudness target (e.g., `-14`, `-23`, `-16`). Sets `--lufs` and `--peak -1` | off |
195
+ | `--rms DBFS` | RMS-normalize to target level in dBFS (e.g., `-18`) | off |
196
+ | `--measure` | Measure and display loudness of generated noise without saving files | off |
197
+
198
+ ### Effects & Processing
199
+
200
+ Effects are applied in this order: LUFS normalization → peak normalization → DC blocker → fade-in → fade-out → reverse → phase invert → lowpass → highpass → bandpass → ADSR envelope → loop crossfade → stereo width → pan → tremolo → bitcrush → dither → compressor → RMS normalization.
201
+
202
+ | Argument | Description | Format |
203
+ |----------|-------------|--------|
204
+ | `--dc-block` | Remove DC offset using a high-pass IIR filter (α = 0.995) | flag |
205
+ | `--fade-in SECONDS` | Linear fade-in at start | float |
206
+ | `--fade-out SECONDS` | Linear fade-out at end | float |
207
+ | `--reverse` | Reverse audio in time | flag |
208
+ | `--invert` | Invert phase (multiply by -1) | flag |
209
+ | `--lowpass HZ` | Low-pass filter cutoff frequency (FFT brickwall) | float |
210
+ | `--highpass HZ` | High-pass filter cutoff frequency (FFT brickwall) | float |
211
+ | `--bandpass LOW,HIGH` | Band-pass filter (e.g., `20,20000`) | `low,high` |
212
+ | `--envelope A,D,S,R` | ADSR envelope (e.g., `0.1,0.2,0.7,0.3`) | `attack,decay,sustain,release` |
213
+ | `--width WIDTH` | Stereo width (0=mono, 1=original, >1=wider) | float |
214
+ | `--pan PAN` | Pan position (-1=left, 0=center, 1=right) | float |
215
+ | `--tremolo RATE,DEPTH` | Amplitude modulation (e.g., `5,0.5`) | `rate_hz,depth` |
216
+ | `--bitcrush BITS` | Bitcrushing (1-24 bits) | int |
217
+ | `--dither BITS` | Dithering for target bit depth (e.g., `16`), with noise shaping | int |
218
+ | `--compressor THRESH,RATIO` | Dynamic range compression (e.g., `-20,4`) | `threshold_db,ratio` |
219
+
220
+ ### Output & Analysis
221
+
222
+ | Argument | Description |
223
+ |----------|-------------|
224
+ | `--preview` | Show ASCII waveform preview of generated audio |
225
+ | `--spectrum` | Show ASCII frequency spectrum visualization (FFT-based, Hanning windowed) |
226
+ | `--eq-viz` | Show EQ filter response plot |
227
+ | `--stats` | Show detailed audio statistics (duration, samples, channels, sample rate, bit depth, peak, peak dBFS, RMS, RMS dBFS, crest factor, DC offset) |
228
+ | `--json FILE` | Save audio statistics as JSON |
229
+ | `--csv FILE` | Save audio statistics as CSV |
230
+ | `--play` | Play audio through system output (requires `sounddevice`) |
231
+ | `--info FILE` | Show detailed info about an existing audio file |
232
+ | `--list` | List available noise types with descriptions and exit |
233
+ | `--benchmark` | Run performance benchmark of all noise generators and exit |
234
+ | `--dry-run` | Show what would be generated without creating files |
235
+
236
+ ### Operation Mode
237
+
238
+ | Argument | Description | Default |
239
+ |----------|-------------|---------|
240
+ | `--parallel` | Generate files in parallel using multiple threads | off |
241
+ | `--workers N` | Number of worker threads for parallel generation | CPU count |
242
+ | `--continuous` | Generate noise continuously until Ctrl+C interrupted | off |
243
+ | `-i, --interactive` | Force interactive wizard mode | auto if no args |
244
+
245
+ ### Configuration
246
+
247
+ | Argument | Description |
248
+ |----------|-------------|
249
+ | `--config FILE` | Load generation config from JSON or YAML file |
250
+ | `--example-config FILE` | Write an example config file (JSON or YAML, inferred from extension) and exit |
251
+ | `--generate-completion SHELL` | Generate shell completion script: `bash`, `zsh`, or `fish` |
252
+ | `--preset NAME` | Apply a preset configuration: `streaming`, `broadcast`, `podcast`, `quick`, `loop` |
253
+
254
+ ### Logging & Display
255
+
256
+ | Argument | Description | Default |
257
+ |----------|-------------|---------|
258
+ | `-v, --verbose` | Enable verbose / debug output | off |
259
+ | `--silent` | Suppress all terminal output except errors | off |
260
+ | `--progress` | Progress display style: `rich`, `simple`, `none` | `rich` |
261
+ | `--log-file FILE` | Write log output to a file in addition to stderr | off |
262
+ | `--no-banner` | Suppress the startup banner | off |
263
+ | `--doctor` | Run system diagnostics and exit | off |
264
+ | `--version` | Show version and exit | off |
265
+
266
+ ## Noise Types
267
+
268
+ | Type | Description | Spectrum | Generation Method |
269
+ |------|-------------|----------|-------------------|
270
+ | `white` | Flat power spectrum across all frequencies | Flat | Uniform random samples in [-1, 1] |
271
+ | `pink` | Power decreases 3 dB/octave (1/f spectrum) | −3 dB/octave | FFT frequency-domain filtering with `1/√f` filter |
272
+ | `brown` | Power decreases 6 dB/octave (1/f² spectrum) | −6 dB/octave | Cumulative sum (integration) of white noise |
273
+ | `blue` | Power increases 3 dB/octave (rising spectrum) | +3 dB/octave | FFT frequency-domain filtering with `√f` filter |
274
+ | `violet` | Power increases 6 dB/octave (rising spectrum) | +6 dB/octave | FFT frequency-domain filtering with `f` filter |
275
+ | `grey` | Psychoacoustic equal-loudness noise | Perceptually flat | FFT filtering with `1/(1+(f/2000)²)` filter |
276
+
277
+ ## Interactive Wizard
278
+
279
+ Running `noisetool` with no arguments launches the interactive wizard.
280
+
281
+ ### Quick mode
282
+
283
+ Select from 5 presets:
284
+
285
+ | Preset | Type | Duration | Sample Rate | Bit Depth | LUFS | Format |
286
+ |--------|------|----------|-------------|-----------|------|--------|
287
+ | `streaming` | all | 30s | 48000 | 24 | -14 | all |
288
+ | `broadcast` | all | 30s | 48000 | 24 | -23 | all |
289
+ | `podcast` | pink | 10s | 44100 | 16 | -16 | wav (mono) |
290
+ | `quick` | pink | 5s | 44100 | 16 | — | wav (mono) |
291
+ | `loop` | pink | 10s | 44100 | 24 | — | flac |
292
+
293
+ Then choose an output folder.
294
+
295
+ ### Custom mode
296
+
297
+ Step through every option:
298
+
299
+ 1. **Noise Types** — Select by number (1=white, 2=pink, 3=brown, 4=blue, 5=violet, 6=grey), comma-separated, or `all`
300
+ 2. **Channels** — Stereo, Mono, or Both
301
+ 3. **Duration** — Seconds (set `0` for continuous generation)
302
+ 4. **Format** — WAV, FLAC, OGG, MP3 (saved as WAV), or WAV+FLAC, with quality/bit-depth/compression setting
303
+ 5. **Sample Rate** — 44100, 48000, 96000, or 192000 Hz
304
+ 6. **Loudness** — None, streaming (-14 LUFS), broadcast (-23 LUFS), podcast (-16 LUFS), or custom
305
+ 7. **Output Folder** — Default `audio/`
306
+
307
+ ## LUFS Loudness Normalization
308
+
309
+ Implements **ITU-R BS.1770-4** for integrated loudness measurement using K-weighting (pre-filter + RLB weighting) with two IIR filter stages.
310
+
311
+ ### Common targets
312
+
313
+ | Target | Standard | Use Case |
314
+ |--------|----------|----------|
315
+ | **−14 LUFS** | Streaming | YouTube, Spotify, Apple Music, Tidal |
316
+ | **−16 LUFS** | Podcasts | Podcast loudness standard |
317
+ | **−23 LUFS** | Broadcast | EBU R128, ATSC A/85 (TV, radio) |
318
+ | **−18 LUFS** | Film | Cinema trailer and film mixing |
319
+
320
+ If normalization causes clipping, the signal is automatically limited to prevent distortion.
321
+
322
+ ## Config File Example
323
+
324
+ ```json
325
+ {
326
+ "type": "all",
327
+ "duration": 30.0,
328
+ "sample_rate": 44100,
329
+ "channels": [1, 2],
330
+ "formats": ["wav", "flac"],
331
+ "bit_depth": 24,
332
+ "lufs": -14.0,
333
+ "peak": -1.0,
334
+ "rms": null,
335
+ "seed": 42,
336
+ "seeds": null,
337
+ "output_dir": "audio",
338
+ "mono": false,
339
+ "stereo": false,
340
+ "mix": "pink=0.7,white=0.3",
341
+ "pattern": null,
342
+ "loop": false,
343
+ "parallel": false,
344
+ "workers": null,
345
+ "continuous": false,
346
+ "dc_block": false,
347
+ "fade_in": 0.1,
348
+ "fade_out": 0.3,
349
+ "reverse": false,
350
+ "invert": false,
351
+ "lowpass": null,
352
+ "highpass": null,
353
+ "bandpass": null,
354
+ "envelope": null,
355
+ "width": null,
356
+ "pan": null,
357
+ "tremolo": null,
358
+ "bitcrush": null,
359
+ "dither": null,
360
+ "compressor": null,
361
+ "preview": false,
362
+ "spectrum": false,
363
+ "eq_viz": false,
364
+ "stats": false,
365
+ "play": false,
366
+ "dry_run": false,
367
+ "silent": false,
368
+ "progress": "rich"
369
+ }
370
+ ```
371
+
372
+ YAML configs are also supported (requires `pyyaml`):
373
+
374
+ ```bash
375
+ noisetool --example-config config.yaml
376
+ noisetool --config config.yaml
377
+ ```
378
+
379
+ ## Shell Completion
380
+
381
+ ```bash
382
+ # Bash
383
+ noisetool --generate-completion bash >> ~/.bashrc
384
+
385
+ # Zsh
386
+ noisetool --generate-completion zsh >> ~/.zshrc
387
+
388
+ # Fish
389
+ noisetool --generate-completion fish > ~/.config/fish/completions/noisetool.fish
390
+ ```
391
+
392
+ Completion scripts provide tab-completion for all options, noise types, formats, bit depths, and file paths.
393
+
394
+ ## Output Files
395
+
396
+ Generated audio files follow this naming convention (default pattern):
397
+
398
+ ```
399
+ audio/
400
+ ├── white_noise.wav / white_noise.flac (stereo)
401
+ ├── white_noise_mono.wav / white_noise_mono.flac (mono)
402
+ ├── pink_noise.wav / pink_noise.flac
403
+ ├── pink_noise_mono.wav / pink_noise_mono.flac
404
+ ├── brown_noise.wav / brown_noise.flac
405
+ ├── brown_noise_mono.wav / brown_noise_mono.flac
406
+ ├── blue_noise.wav / blue_noise.flac
407
+ ├── blue_noise_mono.wav / blue_noise_mono.flac
408
+ ├── violet_noise.wav / violet_noise.flac
409
+ ├── violet_noise_mono.wav / violet_noise_mono.flac
410
+ ├── grey_noise.wav / grey_noise.flac
411
+ └── grey_noise_mono.wav / grey_noise_mono.flac
412
+ ```
413
+
414
+ Use `--pattern` for custom filenames, e.g.:
415
+
416
+ ```bash
417
+ noisetool --pattern "{type}_{channels}_{format}_{sr}hz_{bits}bit"
418
+ ```
419
+
420
+ ## Docker
421
+
422
+ ```bash
423
+ # Build the image
424
+ docker build -t noisetool .
425
+
426
+ # List available noise types
427
+ docker run --rm noisetool --list
428
+
429
+ # Generate noise and save to host directory
430
+ docker run --rm -v "$PWD/audio:/audio" noisetool -o /audio
431
+
432
+ # Generate white noise, mono, WAV only
433
+ docker run --rm -v "$PWD/audio:/audio" noisetool --type white --mono -f wav -o /audio
434
+
435
+ # Run with Docker diagnostics
436
+ docker run --rm noisetool --doctor
437
+ ```
438
+
439
+ The Docker image uses a multi-stage build for minimal size (slim Python image + libsndfile1).
440
+
441
+ ## Development
442
+
443
+ ```bash
444
+ # Install with dev dependencies
445
+ pip install -e ".[dev]"
446
+
447
+ # Run tests
448
+ pytest tests/ -v
449
+
450
+ # Lint with ruff
451
+ ruff check .
452
+ ruff format .
453
+
454
+ # Type check with mypy
455
+ mypy src/
456
+
457
+ # Pre-commit hooks
458
+ pre-commit install
459
+ pre-commit run --all-files
460
+
461
+ # Build distribution packages
462
+ python -m build
463
+ ```
464
+
465
+ ### Project structure
466
+
467
+ ```
468
+ src/noise/
469
+ ├── __init__.py # Version
470
+ ├── cli.py # CLI argument parsing and main orchestration
471
+ ├── interactive.py # Interactive wizard (quick + custom modes)
472
+ ├── generator.py # 6 noise generators + mix function
473
+ ├── effects.py # 16 audio effects
474
+ ├── formats.py # AIFF, OGG, RAW savers
475
+ ├── utils.py # WAV, FLAC savers, constants
476
+ ├── lufs.py # ITU-R BS.1770-4 loudness measurement + normalization
477
+ ├── analysis.py # AudioStats, ASCII spectrum, JSON/CSV export
478
+ ├── preview.py # ASCII waveform visualization
479
+ ├── config.py # Config file loading (JSON/YAML)
480
+ ├── completion.py # Shell completion script
481
+ └── ui.py # Rich terminal output components
482
+ ```
483
+
484
+ ## CI/CD
485
+
486
+ The project runs on GitHub Actions across **Python 3.10–3.14**:
487
+
488
+ - **Lint**: `ruff check` with selected rules (E, F, I, N, W, UP, B, SIM, ARG, C4)
489
+ - **Format**: `ruff format --check`
490
+ - **Type check**: `mypy` strict mode
491
+ - **Test**: `pytest` with coverage (pytest-cov)
492
+ - **Coverage**: Uploaded to Codecov
493
+ - **Publish**: On tagged releases, builds and publishes to PyPI via `pypa/gh-action-pypi-publish`
494
+
495
+ ## License
496
+
497
+ MIT