sipstuff 0.0.2__tar.gz → 0.0.4__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 (45) hide show
  1. {sipstuff-0.0.2 → sipstuff-0.0.4}/PKG-INFO +295 -270
  2. {sipstuff-0.0.2 → sipstuff-0.0.4}/README.md +288 -263
  3. {sipstuff-0.0.2 → sipstuff-0.0.4}/pyproject.toml +5 -5
  4. sipstuff-0.0.4/sipstuff/README.md +1117 -0
  5. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/__init__.py +11 -8
  6. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/cli.py +123 -104
  7. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/realtime/README.md +7 -7
  8. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/sip_account.py +4 -0
  9. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/sip_call.py +9 -6
  10. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/sip_caller.py +5 -1
  11. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/sip_endpoint.py +3 -0
  12. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/sipconfig.py +202 -28
  13. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/stt/stt.py +13 -1
  14. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/training/README.md +4 -0
  15. sipstuff-0.0.4/sipstuff/training/convert_metadata_rhasspypiper_to_piper1gpl.py +65 -0
  16. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/training/record_gui.py +265 -63
  17. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/tts/live.py +59 -35
  18. sipstuff-0.0.2/sipstuff/README.md +0 -1105
  19. {sipstuff-0.0.2 → sipstuff-0.0.4}/.gitignore +0 -0
  20. {sipstuff-0.0.2 → sipstuff-0.0.4}/LICENSE.md +0 -0
  21. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/audio.py +0 -0
  22. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/autoanswer/README.md +0 -0
  23. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/autoanswer/__init__.py +0 -0
  24. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/autoanswer/pjsip_autoanswer_tts_n_wav.py +0 -0
  25. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/autoanswer/py.typed +0 -0
  26. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/py.typed +0 -0
  27. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/realtime/__init__.py +0 -0
  28. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/realtime/pjsip_realtime_tts.py +0 -0
  29. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/realtime/py.typed +0 -0
  30. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/sip_callee.py +0 -0
  31. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/sip_media.py +0 -0
  32. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/sip_types.py +0 -0
  33. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/snddevice_list.py +0 -0
  34. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/stt/__init__.py +0 -0
  35. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/stt/live.py +0 -0
  36. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/stt/py.typed +0 -0
  37. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/training/__init__.py +0 -0
  38. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/training/py.typed +0 -0
  39. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/training/record_dataset.py +0 -0
  40. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/transcribe/README.md +0 -0
  41. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/transcribe/__init__.py +0 -0
  42. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/transcribe/pjsip_live_transcribe.py +0 -0
  43. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/tts/__init__.py +0 -0
  44. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/tts/py.typed +0 -0
  45. {sipstuff-0.0.2 → sipstuff-0.0.4}/sipstuff/tts/tts.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: sipstuff
3
- Version: 0.0.2
3
+ Version: 0.0.4
4
4
  Summary: SIP telephony automation toolkit: place calls via PJSIP, play WAV/TTS audio, record and transcribe responses
5
5
  Project-URL: Homepage, https://github.com/vroomfondel/sipstuff
6
6
  Project-URL: Repository, https://github.com/vroomfondel/sipstuff
@@ -18,15 +18,15 @@ Classifier: Topic :: Communications :: Telephony
18
18
  Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
19
19
  Requires-Python: >=3.14
20
20
  Requires-Dist: faster-whisper
21
- Requires-Dist: loguru>=0.7.0
21
+ Requires-Dist: loguru>=0.7.3
22
22
  Requires-Dist: numpy
23
- Requires-Dist: piper-tts>=1.4.0
24
- Requires-Dist: pydantic>=2.10.0
25
- Requires-Dist: pyyaml>=6.0
23
+ Requires-Dist: piper-tts>=1.8.0
24
+ Requires-Dist: pydantic>=2.14.2
25
+ Requires-Dist: pyyaml>=6.0.3
26
26
  Requires-Dist: ruamel-yaml
27
27
  Requires-Dist: sounddevice
28
28
  Requires-Dist: soundfile
29
- Requires-Dist: tabulate>=0.9.0
29
+ Requires-Dist: tabulate>=0.10.0
30
30
  Provides-Extra: cuda
31
31
  Requires-Dist: nvidia-cublas-cu12; extra == 'cuda'
32
32
  Requires-Dist: nvidia-cudnn-cu12; extra == 'cuda'
@@ -42,6 +42,7 @@ Description-Content-Type: text/markdown
42
42
  [![black-lint](https://github.com/vroomfondel/sipstuff/actions/workflows/checkblack.yml/badge.svg)](https://github.com/vroomfondel/sipstuff/actions/workflows/checkblack.yml)
43
43
  ![Cumulative Clones](https://img.shields.io/endpoint?logo=github&url=https://gist.githubusercontent.com/vroomfondel/92ea75186bc004c1125824335f69a821/raw/sipstuff_clone_count.json)
44
44
  [![Docker Pulls](https://img.shields.io/docker/pulls/xomoxcc/sipstuff?logo=docker)](https://hub.docker.com/r/xomoxcc/sipstuff/tags)
45
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/sipstuff?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=PyPi+Downloads)](https://pepy.tech/projects/sipstuff)
45
46
  [![PyPI](https://img.shields.io/pypi/v/sipstuff?logo=pypi&logoColor=white)](https://pypi.org/project/sipstuff/)
46
47
 
47
48
  [![Gemini_Generated_Image_cpliijcpliijcpli_250x250.png](https://raw.githubusercontent.com/vroomfondel/sipstuff/main/Gemini_Generated_Image_cpliijcpliijcpli_250x250.png)](https://hub.docker.com/r/xomoxcc/sipstuff/tags)
@@ -179,18 +180,18 @@ The `--json` flag outputs structured JSON including segment timestamps, audio du
179
180
  }
180
181
  ```
181
182
 
182
- | Flag | Description |
183
- |------|-------------|
184
- | `wav` (positional) | Path to WAV file to transcribe |
185
- | `--backend` | STT backend: `faster-whisper` (default) or `openvino` |
186
- | `--model`, `-m` | Whisper model size or HuggingFace model ID (default: `medium`) |
187
- | `--language`, `-l` | Language code (default: `de`) |
188
- | `--device` | Compute device: `cpu` or `cuda` (default: `cpu`) |
189
- | `--compute-type` | Quantization: `int8`, `float16`, `float32` (auto-selected by default) |
190
- | `--data-dir` | Directory for Whisper models (default: `~/.local/share/faster-whisper-models`) |
191
- | `--json` | Output result as JSON with metadata and segment timestamps |
192
- | `--no-vad` | Disable Silero VAD pre-filtering (VAD is on by default, recommended for phone recordings) |
193
- | `--verbose`, `-v` | Debug logging |
183
+ | Flag | Description |
184
+ |--------------------|-------------------------------------------------------------------------------------------|
185
+ | `wav` (positional) | Path to WAV file to transcribe |
186
+ | `--backend` | STT backend: `faster-whisper` (default) or `openvino` |
187
+ | `--model`, `-m` | Whisper model size or HuggingFace model ID (default: `medium`) |
188
+ | `--language`, `-l` | Language code (default: `de`) |
189
+ | `--device` | Compute device: `cpu` or `cuda` (default: `cpu`) |
190
+ | `--compute-type` | Quantization: `int8`, `float16`, `float32` (auto-selected by default) |
191
+ | `--data-dir` | Directory for Whisper models (default: `~/.local/share/faster-whisper-models`) |
192
+ | `--json` | Output result as JSON with metadata and segment timestamps |
193
+ | `--no-vad` | Disable Silero VAD pre-filtering (VAD is on by default, recommended for phone recordings) |
194
+ | `--verbose`, `-v` | Debug logging |
194
195
 
195
196
  ### `call` — Place a SIP Call
196
197
 
@@ -212,7 +213,7 @@ python -m sipstuff.cli call \
212
213
  --server pbx.local --user 1000 --password secret \
213
214
  --dest +491234567890 \
214
215
  --text "Achtung! Wasserstand kritisch!" \
215
- --tts-model de_DE-thorsten-high --tts-sample-rate 8000
216
+ --piper-model de_DE-thorsten-high --tts-sample-rate 8000
216
217
 
217
218
  # Wait for callee to finish speaking before playback
218
219
  python -m sipstuff.cli call \
@@ -271,7 +272,7 @@ python -m sipstuff.cli call \
271
272
  --server 192.168.1.100 --user 1001 --password secret \
272
273
  --dest +491234567890 \
273
274
  --interactive \
274
- --piper-model /path/to/de_DE-thorsten-high.onnx \
275
+ --piper-live-model de_DE-thorsten-high \
275
276
  --text "Hallo, hier spricht die Maschine." \
276
277
  --play-audio --play-tx --real-capture -v
277
278
 
@@ -295,102 +296,105 @@ When `--transcribe` is used with `--record`, a JSON call report is written next
295
296
 
296
297
  **SIP connection:**
297
298
 
298
- | Flag | Description |
299
- |------|-------------|
300
- | `--config`, `-c` | Path to YAML config file |
301
- | `--server`, `-s` | PBX hostname or IP |
302
- | `--port`, `-p` | SIP port (default: 5060) |
303
- | `--user`, `-u` | SIP extension / username |
304
- | `--password` | SIP password |
305
- | `--transport` | `udp`, `tcp`, or `tls` (default: udp) |
306
- | `--srtp` | `disabled`, `optional`, or `mandatory` (default: disabled) |
307
- | `--tls-verify` | Verify TLS server certificate |
308
- | `--dest`, `-d` | Destination phone number or SIP URI (required) |
309
- | `--timeout`, `-t` | Call timeout in seconds (default: 60) |
299
+ | Flag | Description |
300
+ |----------------------|------------------------------------------------------------|
301
+ | `--config`, `-c` | Path to YAML config file |
302
+ | `--server`, `-s` | PBX hostname or IP |
303
+ | `--port`, `-p` | SIP port (default: 5060) |
304
+ | `--user`, `-u` | SIP extension / username |
305
+ | `--password` | SIP password |
306
+ | `--transport` | `udp`, `tcp`, or `tls` (default: udp) |
307
+ | `--srtp` | `disabled`, `optional`, or `mandatory` (default: disabled) |
308
+ | `--tls-verify` | Verify TLS server certificate |
309
+ | `--rtp-port` | RTP start port, 0 = OS-assigned (default: 4000) |
310
+ | `--rtp-port-range` | RTP port window width (default: 200) |
311
+ | `--no-rtp-randomize` | Always start at `--rtp-port` instead of a random offset |
312
+ | `--dest`, `-d` | Destination phone number or SIP URI (required) |
313
+ | `--timeout`, `-t` | Call timeout in seconds (default: 60) |
310
314
 
311
315
  **Audio source (mutually exclusive):**
312
316
 
313
- | Flag | Description |
314
- |------|-------------|
315
- | `--wav`, `-w` | Path to WAV file to play (mutually exclusive with `--interactive`) |
316
- | `--interactive` | Interactive live TTS mode: type text in the console that gets spoken via Piper TTS during the call (mutually exclusive with `--wav`, requires `--piper-model`) |
317
+ | Flag | Description |
318
+ |-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
319
+ | `--wav`, `-w` | Path to WAV file to play (mutually exclusive with `--interactive`) |
320
+ | `--interactive` | Interactive live TTS mode: type text in the console that gets spoken via Piper TTS during the call (mutually exclusive with `--wav`, requires `--piper-live-model`) |
317
321
 
318
322
  **TTS:**
319
323
 
320
- | Flag | Description |
321
- |------|-------------|
322
- | `--text` | Text to synthesize via piper TTS, or initial greeting in interactive mode |
323
- | `--tts-model` | Piper voice model for pre-generated TTS (default: `de_DE-thorsten-high`) |
324
- | `--piper-model` | Path to Piper `.onnx` model for live TTS in interactive mode |
325
- | `--tts-sample-rate` | Resample TTS output to this rate in Hz (default: native/22050) |
326
- | `--tts-data-dir` | Directory for piper voice models (default: `~/.local/share/piper-voices`) |
327
- | `--tts-cuda` | Use CUDA GPU acceleration for Piper TTS |
324
+ | Flag | Description |
325
+ |----------------------|---------------------------------------------------------------------------|
326
+ | `--text` | Text to synthesize via piper TTS, or initial greeting in interactive mode |
327
+ | `--piper-model` | Piper voice model for pre-generated TTS (default: `de_DE-thorsten-high`) |
328
+ | `--piper-live-model` | Piper voice model for live TTS in interactive mode |
329
+ | `--tts-sample-rate` | Resample TTS output to this rate in Hz (default: native/22050) |
330
+ | `--tts-data-dir` | Directory for piper voice models (default: `~/.local/share/piper-voices`) |
331
+ | `--tts-cuda` | Use CUDA GPU acceleration for Piper TTS |
328
332
 
329
333
  **Playback timing:**
330
334
 
331
- | Flag | Description |
332
- |------|-------------|
333
- | `--pre-delay` | Seconds to wait after answer before playback (default: 0) |
334
- | `--post-delay` | Seconds to wait after playback before hangup (default: 0) |
335
- | `--inter-delay` | Seconds to wait between WAV repeats (default: 0) |
336
- | `--repeat` | Number of times to play the WAV (default: 1) |
335
+ | Flag | Description |
336
+ |----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
337
+ | `--pre-delay` | Seconds to wait after answer before playback (default: 0) |
338
+ | `--post-delay` | Seconds to wait after playback before hangup (default: 0) |
339
+ | `--inter-delay` | Seconds to wait between WAV repeats (default: 0) |
340
+ | `--repeat` | Number of times to play the WAV (default: 1) |
337
341
  | `--wait-for-silence` | Wait for N seconds of remote silence before playback (e.g. `1.0` to let callee finish "Hello?"). Uses `SilenceDetector` on the incoming audio RMS. Applied after `--pre-delay`. |
338
342
 
339
343
  **Recording & transcription:**
340
344
 
341
- | Flag | Description |
342
- |------|-------------|
343
- | `--record` | Record remote-party (RX) audio to this WAV file path (parent dirs created automatically) |
344
- | `--record-tx` | Record local (TX) audio to this WAV file path |
345
- | `--mix-mode` | Post-call mix mode: `none`, `mono`, or `stereo` (requires `--record` + `--record-tx`) |
346
- | `--mix-output` | Output path for the RX+TX mix file |
347
- | `--transcribe` | Transcribe recorded audio via STT and write a JSON call report (requires `--record`) |
348
- | `--live-transcribe` | Live STT of remote audio during the call (real-time output to console) |
349
- | `--stt-backend` | STT backend: `faster-whisper` (default) or `openvino` |
350
- | `--stt-model` | Whisper model size for transcription (default: `medium`) |
351
- | `--stt-language` | Language code for STT transcription (default: from config, then `de`) |
352
- | `--stt-data-dir` | Directory for Whisper STT models (default: `~/.local/share/faster-whisper-models`) |
345
+ | Flag | Description |
346
+ |---------------------|------------------------------------------------------------------------------------------|
347
+ | `--record` | Record remote-party (RX) audio to this WAV file path (parent dirs created automatically) |
348
+ | `--record-tx` | Record local (TX) audio to this WAV file path |
349
+ | `--mix-mode` | Post-call mix mode: `none`, `mono`, or `stereo` (requires `--record` + `--record-tx`) |
350
+ | `--mix-output` | Output path for the RX+TX mix file |
351
+ | `--transcribe` | Transcribe recorded audio via STT and write a JSON call report (requires `--record`) |
352
+ | `--live-transcribe` | Live STT of remote audio during the call (real-time output to console) |
353
+ | `--stt-backend` | STT backend: `faster-whisper` (default) or `openvino` |
354
+ | `--stt-model` | Whisper model size for transcription (default: `medium`) |
355
+ | `--stt-language` | Language code for STT transcription (default: from config, then `de`) |
356
+ | `--stt-data-dir` | Directory for Whisper STT models (default: `~/.local/share/faster-whisper-models`) |
353
357
 
354
358
  **Live VAD (for `--live-transcribe`):**
355
359
 
356
- | Flag | Description |
357
- |------|-------------|
358
- | `--vad-silence-threshold` | RMS silence threshold (default: 0.01) |
359
- | `--vad-silence-trigger` | Seconds of silence to trigger chunk boundary (default: 0.3) |
360
- | `--vad-max-chunk` | Max seconds per audio chunk (default: 5.0) |
361
- | `--vad-min-chunk` | Min seconds per audio chunk (default: 0.5) |
360
+ | Flag | Description |
361
+ |---------------------------|-------------------------------------------------------------|
362
+ | `--vad-silence-threshold` | RMS silence threshold (default: 0.01) |
363
+ | `--vad-silence-trigger` | Seconds of silence to trigger chunk boundary (default: 0.3) |
364
+ | `--vad-max-chunk` | Max seconds per audio chunk (default: 5.0) |
365
+ | `--vad-min-chunk` | Min seconds per audio chunk (default: 0.5) |
362
366
 
363
367
  **Audio device:**
364
368
 
365
- | Flag | Description |
366
- |------|-------------|
367
- | `--no-null-audio` | Use real audio devices instead of null device for both directions |
368
- | `--real-capture` | Use real microphone even when playback stays null |
369
- | `--real-playback` | Use real speaker even when capture stays null |
370
- | `--play-audio` | Play remote-party (RX) audio on local speakers via sounddevice |
371
- | `--play-tx` | Route local (TX) audio to output sinks; stereo with RX when combined with `--play-audio` |
372
- | `--no-play-rx` | Disable routing of RX audio to output sinks |
373
- | `--audio-device` | Sounddevice output device (index or name substring) |
374
- | `--audio-socket` | Unix socket path for live PCM streaming (16 kHz, S16_LE, mono) |
369
+ | Flag | Description |
370
+ |-------------------|------------------------------------------------------------------------------------------|
371
+ | `--no-null-audio` | Use real audio devices instead of null device for both directions |
372
+ | `--real-capture` | Use real microphone even when playback stays null |
373
+ | `--real-playback` | Use real speaker even when capture stays null |
374
+ | `--play-audio` | Play remote-party (RX) audio on local speakers via sounddevice |
375
+ | `--play-tx` | Route local (TX) audio to output sinks; stereo with RX when combined with `--play-audio` |
376
+ | `--no-play-rx` | Disable routing of RX audio to output sinks |
377
+ | `--audio-device` | Sounddevice output device (index or name substring) |
378
+ | `--audio-socket` | Unix socket path for live PCM streaming (16 kHz, S16_LE, mono) |
375
379
 
376
380
  **NAT traversal:**
377
381
 
378
- | Flag | Description |
379
- |------|-------------|
380
- | `--stun-servers` | Comma-separated STUN servers (e.g. `stun.l.google.com:19302`) |
381
- | `--ice` | Enable ICE for media NAT traversal |
382
- | `--turn-server` | TURN relay server (`host:port`) |
383
- | `--turn-username` | TURN username |
384
- | `--turn-password` | TURN password |
385
- | `--turn-transport` | TURN transport: `udp`, `tcp`, or `tls` (default: udp) |
386
- | `--keepalive` | UDP keepalive interval in seconds (0 = disabled) |
387
- | `--public-address` | Public IP to advertise in SDP/Contact (e.g. K3s node IP) |
382
+ | Flag | Description |
383
+ |--------------------|---------------------------------------------------------------|
384
+ | `--stun-servers` | Comma-separated STUN servers (e.g. `stun.l.google.com:19302`) |
385
+ | `--ice` | Enable ICE for media NAT traversal |
386
+ | `--turn-server` | TURN relay server (`host:port`) |
387
+ | `--turn-username` | TURN username |
388
+ | `--turn-password` | TURN password |
389
+ | `--turn-transport` | TURN transport: `udp`, `tcp`, or `tls` (default: udp) |
390
+ | `--keepalive` | UDP keepalive interval in seconds (0 = disabled) |
391
+ | `--public-address` | Public IP to advertise in SDP/Contact (e.g. K3s node IP) |
388
392
 
389
393
  **Logging:**
390
394
 
391
- | Flag | Description |
392
- |------|-------------|
393
- | `--verbose`, `-v` | Debug logging |
395
+ | Flag | Description |
396
+ |---------------------|---------------------------------------|
397
+ | `--verbose`, `-v` | Debug logging |
394
398
  | `--pjsip-log-level` | PJSIP log verbosity (0–6, default: 3) |
395
399
 
396
400
  ### `callee_autoanswer` — Auto-Answer Incoming Calls
@@ -421,23 +425,23 @@ python -m sipstuff.cli callee_autoanswer \
421
425
  --answer-delay 2.0
422
426
  ```
423
427
 
424
- | Flag | Description |
425
- |------|-------------|
426
- | `--mode` | Playback mode: `none`, `wav`, or `tts` (default: `none`) |
427
- | `--wav-file` | WAV file to play (requires `--mode wav`) |
428
- | `--tts-text` | Text for TTS (requires `--mode tts`) |
429
- | `--piper-model` | Piper voice model (default: `de_DE-thorsten-high`) |
430
- | `--tts-data-dir` | Piper data directory |
431
- | `--start-wav` | WAV file to play at call start |
432
- | `--end-wav` | WAV file to play before hangup |
433
- | `--pause-before-start` | Pause before start WAV (default: 0.0 s) |
434
- | `--pause-before-content` | Pause before content WAV/TTS (default: 0.0 s) |
435
- | `--pause-before-end` | Pause before end WAV (default: 0.0 s) |
436
- | `--answer-delay` | Seconds before answering (default: 1.0) |
437
- | `--tts-cuda` | Use CUDA GPU acceleration for Piper TTS |
438
- | `--no-auto-answer` | Do not auto-answer calls |
439
-
440
- Shared flags: `--config`, `--server`, `--port`, `--user`, `--password`, `--transport`, `--srtp`, `--tls-verify`, `--local-port`, NAT traversal group, `--verbose`, `--pjsip-log-level`
428
+ | Flag | Description |
429
+ |--------------------------|----------------------------------------------------------|
430
+ | `--mode` | Playback mode: `none`, `wav`, or `tts` (default: `none`) |
431
+ | `--wav-file` | WAV file to play (requires `--mode wav`) |
432
+ | `--tts-text` | Text for TTS (requires `--mode tts`) |
433
+ | `--piper-model` | Piper voice model (default: `de_DE-thorsten-high`) |
434
+ | `--tts-data-dir` | Piper data directory |
435
+ | `--start-wav` | WAV file to play at call start |
436
+ | `--end-wav` | WAV file to play before hangup |
437
+ | `--pause-before-start` | Pause before start WAV (default: 0.0 s) |
438
+ | `--pause-before-content` | Pause before content WAV/TTS (default: 0.0 s) |
439
+ | `--pause-before-end` | Pause before end WAV (default: 0.0 s) |
440
+ | `--answer-delay` | Seconds before answering (default: 1.0) |
441
+ | `--tts-cuda` | Use CUDA GPU acceleration for Piper TTS |
442
+ | `--no-auto-answer` | Do not auto-answer calls |
443
+
444
+ Shared flags: `--config`, `--server`, `--port`, `--user`, `--password`, `--transport`, `--srtp`, `--tls-verify`, `--rtp-port`, `--rtp-port-range`, `--no-rtp-randomize`, `--local-port`, NAT traversal group, `--verbose`, `--pjsip-log-level`
441
445
 
442
446
  ### `callee_realtime-tts` — Incoming Call with Live TTS
443
447
 
@@ -448,67 +452,67 @@ Answer incoming calls and speak text in real-time via Piper TTS:
448
452
  python -m sipstuff.cli callee_realtime-tts \
449
453
  --server pbx.local --user 1001 --password secret \
450
454
  --tts-text "Willkommen, wie kann ich Ihnen helfen?" \
451
- --piper-model /path/to/de_DE-thorsten-high.onnx
455
+ --piper-live-model de_DE-thorsten-high
452
456
 
453
457
  # Interactive mode — type text during the call
454
458
  python -m sipstuff.cli callee_realtime-tts \
455
459
  --server pbx.local --user 1001 --password secret \
456
460
  --interactive \
457
- --piper-model /path/to/de_DE-thorsten-high.onnx
461
+ --piper-live-model de_DE-thorsten-high
458
462
  ```
459
463
 
460
464
  **TTS & playback:**
461
465
 
462
- | Flag | Description |
463
- |------|-------------|
464
- | `--tts-text` | Initial TTS text spoken on answer |
465
- | `--interactive` | Interactive mode: type text in the console that gets spoken live |
466
- | `--piper-model` | Path to Piper `.onnx` model (default: `./de_DE-thorsten-high.onnx`) |
467
- | `--tts-cuda` | Use CUDA GPU acceleration for Piper TTS |
468
- | `--wav-file` | WAV file to play at call start |
469
- | `--play-delay` | Seconds to wait before playback (default: 0.0) |
470
- | `--answer-delay` | Seconds before answering (default: 1.0) |
471
- | `--no-auto-answer` | Do not auto-answer calls |
466
+ | Flag | Description |
467
+ |----------------------|------------------------------------------------------------------|
468
+ | `--tts-text` | Initial TTS text spoken on answer |
469
+ | `--interactive` | Interactive mode: type text in the console that gets spoken live |
470
+ | `--piper-live-model` | Piper voice model (default: `de_DE-thorsten-high`) |
471
+ | `--tts-cuda` | Use CUDA GPU acceleration for Piper TTS |
472
+ | `--wav-file` | WAV file to play at call start |
473
+ | `--play-delay` | Seconds to wait before playback (default: 0.0) |
474
+ | `--answer-delay` | Seconds before answering (default: 1.0) |
475
+ | `--no-auto-answer` | Do not auto-answer calls |
472
476
 
473
477
  **STT (speech-to-text):**
474
478
 
475
- | Flag | Description |
476
- |------|-------------|
477
- | `--stt-backend` | STT backend: `faster-whisper` (default) or `openvino` |
478
- | `--stt-model` | Whisper model size or HuggingFace model ID (default: `base`) |
479
- | `--stt-live-model` | Separate smaller model for live transcription |
480
- | `--stt-device` | Compute device: `cpu` or `cuda` |
481
- | `--stt-language` | Language code for STT |
482
- | `--stt-data-dir` | Whisper model cache directory |
479
+ | Flag | Description |
480
+ |--------------------|--------------------------------------------------------------|
481
+ | `--stt-backend` | STT backend: `faster-whisper` (default) or `openvino` |
482
+ | `--stt-model` | Whisper model size or HuggingFace model ID (default: `base`) |
483
+ | `--stt-live-model` | Separate smaller model for live transcription |
484
+ | `--stt-device` | Compute device: `cpu` or `cuda` |
485
+ | `--stt-language` | Language code for STT |
486
+ | `--stt-data-dir` | Whisper model cache directory |
483
487
 
484
488
  **Live VAD:**
485
489
 
486
- | Flag | Description |
487
- |------|-------------|
488
- | `--vad-silence-threshold` | RMS silence threshold (default: 0.01) |
489
- | `--vad-silence-trigger` | Seconds of silence to trigger chunk boundary (default: 0.3) |
490
- | `--vad-max-chunk` | Max seconds per audio chunk (default: 5.0) |
491
- | `--vad-min-chunk` | Min seconds per audio chunk (default: 0.5) |
490
+ | Flag | Description |
491
+ |---------------------------|-------------------------------------------------------------|
492
+ | `--vad-silence-threshold` | RMS silence threshold (default: 0.01) |
493
+ | `--vad-silence-trigger` | Seconds of silence to trigger chunk boundary (default: 0.3) |
494
+ | `--vad-max-chunk` | Max seconds per audio chunk (default: 5.0) |
495
+ | `--vad-min-chunk` | Min seconds per audio chunk (default: 0.5) |
492
496
 
493
497
  **Recording & transcription:**
494
498
 
495
- | Flag | Description |
496
- |------|-------------|
497
- | `--wav-output` | Save RX recording to this path |
498
- | `--wav-dir` | Directory for WAV files (default: `..`) |
499
- | `--wav-output-tx` | Save TX recording to this path |
500
- | `--no-wav` | Do not save WAV recordings |
501
- | `--transcribe` | Full transcription of RX recording after call ends (writes JSON report) |
499
+ | Flag | Description |
500
+ |-------------------|-------------------------------------------------------------------------|
501
+ | `--wav-output` | Save RX recording to this path |
502
+ | `--wav-dir` | Directory for WAV files (default: `..`) |
503
+ | `--wav-output-tx` | Save TX recording to this path |
504
+ | `--no-wav` | Do not save WAV recordings |
505
+ | `--transcribe` | Full transcription of RX recording after call ends (writes JSON report) |
502
506
 
503
507
  **Audio output:**
504
508
 
505
- | Flag | Description |
506
- |------|-------------|
509
+ | Flag | Description |
510
+ |------------------|-----------------------------------------------------------------|
507
511
  | `--audio-socket` | Unix socket for live audio streaming (PCM 16 kHz, S16_LE, mono) |
508
- | `--play-audio` | Play remote audio on local speakers via sounddevice |
509
- | `--audio-device` | Sounddevice output device (index or name substring) |
512
+ | `--play-audio` | Play remote audio on local speakers via sounddevice |
513
+ | `--audio-device` | Sounddevice output device (index or name substring) |
510
514
 
511
- Shared flags: `--config`, `--server`, `--port`, `--user`, `--password`, `--transport`, `--srtp`, `--tls-verify`, `--local-port`, NAT traversal group, `--verbose`, `--pjsip-log-level`
515
+ Shared flags: `--config`, `--server`, `--port`, `--user`, `--password`, `--transport`, `--srtp`, `--tls-verify`, `--rtp-port`, `--rtp-port-range`, `--no-rtp-randomize`, `--local-port`, NAT traversal group, `--verbose`, `--pjsip-log-level`
512
516
 
513
517
  ### `callee_live-transcribe` — Incoming Call with Live Transcription
514
518
 
@@ -533,35 +537,35 @@ python -m sipstuff.cli callee_live-transcribe \
533
537
  --audio-socket /tmp/audio.sock --play-audio
534
538
  ```
535
539
 
536
- | Flag | Description |
537
- |------|-------------|
538
- | `--stt-backend` | STT backend: `faster-whisper` (default) or `openvino` |
539
- | `--stt-model` | Whisper model (default: `base`) |
540
- | `--stt-live-model` | Separate smaller model for live transcription |
541
- | `--stt-device` | Compute device: `cpu` or `cuda` |
542
- | `--stt-language` | Language code for STT |
543
- | `--stt-data-dir` | Whisper model cache directory |
544
- | `--vad-silence-threshold` | RMS silence threshold (default: 0.01) |
545
- | `--vad-silence-trigger` | Seconds of silence to trigger chunk boundary (default: 0.3) |
546
- | `--vad-max-chunk` | Max seconds per audio chunk (default: 5.0) |
547
- | `--vad-min-chunk` | Min seconds per audio chunk (default: 0.5) |
548
- | `--wav-output` | Save RX recording to this path |
549
- | `--wav-output-tx` | Save TX recording to this path |
550
- | `--wav-dir` | Directory for WAV files (default: `..`) |
551
- | `--no-wav` | Do not save WAV recordings |
552
- | `--transcribe` | Full transcription of RX recording after call ends (writes JSON report) |
553
- | `--wav-file` | WAV file to play at call start |
554
- | `--tts-text` | Text for Piper TTS playback at call start |
555
- | `--piper-model` | Piper voice model (default: `de_DE-thorsten-high`) |
556
- | `--tts-data-dir` | Piper data directory |
557
- | `--play-delay` | Seconds to wait before playback (default: 0.0) |
558
- | `--audio-socket` | Unix socket for live audio streaming (PCM 16 kHz, S16_LE, mono) |
559
- | `--play-audio` | Play remote audio on local speakers via sounddevice |
560
- | `--audio-device` | Sounddevice output device (index or name substring) |
561
- | `--answer-delay` | Seconds before answering (default: 1.0) |
562
- | `--no-auto-answer` | Do not auto-answer calls |
563
-
564
- Shared flags: `--config`, `--server`, `--port`, `--user`, `--password`, `--transport`, `--srtp`, `--tls-verify`, `--local-port`, NAT traversal group, `--verbose`, `--pjsip-log-level`
540
+ | Flag | Description |
541
+ |---------------------------|-------------------------------------------------------------------------|
542
+ | `--stt-backend` | STT backend: `faster-whisper` (default) or `openvino` |
543
+ | `--stt-model` | Whisper model (default: `base`) |
544
+ | `--stt-live-model` | Separate smaller model for live transcription |
545
+ | `--stt-device` | Compute device: `cpu` or `cuda` |
546
+ | `--stt-language` | Language code for STT |
547
+ | `--stt-data-dir` | Whisper model cache directory |
548
+ | `--vad-silence-threshold` | RMS silence threshold (default: 0.01) |
549
+ | `--vad-silence-trigger` | Seconds of silence to trigger chunk boundary (default: 0.3) |
550
+ | `--vad-max-chunk` | Max seconds per audio chunk (default: 5.0) |
551
+ | `--vad-min-chunk` | Min seconds per audio chunk (default: 0.5) |
552
+ | `--wav-output` | Save RX recording to this path |
553
+ | `--wav-output-tx` | Save TX recording to this path |
554
+ | `--wav-dir` | Directory for WAV files (default: `..`) |
555
+ | `--no-wav` | Do not save WAV recordings |
556
+ | `--transcribe` | Full transcription of RX recording after call ends (writes JSON report) |
557
+ | `--wav-file` | WAV file to play at call start |
558
+ | `--tts-text` | Text for Piper TTS playback at call start |
559
+ | `--piper-model` | Piper voice model (default: `de_DE-thorsten-high`) |
560
+ | `--tts-data-dir` | Piper data directory |
561
+ | `--play-delay` | Seconds to wait before playback (default: 0.0) |
562
+ | `--audio-socket` | Unix socket for live audio streaming (PCM 16 kHz, S16_LE, mono) |
563
+ | `--play-audio` | Play remote audio on local speakers via sounddevice |
564
+ | `--audio-device` | Sounddevice output device (index or name substring) |
565
+ | `--answer-delay` | Seconds before answering (default: 1.0) |
566
+ | `--no-auto-answer` | Do not auto-answer calls |
567
+
568
+ Shared flags: `--config`, `--server`, `--port`, `--user`, `--password`, `--transport`, `--srtp`, `--tls-verify`, `--rtp-port`, `--rtp-port-range`, `--no-rtp-randomize`, `--local-port`, NAT traversal group, `--verbose`, `--pjsip-log-level`
565
569
 
566
570
  ## Docker / Podman Example
567
571
 
@@ -667,11 +671,11 @@ Notes:
667
671
  <video src="https://github.com/user-attachments/assets/996c63d2-4f40-4402-9107-9d8b4b8827eb" width="100%" controls></video>
668
672
 
669
673
 
670
- ![Call startup — TTS generation, SIP registration, silence detection, and WAV playback](Bildschirmfoto_2026-02-15_17-40-19_blurred.png)
674
+ ![Call startup — TTS generation, SIP registration, silence detection, and WAV playback](https://raw.githubusercontent.com/vroomfondel/sipstuff/main/Bildschirmfoto_2026-02-15_17-40-19_blurred.png)
671
675
 
672
- ![Call completion — RTP stats, STT transcription, and JSON call report](Bildschirmfoto_2026-02-15_17-40-43_blurred.png)
676
+ ![Call completion — RTP stats, STT transcription, and JSON call report](https://raw.githubusercontent.com/vroomfondel/sipstuff/main/Bildschirmfoto_2026-02-15_17-40-43_blurred.png)
673
677
 
674
- ![JSON call report detail and follow-up call](Bildschirmfoto_2026-02-15_17-41-02_blurred.png)
678
+ ![JSON call report detail and follow-up call](https://raw.githubusercontent.com/vroomfondel/sipstuff/main/Bildschirmfoto_2026-02-15_17-41-02_blurred.png)
675
679
 
676
680
  ## Library Usage
677
681
 
@@ -850,6 +854,9 @@ sip:
850
854
  srtp: "disabled" # disabled, optional, or mandatory
851
855
  tls_verify_server: false
852
856
  local_port: 0 # 0 = auto
857
+ rtp_port: 4000 # 0 = OS-assigned
858
+ rtp_port_range: 200
859
+ rtp_randomize_port: true
853
860
 
854
861
  call:
855
862
  timeout: 60
@@ -915,111 +922,114 @@ All settings can be set via `SIP_` prefixed environment variables:
915
922
 
916
923
  **SIP connection:**
917
924
 
918
- | Variable | Maps to |
919
- |----------|---------|
920
- | `SIP_SERVER` | `sip.server` |
921
- | `SIP_PORT` | `sip.port` |
922
- | `SIP_USER` | `sip.user` |
923
- | `SIP_PASSWORD` | `sip.password` |
924
- | `SIP_TRANSPORT` | `sip.transport` |
925
- | `SIP_SRTP` | `sip.srtp` |
926
- | `SIP_TLS_VERIFY_SERVER` | `sip.tls_verify_server` |
927
- | `SIP_LOCAL_PORT` | `sip.local_port` |
925
+ | Variable | Maps to |
926
+ |--------------------------|--------------------------|
927
+ | `SIP_SERVER` | `sip.server` |
928
+ | `SIP_PORT` | `sip.port` |
929
+ | `SIP_USER` | `sip.user` |
930
+ | `SIP_PASSWORD` | `sip.password` |
931
+ | `SIP_TRANSPORT` | `sip.transport` |
932
+ | `SIP_SRTP` | `sip.srtp` |
933
+ | `SIP_TLS_VERIFY_SERVER` | `sip.tls_verify_server` |
934
+ | `SIP_LOCAL_PORT` | `sip.local_port` |
935
+ | `SIP_RTP_PORT` | `sip.rtp_port` |
936
+ | `SIP_RTP_PORT_RANGE` | `sip.rtp_port_range` |
937
+ | `SIP_RTP_RANDOMIZE_PORT` | `sip.rtp_randomize_port` |
928
938
 
929
939
  **Call timing:**
930
940
 
931
- | Variable | Maps to |
932
- |----------|---------|
933
- | `SIP_TIMEOUT` | `call.timeout` |
934
- | `SIP_PRE_DELAY` | `call.pre_delay` |
935
- | `SIP_POST_DELAY` | `call.post_delay` |
936
- | `SIP_INTER_DELAY` | `call.inter_delay` |
937
- | `SIP_REPEAT` | `call.repeat` |
941
+ | Variable | Maps to |
942
+ |------------------------|-------------------------|
943
+ | `SIP_TIMEOUT` | `call.timeout` |
944
+ | `SIP_PRE_DELAY` | `call.pre_delay` |
945
+ | `SIP_POST_DELAY` | `call.post_delay` |
946
+ | `SIP_INTER_DELAY` | `call.inter_delay` |
947
+ | `SIP_REPEAT` | `call.repeat` |
938
948
  | `SIP_WAIT_FOR_SILENCE` | `call.wait_for_silence` |
939
949
 
940
950
  **TTS:**
941
951
 
942
- | Variable | Maps to |
943
- |----------|---------|
944
- | `SIP_TTS_MODEL` | `tts.model` |
952
+ | Variable | Maps to |
953
+ |-----------------------|-------------------|
954
+ | `SIP_TTS_MODEL` | `tts.model` |
945
955
  | `SIP_TTS_SAMPLE_RATE` | `tts.sample_rate` |
946
- | `SIP_TTS_CUDA` | `tts.use_cuda` |
947
- | `SIP_TTS_DATA_DIR` | `tts.data_dir` |
956
+ | `SIP_TTS_CUDA` | `tts.use_cuda` |
957
+ | `SIP_TTS_DATA_DIR` | `tts.data_dir` |
948
958
 
949
959
  **NAT traversal:**
950
960
 
951
- | Variable | Maps to |
952
- |----------|---------|
953
- | `SIP_STUN_SERVERS` | `nat.stun_servers` (comma-separated) |
954
- | `SIP_STUN_IGNORE_FAILURE` | `nat.stun_ignore_failure` |
955
- | `SIP_ICE_ENABLED` | `nat.ice_enabled` |
956
- | `SIP_TURN_ENABLED` | `nat.turn_enabled` |
957
- | `SIP_TURN_SERVER` | `nat.turn_server` |
958
- | `SIP_TURN_USERNAME` | `nat.turn_username` |
959
- | `SIP_TURN_PASSWORD` | `nat.turn_password` |
960
- | `SIP_TURN_TRANSPORT` | `nat.turn_transport` |
961
- | `SIP_KEEPALIVE_SEC` | `nat.keepalive_sec` |
962
- | `SIP_PUBLIC_ADDRESS` | `nat.public_address` |
961
+ | Variable | Maps to |
962
+ |---------------------------|--------------------------------------|
963
+ | `SIP_STUN_SERVERS` | `nat.stun_servers` (comma-separated) |
964
+ | `SIP_STUN_IGNORE_FAILURE` | `nat.stun_ignore_failure` |
965
+ | `SIP_ICE_ENABLED` | `nat.ice_enabled` |
966
+ | `SIP_TURN_ENABLED` | `nat.turn_enabled` |
967
+ | `SIP_TURN_SERVER` | `nat.turn_server` |
968
+ | `SIP_TURN_USERNAME` | `nat.turn_username` |
969
+ | `SIP_TURN_PASSWORD` | `nat.turn_password` |
970
+ | `SIP_TURN_TRANSPORT` | `nat.turn_transport` |
971
+ | `SIP_KEEPALIVE_SEC` | `nat.keepalive_sec` |
972
+ | `SIP_PUBLIC_ADDRESS` | `nat.public_address` |
963
973
 
964
974
  **Audio device:**
965
975
 
966
- | Variable | Maps to |
967
- |----------|---------|
968
- | `SIP_NULL_AUDIO` | `audio.use_null_audio` (default: `true`) |
969
- | `SIP_NULL_CAPTURE` | `audio.null_capture` (null mic; `None` inherits `SIP_NULL_AUDIO`) |
976
+ | Variable | Maps to |
977
+ |---------------------|------------------------------------------------------------------------|
978
+ | `SIP_NULL_AUDIO` | `audio.use_null_audio` (default: `true`) |
979
+ | `SIP_NULL_CAPTURE` | `audio.null_capture` (null mic; `None` inherits `SIP_NULL_AUDIO`) |
970
980
  | `SIP_NULL_PLAYBACK` | `audio.null_playback` (null speaker; `None` inherits `SIP_NULL_AUDIO`) |
971
- | `SIP_PLAY_RX` | `audio.play_rx` (route RX to output sinks; default: `true`) |
972
- | `SIP_PLAY_TX` | `audio.play_tx` (route TX to output sinks; default: `false`) |
973
- | `SIP_AUDIO_DEVICE` | `audio.audio_device` (sounddevice index or name) |
981
+ | `SIP_PLAY_RX` | `audio.play_rx` (route RX to output sinks; default: `true`) |
982
+ | `SIP_PLAY_TX` | `audio.play_tx` (route TX to output sinks; default: `false`) |
983
+ | `SIP_AUDIO_DEVICE` | `audio.audio_device` (sounddevice index or name) |
974
984
 
975
985
  **STT:**
976
986
 
977
- | Variable | Maps to |
978
- |----------|---------|
979
- | `SIP_STT_BACKEND` | `stt.backend` |
980
- | `SIP_STT_MODEL` | `stt.model` |
981
- | `SIP_STT_LANGUAGE` | `stt.language` |
982
- | `SIP_STT_DEVICE` | `stt.device` |
983
- | `SIP_STT_DATA_DIR` | `stt.data_dir` |
987
+ | Variable | Maps to |
988
+ |-----------------------|-----------------------|
989
+ | `SIP_STT_BACKEND` | `stt.backend` |
990
+ | `SIP_STT_MODEL` | `stt.model` |
991
+ | `SIP_STT_LANGUAGE` | `stt.language` |
992
+ | `SIP_STT_DEVICE` | `stt.device` |
993
+ | `SIP_STT_DATA_DIR` | `stt.data_dir` |
984
994
  | `SIP_LIVE_TRANSCRIBE` | `stt.live_transcribe` |
985
995
 
986
996
  **VAD:**
987
997
 
988
- | Variable | Maps to |
989
- |----------|---------|
998
+ | Variable | Maps to |
999
+ |-----------------------------|-------------------------|
990
1000
  | `SIP_VAD_SILENCE_THRESHOLD` | `vad.silence_threshold` |
991
- | `SIP_VAD_SILENCE_TRIGGER` | `vad.silence_trigger` |
992
- | `SIP_VAD_MAX_CHUNK` | `vad.max_chunk` |
993
- | `SIP_VAD_MIN_CHUNK` | `vad.min_chunk` |
1001
+ | `SIP_VAD_SILENCE_TRIGGER` | `vad.silence_trigger` |
1002
+ | `SIP_VAD_MAX_CHUNK` | `vad.max_chunk` |
1003
+ | `SIP_VAD_MIN_CHUNK` | `vad.min_chunk` |
994
1004
 
995
1005
  **Callee:**
996
1006
 
997
- | Variable | Maps to |
998
- |----------|---------|
999
- | `SIP_AUTO_ANSWER` | `callee.auto_answer` (default: `true`) |
1007
+ | Variable | Maps to |
1008
+ |--------------------|----------------------------------------|
1009
+ | `SIP_AUTO_ANSWER` | `callee.auto_answer` (default: `true`) |
1000
1010
  | `SIP_ANSWER_DELAY` | `callee.answer_delay` (default: `1.0`) |
1001
1011
 
1002
1012
  **TTS runtime:**
1003
1013
 
1004
- | Variable | Default | Description |
1005
- |----------|---------|-------------|
1014
+ | Variable | Default | Description |
1015
+ |------------------|-------------------------------|---------------------------------------|
1006
1016
  | `PIPER_DATA_DIR` | `~/.local/share/piper-voices` | Directory for downloaded voice models |
1007
1017
 
1008
1018
  **STT runtime (faster-whisper):**
1009
1019
 
1010
- | Variable | Default | Description |
1011
- |----------|---------|-------------|
1012
- | `WHISPER_DATA_DIR` | `~/.local/share/faster-whisper-models` | Directory for downloaded Whisper models |
1013
- | `WHISPER_MODEL` | `medium` | Default model size (`tiny`, `base`, `small`, `medium`, `large-v3`) |
1014
- | `WHISPER_DEVICE` | `cpu` | Compute device (`cpu` or `cuda`) |
1015
- | `WHISPER_COMPUTE_TYPE` | `int8` (CPU) / `float16` (CUDA) | Quantization type (`int8`, `float16`, `float32`) |
1020
+ | Variable | Default | Description |
1021
+ |------------------------|----------------------------------------|--------------------------------------------------------------------|
1022
+ | `WHISPER_DATA_DIR` | `~/.local/share/faster-whisper-models` | Directory for downloaded Whisper models |
1023
+ | `WHISPER_MODEL` | `medium` | Default model size (`tiny`, `base`, `small`, `medium`, `large-v3`) |
1024
+ | `WHISPER_DEVICE` | `cpu` | Compute device (`cpu` or `cuda`) |
1025
+ | `WHISPER_COMPUTE_TYPE` | `int8` (CPU) / `float16` (CUDA) | Quantization type (`int8`, `float16`, `float32`) |
1016
1026
 
1017
1027
  **PJSIP native log routing:**
1018
1028
 
1019
- | Variable | Default | Description |
1020
- |----------|---------|-------------|
1021
- | `PJSIP_LOG_LEVEL` | `3` | PJSIP log verbosity routed through loguru (0 = none … 6 = trace) |
1022
- | `PJSIP_CONSOLE_LEVEL` | `4` | PJSIP native console output printed directly to stdout (4 = PJSIP default, 0 = suppressed) |
1029
+ | Variable | Default | Description |
1030
+ |-----------------------|---------|--------------------------------------------------------------------------------------------|
1031
+ | `PJSIP_LOG_LEVEL` | `3` | PJSIP log verbosity routed through loguru (0 = none … 6 = trace) |
1032
+ | `PJSIP_CONSOLE_LEVEL` | `4` | PJSIP native console output printed directly to stdout (4 = PJSIP default, 0 = suppressed) |
1023
1033
 
1024
1034
  All PJSIP native output is captured by a `pj.LogWriter` subclass and forwarded to loguru (`classname="pjsip"`). `PJSIP_LOG_LEVEL` controls what the writer receives; `PJSIP_CONSOLE_LEVEL` controls what PJSIP additionally prints to stdout on its own. Set `PJSIP_CONSOLE_LEVEL=0` to suppress native output and rely solely on loguru.
1025
1035
 
@@ -1061,28 +1071,30 @@ Non-standard formats (stereo, different bit depths/rates) will produce warnings
1061
1071
 
1062
1072
  ## Module Structure
1063
1073
 
1064
- | File | Purpose |
1065
- |------|---------|
1066
- | `__init__.py` | Public API: `make_sip_call`, `SipCaller`, `SipCallee`, `SipEndpoint`, `SipCallError`, `CallResult`, config classes, `generate_wav`, `transcribe_wav`, `configure_logging`, `print_banner` |
1067
- | `sip_endpoint.py` | `SipEndpoint` base class for PJSUA2 Endpoint lifecycle, `SipCaller(SipEndpoint)` with `make_call()` orchestration, `_PjLogWriter`, `_local_address_for()` |
1068
- | `sip_call.py` | `SipCall(pj.Call)` shared base, `SipCallerCall` (caller-side media management), `SipCalleeCall` (callee-side hooks) |
1069
- | `sip_media.py` | `SilenceDetector`, `AudioStreamPort`, `TranscriptionPort` — PJSUA2 `AudioMediaPort` subclasses |
1070
- | `sip_account.py` | `SipAccount(pj.Account)` base, `SipCallerAccount` (incoming-call rejection), `SipCalleeAccount` (auto-answer dispatch) |
1071
- | `sip_callee.py` | `SipCallee(SipEndpoint)` — incoming call handling orchestration |
1072
- | `sip_types.py` | `CallResult` dataclass, `SipCallError`, `WavInfo` |
1073
- | `sip_caller.py` | Legacy module (retained for imports) |
1074
- | `sipconfig.py` | Pydantic v2 config models (`SipEndpointConfig`, `SipCallerConfig`, `SipCalleeConfig`) with YAML / env / override loading |
1075
- | `vad.py` | `VADAudioBuffer` — voice activity detection buffer for live transcription |
1076
- | `audio.py` | `resample_linear()` (numpy), `ensure_wav_16k_mono()` — audio format utilities |
1077
- | `snddevice_list.py` | Sound device enumeration utility |
1078
- | `tts/tts.py` | Piper TTS integration: text-to-WAV generation via Python API with optional resampling |
1079
- | `tts/live.py` | Live TTS streaming: `PiperTTSProducer` (producer thread), `TTSMediaPort` (PJSIP consumer), `interactive_console()` |
1080
- | `stt/stt.py` | Speech-to-text via faster-whisper: WAV transcription with Silero VAD pre-filtering and segment timestamps |
1081
- | `stt/live.py` | Live STT streaming during calls |
1082
- | `autoanswer/` | Callee auto-answer implementation (integrated as `callee_autoanswer` CLI subcommand) |
1083
- | `realtime/` | Callee real-time TTS implementation (integrated as `callee_realtime-tts` CLI subcommand) |
1084
- | `transcribe/` | Callee live-transcribe implementation (integrated as `callee_live-transcribe` CLI subcommand) |
1085
- | `training/` | Voice training utilities: `record_dataset.py`, `record_gui.py` (standalone, not in CLI) |
1074
+ | File | Purpose |
1075
+ |---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1076
+ | `__init__.py` | Public API: `make_sip_call`, `SipCaller`, `SipCallee`, `SipEndpoint`, `SipCallError`, `CallResult`, config classes, `generate_wav`, `transcribe_wav`, `configure_logging`, `print_banner` |
1077
+ | `sip_endpoint.py` | `SipEndpoint` base class for PJSUA2 Endpoint lifecycle, `SipCaller(SipEndpoint)` with `make_call()` orchestration, `_PjLogWriter`, `_local_address_for()` |
1078
+ | `sip_call.py` | `SipCall(pj.Call)` shared base, `SipCallerCall` (caller-side media management), `SipCalleeCall` (callee-side hooks) |
1079
+ | `sip_media.py` | `SilenceDetector`, `AudioStreamPort`, `TranscriptionPort` — PJSUA2 `AudioMediaPort` subclasses |
1080
+ | `sip_account.py` | `SipAccount(pj.Account)` base, `SipCallerAccount` (incoming-call rejection), `SipCalleeAccount` (auto-answer dispatch) |
1081
+ | `sip_callee.py` | `SipCallee(SipEndpoint)` — incoming call handling orchestration |
1082
+ | `sip_types.py` | `CallResult` dataclass, `SipCallError`, `WavInfo` |
1083
+ | `sip_caller.py` | Legacy module (retained for imports) |
1084
+ | `sipconfig.py` | Pydantic v2 config models (`SipEndpointConfig`, `SipCallerConfig`, `SipCalleeConfig`) with YAML / env / override loading |
1085
+ | `vad.py` | `VADAudioBuffer` — voice activity detection buffer for live transcription |
1086
+ | `audio.py` | `resample_linear()` (numpy), `ensure_wav_16k_mono()` — audio format utilities |
1087
+ | `snddevice_list.py` | Sound device enumeration utility |
1088
+ | `tts/tts.py` | Piper TTS integration: text-to-WAV generation via Python API with optional resampling |
1089
+ | `tts/live.py` | Live TTS streaming: `PiperTTSProducer` (producer thread), `TTSMediaPort` (PJSIP consumer), `interactive_console()` |
1090
+ | `stt/stt.py` | Speech-to-text via faster-whisper: WAV transcription with Silero VAD pre-filtering and segment timestamps |
1091
+ | `stt/live.py` | Live STT streaming during calls |
1092
+ | `autoanswer/` | Callee auto-answer implementation (integrated as `callee_autoanswer` CLI subcommand) |
1093
+ | `realtime/` | Callee real-time TTS implementation (integrated as `callee_realtime-tts` CLI subcommand) |
1094
+ | `transcribe/` | Callee live-transcribe implementation (integrated as `callee_live-transcribe` CLI subcommand) |
1095
+ | `training/` | Voice training utilities: `record_dataset.py`, `record_gui.py` (standalone, not in CLI) — see [training README](https://github.com/vroomfondel/sipstuff/blob/main/sipstuff/training/README.md) |
1096
+
1097
+ ![Audio device enumeration (sounddevice input/output devices)](https://raw.githubusercontent.com/vroomfondel/sipstuff/main/Bildschirmfoto_2026-02-22_12-08-06.png)
1086
1098
  | `cli.py` | CLI entry point with six subcommands |
1087
1099
  | `example_config.yaml` | Sample configuration file |
1088
1100
  | `dist_scripts/install_pjsip.sh` | Build script for PJSIP with Python bindings (default: 2.16) |
@@ -1136,5 +1148,18 @@ Tests cover config validation (SipConfig, CallConfig, SipCallerConfig, NatConfig
1136
1148
  CI skips venv setup when `GITHUB_RUN_ID` is set — installs deps directly.
1137
1149
 
1138
1150
  ## License
1151
+ This project is licensed under the LGPL where applicable/possible — see [LICENSE.md](https://github.com/vroomfondel/sipstuff/blob/main/LICENSE.md). Some files/parts may use other licenses: [MIT](https://github.com/vroomfondel/sipstuff/blob/main/LICENSEMIT.md) | [GPL](https://github.com/vroomfondel/sipstuff/blob/main/LICENSEGPL.md) | [LGPL](https://github.com/vroomfondel/sipstuff/blob/main/LICENSELGPL.md). Always check per‑file headers/comments.
1152
+
1153
+
1154
+ ## Authors
1155
+ - Repo owner (primary author)
1156
+ - Additional attributions are noted inline in code comments
1157
+
1158
+
1159
+ ## Acknowledgments
1160
+ - Inspirations and snippets are referenced in code comments where appropriate.
1161
+
1162
+
1163
+ ## ⚠️ Note
1139
1164
 
1140
- LGPLv3 — see [LICENSE.md](LICENSE.md), [LICENSELGPL.md](LICENSELGPL.md), [LICENSEGPL.md](LICENSEGPL.md), [LICENSEMIT.md](LICENSEMIT.md).
1165
+ This is a development/experimental project. For production use, review security settings, customize configurations, and test thoroughly in your environment. Provided "as is" without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software. Use at your own risk.