proc-tap 0.2.0__tar.gz → 0.3.1__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 (39) hide show
  1. {proc_tap-0.2.0/src/proc_tap.egg-info → proc_tap-0.3.1}/PKG-INFO +125 -22
  2. {proc_tap-0.2.0 → proc_tap-0.3.1}/README.md +116 -21
  3. {proc_tap-0.2.0 → proc_tap-0.3.1}/pyproject.toml +53 -2
  4. {proc_tap-0.2.0 → proc_tap-0.3.1/src/proc_tap.egg-info}/PKG-INFO +125 -22
  5. proc_tap-0.3.1/src/proc_tap.egg-info/SOURCES.txt +33 -0
  6. proc_tap-0.3.1/src/proc_tap.egg-info/entry_points.txt +2 -0
  7. proc_tap-0.3.1/src/proc_tap.egg-info/requires.txt +27 -0
  8. {proc_tap-0.2.0 → proc_tap-0.3.1}/src/proctap/__init__.py +2 -2
  9. proc_tap-0.3.1/src/proctap/__main__.py +199 -0
  10. {proc_tap-0.2.0 → proc_tap-0.3.1}/src/proctap/backends/__init__.py +9 -5
  11. {proc_tap-0.2.0 → proc_tap-0.3.1}/src/proctap/backends/base.py +2 -1
  12. proc_tap-0.3.1/src/proctap/backends/converter.py +489 -0
  13. proc_tap-0.3.1/src/proctap/backends/linux.py +1389 -0
  14. {proc_tap-0.2.0 → proc_tap-0.3.1}/src/proctap/backends/macos.py +2 -2
  15. proc_tap-0.3.1/src/proctap/backends/pipewire_native.py +1376 -0
  16. proc_tap-0.3.1/src/proctap/backends/windows.py +148 -0
  17. proc_tap-0.3.1/src/proctap/contrib/__init__.py +41 -0
  18. {proc_tap-0.2.0 → proc_tap-0.3.1}/src/proctap/contrib/discord_source.py +44 -157
  19. proc_tap-0.3.1/src/proctap/contrib/filters/__init__.py +54 -0
  20. proc_tap-0.3.1/src/proctap/contrib/filters/base.py +49 -0
  21. proc_tap-0.3.1/src/proctap/contrib/filters/chain.py +131 -0
  22. proc_tap-0.3.1/src/proctap/contrib/filters/dsp.py +205 -0
  23. proc_tap-0.3.1/src/proctap/contrib/filters/dynamics.py +190 -0
  24. proc_tap-0.3.1/src/proctap/contrib/filters/vad.py +113 -0
  25. proc_tap-0.3.1/src/proctap/contrib/whisper_transcribe.py +504 -0
  26. {proc_tap-0.2.0 → proc_tap-0.3.1}/src/proctap/core.py +78 -12
  27. proc_tap-0.3.1/tests/test_converter_optimizations.py +339 -0
  28. proc_tap-0.3.1/tests/test_pipewire_native.py +275 -0
  29. proc_tap-0.2.0/src/proc_tap.egg-info/SOURCES.txt +0 -20
  30. proc_tap-0.2.0/src/proc_tap.egg-info/requires.txt +0 -15
  31. proc_tap-0.2.0/src/proctap/backends/linux.py +0 -521
  32. proc_tap-0.2.0/src/proctap/backends/windows.py +0 -85
  33. proc_tap-0.2.0/src/proctap/contrib/__init__.py +0 -17
  34. {proc_tap-0.2.0 → proc_tap-0.3.1}/LICENSE +0 -0
  35. {proc_tap-0.2.0 → proc_tap-0.3.1}/setup.cfg +0 -0
  36. {proc_tap-0.2.0 → proc_tap-0.3.1}/setup.py +0 -0
  37. {proc_tap-0.2.0 → proc_tap-0.3.1}/src/proc_tap.egg-info/dependency_links.txt +0 -0
  38. {proc_tap-0.2.0 → proc_tap-0.3.1}/src/proc_tap.egg-info/top_level.txt +0 -0
  39. {proc_tap-0.2.0 → proc_tap-0.3.1}/src/proctap/_native.pyi +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: proc-tap
3
- Version: 0.2.0
3
+ Version: 0.3.1
4
4
  Summary: Cross-platform process-level audio capture library
5
5
  Author-email: m96-chan <y_harada@technologies.moe>
6
6
  License: MIT
@@ -28,16 +28,24 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
28
  Requires-Python: >=3.10
29
29
  Description-Content-Type: text/markdown
30
30
  License-File: LICENSE
31
+ Requires-Dist: numpy>=1.20.0
32
+ Requires-Dist: scipy>=1.7.0
31
33
  Requires-Dist: pulsectl>=23.5.0; sys_platform == "linux"
32
34
  Provides-Extra: dev
33
35
  Requires-Dist: pytest; extra == "dev"
34
36
  Requires-Dist: mypy; extra == "dev"
35
37
  Requires-Dist: types-setuptools; extra == "dev"
38
+ Requires-Dist: types-psutil; extra == "dev"
39
+ Requires-Dist: scipy-stubs; extra == "dev"
36
40
  Provides-Extra: docs
37
41
  Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
38
42
  Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "docs"
39
43
  Provides-Extra: linux
40
44
  Requires-Dist: pulsectl>=23.5.0; extra == "linux"
45
+ Provides-Extra: contrib
46
+ Requires-Dist: faster-whisper>=1.0.0; extra == "contrib"
47
+ Provides-Extra: hq-resample
48
+ Requires-Dist: samplerate>=0.1.0; (python_version < "3.13" or sys_platform != "win32") and extra == "hq-resample"
41
49
  Dynamic: license-file
42
50
 
43
51
  <div align="center">
@@ -68,10 +76,10 @@ Ideal for VRChat, games, DAWs, browsers, and AI audio analysis pipelines.
68
76
  | Platform | Status | Backend | Notes |
69
77
  |----------|--------|---------|-------|
70
78
  | **Windows** | ✅ **Fully Supported** | WASAPI (C++ native) | Windows 10/11 (20H1+) |
71
- | **Linux** | 🧪 **Experimental** | PulseAudio/PipeWire | Basic support, sink monitor capture |
79
+ | **Linux** | **Fully Supported** | PipeWire Native / PulseAudio | Per-process isolation, auto-fallback (v0.3.0+) |
72
80
  | **macOS** | 🧪 **Experimental** | Core Audio Process Tap | macOS 14.4+ (Sonoma) required |
73
81
 
74
- <sub>\* Linux and macOS support are experimental with limitations (see requirements). Windows is currently the only fully functional platform.</sub>
82
+ <sub>\* Linux is fully supported with PipeWire/PulseAudio (v0.3.0+). macOS support is experimental (see requirements).</sub>
75
83
 
76
84
  </div>
77
85
 
@@ -83,11 +91,11 @@ Ideal for VRChat, games, DAWs, browsers, and AI audio analysis pipelines.
83
91
  (VRChat, games, browsers, Discord, DAWs, streaming tools, etc.)
84
92
 
85
93
  - 🌍 **Cross-platform architecture**
86
- → Windows (fully supported) | Linux (experimental) | macOS (experimental, 14.4+)
94
+ → Windows (fully supported) | Linux (fully supported, v0.3.0+) | macOS (experimental, 14.4+)
87
95
 
88
96
  - ⚡ **Platform-optimized backends**
89
97
  → Windows: ActivateAudioInterfaceAsync (modern WASAPI)
90
- → Linux: PulseAudio/PipeWire (experimental)
98
+ → Linux: PipeWire Native API / PulseAudio (fully supported, v0.3.0+)
91
99
  → macOS: Core Audio Process Tap API (macOS 14.4+)
92
100
 
93
101
  - 🧵 **Low-latency, thread-safe audio engine**
@@ -121,6 +129,22 @@ pip install proc-tap
121
129
  sudo dnf install pulseaudio-utils
122
130
  ```
123
131
 
132
+ **Optional: High-Quality Audio Resampling** (74% faster / 3.8x speedup for sample rate conversion):
133
+
134
+ ```bash
135
+ pip install proc-tap[hq-resample]
136
+ ```
137
+
138
+ **Performance:** With `libsamplerate`, resampling achieves **0.66ms per 10ms chunk** (vs 2.6ms with scipy-only).
139
+
140
+ **Compatibility Notes:**
141
+ - ✅ **Python 3.10-3.12**: Works on all platforms
142
+ - ✅ **Linux/macOS + Python 3.13+**: Should work (you can try it!)
143
+ - ⚠️ **Windows + Python 3.13+**: May fail to build (as of 2025-01)
144
+ - If it fails, the library automatically falls back to scipy's polyphase filtering
145
+ - Still provides excellent audio quality, just 74% slower for resampling
146
+ - You can still try installing - if it works, great! If not, no harm done.
147
+
124
148
  📚 **[Read the Full Documentation](https://m96-chan.github.io/ProcTap/)** for detailed guides and API reference.
125
149
 
126
150
  **From TestPyPI** (for testing pre-releases):
@@ -139,6 +163,58 @@ pip install -e .
139
163
 
140
164
  ---
141
165
 
166
+ ## 🎬 CLI Usage (Pipe to FFmpeg)
167
+
168
+ ProcTap includes a CLI for piping audio directly to FFmpeg or other tools:
169
+
170
+ ```bash
171
+ # Pipe to FFmpeg (MP3 encoding) - Direct command
172
+ proctap --pid 12345 --stdout | ffmpeg -f s16le -ar 48000 -ac 2 -i pipe:0 output.mp3
173
+
174
+ # Or using python -m
175
+ python -m proctap --pid 12345 --stdout | ffmpeg -f s16le -ar 48000 -ac 2 -i pipe:0 output.mp3
176
+
177
+ # Using process name instead of PID
178
+ proctap --name "VRChat.exe" --stdout | ffmpeg -f s16le -ar 48000 -ac 2 -i pipe:0 output.mp3
179
+
180
+ # FLAC encoding (lossless)
181
+ proctap --pid 12345 --stdout | ffmpeg -f s16le -ar 48000 -ac 2 -i pipe:0 output.flac
182
+
183
+ # Custom sample rate and mono output
184
+ proctap --pid 12345 --sample-rate 44100 --channels 1 --stdout | ffmpeg -f s16le -ar 44100 -ac 1 -i pipe:0 output.wav
185
+ ```
186
+
187
+ **CLI Options:**
188
+
189
+ | Option | Description |
190
+ |--------|-------------|
191
+ | `--pid PID` | Process ID to capture (required if `--name` not used) |
192
+ | `--name NAME` | Process name to capture (e.g., `VRChat.exe` or `VRChat`) |
193
+ | `--stdout` | Output raw PCM to stdout for piping (required) |
194
+ | `--sample-rate RATE` | Sample rate in Hz (default: 48000) |
195
+ | `--channels {1,2}` | Number of channels: 1=mono, 2=stereo (default: 2) |
196
+ | `--verbose` | Enable verbose logging to stderr |
197
+
198
+ **Finding Process IDs:**
199
+
200
+ ```bash
201
+ # Windows
202
+ tasklist | findstr "VRChat"
203
+
204
+ # Linux/macOS
205
+ ps aux | grep VRChat
206
+ ```
207
+
208
+ **FFmpeg Format Arguments:**
209
+
210
+ The CLI outputs raw PCM in s16le (signed 16-bit little-endian) format by default, but can be customized via `--sample-rate` and `--channels` options. FFmpeg needs these arguments:
211
+ - `-f s16le`: PCM format
212
+ - `-ar RATE`: Sample rate (must match `--sample-rate`, default 48000)
213
+ - `-ac CHANNELS`: Number of channels (must match `--channels`, default 2)
214
+ - `-i pipe:0`: Read from stdin
215
+
216
+ ---
217
+
142
218
  ## 🛠 Requirements
143
219
 
144
220
  **Windows (Fully Supported):**
@@ -147,13 +223,21 @@ pip install -e .
147
223
  - WASAPI support
148
224
  - **No admin privileges required**
149
225
 
150
- **Linux (Experimental):**
151
- - Linux with PulseAudio or PipeWire (with pulseaudio-compat)
226
+ **Linux (Fully Supported - v0.3.0+):**
227
+ - Linux with PulseAudio or PipeWire
152
228
  - Python 3.10+
153
- - `pulsectl` library: **automatically installed with `pip install proc-tap`**
154
- - `parec` command: install with `sudo apt-get install pulseaudio-utils`
155
- - ⚠️ **EXPERIMENTAL:** Basic PulseAudio support implemented
156
- - ⚠️ **LIMITATION:** Currently captures from entire sink monitor (may include other apps)
229
+ - **Auto-detection:** Automatically selects best available backend
230
+ - **Native PipeWire API** (in development, experimental):
231
+ - `libpipewire-0.3-dev`: `sudo apt-get install libpipewire-0.3-dev`
232
+ - Target latency: ~2-5ms (when fully implemented)
233
+ - Auto-selected when available (may fall back to subprocess)
234
+ - **PipeWire subprocess:**
235
+ - `pw-record`: install with `sudo apt-get install pipewire-media-session`
236
+ - **PulseAudio fallback:**
237
+ - `pulsectl` library: automatically installed
238
+ - `parec` command: `sudo apt-get install pulseaudio-utils`
239
+ - ✅ **Per-process isolation** using null-sink strategy
240
+ - ✅ **Graceful fallback** chain: Native → PipeWire subprocess → PulseAudio
157
241
 
158
242
  **macOS (Experimental):**
159
243
  - macOS 14.4 (Sonoma) or later
@@ -239,15 +323,29 @@ asyncio.run(main())
239
323
 
240
324
  ### Audio Format
241
325
 
242
- **Note:** The native extension uses a **fixed audio format** (hardcoded in C++):
326
+ **Native Backend Format** (Windows WASAPI, hardcoded in C++):
243
327
 
244
328
  | Parameter | Value | Description |
245
329
  |-----------|-------|-------------|
246
- | Sample Rate | **44,100 Hz** | CD quality (fixed) |
247
- | Channels | **2** | Stereo (fixed) |
248
- | Bit Depth | **16-bit** | PCM format (fixed) |
330
+ | Sample Rate | **44,100 Hz** | CD quality (fixed in C++) |
331
+ | Channels | **2** | Stereo (fixed in C++) |
332
+ | Bit Depth | **16-bit** | PCM format (fixed in C++) |
333
+
334
+ **Output Format Conversion** (v0.2.1+):
335
+
336
+ The `StreamConfig` class controls the **output format** through automatic conversion:
337
+ - Native format → converted to match your `StreamConfig` settings
338
+ - Supports sample rate conversion (e.g., 44.1kHz → 48kHz)
339
+ - Supports channel conversion (mono ↔ stereo)
340
+ - Supports bit depth conversion (8/16/24/32-bit)
341
+ - Zero overhead when formats match (automatic bypass)
249
342
 
250
- The `StreamConfig` class exists for API compatibility but does not change the native backend format.
343
+ Example:
344
+ ```python
345
+ # Get audio as 48kHz mono 24-bit
346
+ config = StreamConfig(sample_rate=48000, channels=1, width=3)
347
+ tap = ProcTap(pid, config=config)
348
+ ```
251
349
 
252
350
  ---
253
351
 
@@ -312,7 +410,7 @@ finally:
312
410
  ## 🐧 Linux Example
313
411
 
314
412
  ```python
315
- from proctap import ProcessAudioTap, StreamConfig
413
+ from proctap import ProcessAudioCapture, StreamConfig
316
414
  import wave
317
415
 
318
416
  pid = 12345 # Your target process ID
@@ -330,7 +428,7 @@ def on_data(pcm, frames):
330
428
  config = StreamConfig(sample_rate=44100, channels=2)
331
429
 
332
430
  try:
333
- with ProcessAudioTap(pid, config=config, on_data=on_data):
431
+ with ProcessAudioCapture(pid, config=config, on_data=on_data):
334
432
  print("⚠️ Make sure the process is actively playing audio!")
335
433
  input("Recording... Press Enter to stop.\n")
336
434
  finally:
@@ -348,7 +446,7 @@ finally:
348
446
  ## 🍎 macOS Example
349
447
 
350
448
  ```python
351
- from proctap import ProcessAudioTap, StreamConfig
449
+ from proctap import ProcessAudioCapture, StreamConfig
352
450
  import wave
353
451
 
354
452
  pid = 12345 # Your target process ID
@@ -366,7 +464,7 @@ def on_data(pcm, frames):
366
464
  config = StreamConfig(sample_rate=48000, channels=2)
367
465
 
368
466
  try:
369
- with ProcessAudioTap(pid, config=config, on_data=on_data):
467
+ with ProcessAudioCapture(pid, config=config, on_data=on_data):
370
468
  print("⚠️ Make sure the process is actively playing audio!")
371
469
  print("⚠️ On first run, macOS will prompt for permission.")
372
470
  input("Recording... Press Enter to stop.\n")
@@ -403,9 +501,14 @@ pip install -e .
403
501
  - Windows SDK
404
502
  - CMake (if you modularize the C++ code)
405
503
 
406
- **Linux/macOS:**
504
+ **Linux:**
505
+ - No C++ compiler required (pure Python)
506
+ - System dependencies: `pulseaudio-utils` or `pipewire` with `libpipewire-0.3-dev`
507
+
508
+ **macOS:**
407
509
  - No C++ compiler required (pure Python)
408
- - Note: Backends are not yet functional on these platforms
510
+ - Swift toolchain (optional, for building the Swift CLI helper)
511
+ - If Swift is not available, pre-built binary is included in the package
409
512
 
410
513
  ---
411
514
 
@@ -26,10 +26,10 @@ Ideal for VRChat, games, DAWs, browsers, and AI audio analysis pipelines.
26
26
  | Platform | Status | Backend | Notes |
27
27
  |----------|--------|---------|-------|
28
28
  | **Windows** | ✅ **Fully Supported** | WASAPI (C++ native) | Windows 10/11 (20H1+) |
29
- | **Linux** | 🧪 **Experimental** | PulseAudio/PipeWire | Basic support, sink monitor capture |
29
+ | **Linux** | **Fully Supported** | PipeWire Native / PulseAudio | Per-process isolation, auto-fallback (v0.3.0+) |
30
30
  | **macOS** | 🧪 **Experimental** | Core Audio Process Tap | macOS 14.4+ (Sonoma) required |
31
31
 
32
- <sub>\* Linux and macOS support are experimental with limitations (see requirements). Windows is currently the only fully functional platform.</sub>
32
+ <sub>\* Linux is fully supported with PipeWire/PulseAudio (v0.3.0+). macOS support is experimental (see requirements).</sub>
33
33
 
34
34
  </div>
35
35
 
@@ -41,11 +41,11 @@ Ideal for VRChat, games, DAWs, browsers, and AI audio analysis pipelines.
41
41
  (VRChat, games, browsers, Discord, DAWs, streaming tools, etc.)
42
42
 
43
43
  - 🌍 **Cross-platform architecture**
44
- → Windows (fully supported) | Linux (experimental) | macOS (experimental, 14.4+)
44
+ → Windows (fully supported) | Linux (fully supported, v0.3.0+) | macOS (experimental, 14.4+)
45
45
 
46
46
  - ⚡ **Platform-optimized backends**
47
47
  → Windows: ActivateAudioInterfaceAsync (modern WASAPI)
48
- → Linux: PulseAudio/PipeWire (experimental)
48
+ → Linux: PipeWire Native API / PulseAudio (fully supported, v0.3.0+)
49
49
  → macOS: Core Audio Process Tap API (macOS 14.4+)
50
50
 
51
51
  - 🧵 **Low-latency, thread-safe audio engine**
@@ -79,6 +79,22 @@ pip install proc-tap
79
79
  sudo dnf install pulseaudio-utils
80
80
  ```
81
81
 
82
+ **Optional: High-Quality Audio Resampling** (74% faster / 3.8x speedup for sample rate conversion):
83
+
84
+ ```bash
85
+ pip install proc-tap[hq-resample]
86
+ ```
87
+
88
+ **Performance:** With `libsamplerate`, resampling achieves **0.66ms per 10ms chunk** (vs 2.6ms with scipy-only).
89
+
90
+ **Compatibility Notes:**
91
+ - ✅ **Python 3.10-3.12**: Works on all platforms
92
+ - ✅ **Linux/macOS + Python 3.13+**: Should work (you can try it!)
93
+ - ⚠️ **Windows + Python 3.13+**: May fail to build (as of 2025-01)
94
+ - If it fails, the library automatically falls back to scipy's polyphase filtering
95
+ - Still provides excellent audio quality, just 74% slower for resampling
96
+ - You can still try installing - if it works, great! If not, no harm done.
97
+
82
98
  📚 **[Read the Full Documentation](https://m96-chan.github.io/ProcTap/)** for detailed guides and API reference.
83
99
 
84
100
  **From TestPyPI** (for testing pre-releases):
@@ -97,6 +113,58 @@ pip install -e .
97
113
 
98
114
  ---
99
115
 
116
+ ## 🎬 CLI Usage (Pipe to FFmpeg)
117
+
118
+ ProcTap includes a CLI for piping audio directly to FFmpeg or other tools:
119
+
120
+ ```bash
121
+ # Pipe to FFmpeg (MP3 encoding) - Direct command
122
+ proctap --pid 12345 --stdout | ffmpeg -f s16le -ar 48000 -ac 2 -i pipe:0 output.mp3
123
+
124
+ # Or using python -m
125
+ python -m proctap --pid 12345 --stdout | ffmpeg -f s16le -ar 48000 -ac 2 -i pipe:0 output.mp3
126
+
127
+ # Using process name instead of PID
128
+ proctap --name "VRChat.exe" --stdout | ffmpeg -f s16le -ar 48000 -ac 2 -i pipe:0 output.mp3
129
+
130
+ # FLAC encoding (lossless)
131
+ proctap --pid 12345 --stdout | ffmpeg -f s16le -ar 48000 -ac 2 -i pipe:0 output.flac
132
+
133
+ # Custom sample rate and mono output
134
+ proctap --pid 12345 --sample-rate 44100 --channels 1 --stdout | ffmpeg -f s16le -ar 44100 -ac 1 -i pipe:0 output.wav
135
+ ```
136
+
137
+ **CLI Options:**
138
+
139
+ | Option | Description |
140
+ |--------|-------------|
141
+ | `--pid PID` | Process ID to capture (required if `--name` not used) |
142
+ | `--name NAME` | Process name to capture (e.g., `VRChat.exe` or `VRChat`) |
143
+ | `--stdout` | Output raw PCM to stdout for piping (required) |
144
+ | `--sample-rate RATE` | Sample rate in Hz (default: 48000) |
145
+ | `--channels {1,2}` | Number of channels: 1=mono, 2=stereo (default: 2) |
146
+ | `--verbose` | Enable verbose logging to stderr |
147
+
148
+ **Finding Process IDs:**
149
+
150
+ ```bash
151
+ # Windows
152
+ tasklist | findstr "VRChat"
153
+
154
+ # Linux/macOS
155
+ ps aux | grep VRChat
156
+ ```
157
+
158
+ **FFmpeg Format Arguments:**
159
+
160
+ The CLI outputs raw PCM in s16le (signed 16-bit little-endian) format by default, but can be customized via `--sample-rate` and `--channels` options. FFmpeg needs these arguments:
161
+ - `-f s16le`: PCM format
162
+ - `-ar RATE`: Sample rate (must match `--sample-rate`, default 48000)
163
+ - `-ac CHANNELS`: Number of channels (must match `--channels`, default 2)
164
+ - `-i pipe:0`: Read from stdin
165
+
166
+ ---
167
+
100
168
  ## 🛠 Requirements
101
169
 
102
170
  **Windows (Fully Supported):**
@@ -105,13 +173,21 @@ pip install -e .
105
173
  - WASAPI support
106
174
  - **No admin privileges required**
107
175
 
108
- **Linux (Experimental):**
109
- - Linux with PulseAudio or PipeWire (with pulseaudio-compat)
176
+ **Linux (Fully Supported - v0.3.0+):**
177
+ - Linux with PulseAudio or PipeWire
110
178
  - Python 3.10+
111
- - `pulsectl` library: **automatically installed with `pip install proc-tap`**
112
- - `parec` command: install with `sudo apt-get install pulseaudio-utils`
113
- - ⚠️ **EXPERIMENTAL:** Basic PulseAudio support implemented
114
- - ⚠️ **LIMITATION:** Currently captures from entire sink monitor (may include other apps)
179
+ - **Auto-detection:** Automatically selects best available backend
180
+ - **Native PipeWire API** (in development, experimental):
181
+ - `libpipewire-0.3-dev`: `sudo apt-get install libpipewire-0.3-dev`
182
+ - Target latency: ~2-5ms (when fully implemented)
183
+ - Auto-selected when available (may fall back to subprocess)
184
+ - **PipeWire subprocess:**
185
+ - `pw-record`: install with `sudo apt-get install pipewire-media-session`
186
+ - **PulseAudio fallback:**
187
+ - `pulsectl` library: automatically installed
188
+ - `parec` command: `sudo apt-get install pulseaudio-utils`
189
+ - ✅ **Per-process isolation** using null-sink strategy
190
+ - ✅ **Graceful fallback** chain: Native → PipeWire subprocess → PulseAudio
115
191
 
116
192
  **macOS (Experimental):**
117
193
  - macOS 14.4 (Sonoma) or later
@@ -197,15 +273,29 @@ asyncio.run(main())
197
273
 
198
274
  ### Audio Format
199
275
 
200
- **Note:** The native extension uses a **fixed audio format** (hardcoded in C++):
276
+ **Native Backend Format** (Windows WASAPI, hardcoded in C++):
201
277
 
202
278
  | Parameter | Value | Description |
203
279
  |-----------|-------|-------------|
204
- | Sample Rate | **44,100 Hz** | CD quality (fixed) |
205
- | Channels | **2** | Stereo (fixed) |
206
- | Bit Depth | **16-bit** | PCM format (fixed) |
280
+ | Sample Rate | **44,100 Hz** | CD quality (fixed in C++) |
281
+ | Channels | **2** | Stereo (fixed in C++) |
282
+ | Bit Depth | **16-bit** | PCM format (fixed in C++) |
283
+
284
+ **Output Format Conversion** (v0.2.1+):
285
+
286
+ The `StreamConfig` class controls the **output format** through automatic conversion:
287
+ - Native format → converted to match your `StreamConfig` settings
288
+ - Supports sample rate conversion (e.g., 44.1kHz → 48kHz)
289
+ - Supports channel conversion (mono ↔ stereo)
290
+ - Supports bit depth conversion (8/16/24/32-bit)
291
+ - Zero overhead when formats match (automatic bypass)
207
292
 
208
- The `StreamConfig` class exists for API compatibility but does not change the native backend format.
293
+ Example:
294
+ ```python
295
+ # Get audio as 48kHz mono 24-bit
296
+ config = StreamConfig(sample_rate=48000, channels=1, width=3)
297
+ tap = ProcTap(pid, config=config)
298
+ ```
209
299
 
210
300
  ---
211
301
 
@@ -270,7 +360,7 @@ finally:
270
360
  ## 🐧 Linux Example
271
361
 
272
362
  ```python
273
- from proctap import ProcessAudioTap, StreamConfig
363
+ from proctap import ProcessAudioCapture, StreamConfig
274
364
  import wave
275
365
 
276
366
  pid = 12345 # Your target process ID
@@ -288,7 +378,7 @@ def on_data(pcm, frames):
288
378
  config = StreamConfig(sample_rate=44100, channels=2)
289
379
 
290
380
  try:
291
- with ProcessAudioTap(pid, config=config, on_data=on_data):
381
+ with ProcessAudioCapture(pid, config=config, on_data=on_data):
292
382
  print("⚠️ Make sure the process is actively playing audio!")
293
383
  input("Recording... Press Enter to stop.\n")
294
384
  finally:
@@ -306,7 +396,7 @@ finally:
306
396
  ## 🍎 macOS Example
307
397
 
308
398
  ```python
309
- from proctap import ProcessAudioTap, StreamConfig
399
+ from proctap import ProcessAudioCapture, StreamConfig
310
400
  import wave
311
401
 
312
402
  pid = 12345 # Your target process ID
@@ -324,7 +414,7 @@ def on_data(pcm, frames):
324
414
  config = StreamConfig(sample_rate=48000, channels=2)
325
415
 
326
416
  try:
327
- with ProcessAudioTap(pid, config=config, on_data=on_data):
417
+ with ProcessAudioCapture(pid, config=config, on_data=on_data):
328
418
  print("⚠️ Make sure the process is actively playing audio!")
329
419
  print("⚠️ On first run, macOS will prompt for permission.")
330
420
  input("Recording... Press Enter to stop.\n")
@@ -361,9 +451,14 @@ pip install -e .
361
451
  - Windows SDK
362
452
  - CMake (if you modularize the C++ code)
363
453
 
364
- **Linux/macOS:**
454
+ **Linux:**
455
+ - No C++ compiler required (pure Python)
456
+ - System dependencies: `pulseaudio-utils` or `pipewire` with `libpipewire-0.3-dev`
457
+
458
+ **macOS:**
365
459
  - No C++ compiler required (pure Python)
366
- - Note: Backends are not yet functional on these platforms
460
+ - Swift toolchain (optional, for building the Swift CLI helper)
461
+ - If Swift is not available, pre-built binary is included in the package
367
462
 
368
463
  ---
369
464
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "proc-tap"
7
- version = "0.2.0"
7
+ version = "0.3.1"
8
8
  description = "Cross-platform process-level audio capture library"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -35,6 +35,8 @@ classifiers = [
35
35
 
36
36
  # Platform-specific dependencies (automatically installed based on OS)
37
37
  dependencies = [
38
+ "numpy>=1.20.0",
39
+ "scipy>=1.7.0",
38
40
  "pulsectl>=23.5.0; sys_platform == 'linux'",
39
41
  ]
40
42
 
@@ -43,11 +45,16 @@ Homepage = "https://github.com/m96-chan/ProcTap"
43
45
  Repository = "https://github.com/m96-chan/ProcTap"
44
46
  Issues = "https://github.com/m96-chan/ProcTap/issues"
45
47
 
48
+ [project.scripts]
49
+ proctap = "proctap.__main__:main"
50
+
46
51
  [project.optional-dependencies]
47
52
  dev = [
48
53
  "pytest",
49
54
  "mypy",
50
- "types-setuptools"
55
+ "types-setuptools",
56
+ "types-psutil",
57
+ "scipy-stubs",
51
58
  ]
52
59
  docs = [
53
60
  "mkdocs-material>=9.0.0",
@@ -56,7 +63,51 @@ docs = [
56
63
  linux = [
57
64
  "pulsectl>=23.5.0",
58
65
  ]
66
+ # Contrib modules with optional dependencies
67
+ contrib = [
68
+ "faster-whisper>=1.0.0",
69
+ ]
70
+ # High-quality resampling using libsamplerate (optional, scipy fallback available)
71
+ # Note: samplerate package may fail to build on Windows with Python 3.13+ due to
72
+ # C compiler compatibility issues (as of 2025-01). Non-Windows platforms and
73
+ # Python <3.13 should work fine. If installation fails, scipy's polyphase
74
+ # filtering provides excellent quality as a fallback (though 30-50% slower).
75
+ # This is an optional optimization - the converter works well without it.
76
+ hq-resample = [
77
+ "samplerate>=0.1.0; python_version < '3.13' or sys_platform != 'win32'",
78
+ ]
59
79
 
60
80
  [tool.setuptools.packages.find]
61
81
  where = ["src"]
62
82
  include = ["proctap*"]
83
+
84
+ [tool.pytest.ini_options]
85
+ testpaths = ["tests"]
86
+ python_files = ["test_*.py"]
87
+ python_classes = ["Test*"]
88
+ python_functions = ["test_*"]
89
+ addopts = [
90
+ "-v",
91
+ "--tb=short",
92
+ ]
93
+
94
+ [tool.mypy]
95
+ python_version = "3.10"
96
+ warn_return_any = true
97
+ warn_unused_configs = true
98
+ disallow_untyped_defs = false
99
+ ignore_missing_imports = false
100
+
101
+ # Platform-specific and optional dependencies
102
+ [[tool.mypy.overrides]]
103
+ module = [
104
+ "pulsectl",
105
+ "pulsectl.*",
106
+ "discord",
107
+ "discord.*",
108
+ "faster_whisper",
109
+ "faster_whisper.*",
110
+ "samplerate",
111
+ "samplerate.*",
112
+ ]
113
+ ignore_missing_imports = true