proc-tap 0.2.0__tar.gz → 0.3.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.
- {proc_tap-0.2.0/src/proc_tap.egg-info → proc_tap-0.3.0}/PKG-INFO +73 -22
- {proc_tap-0.2.0 → proc_tap-0.3.0}/README.md +64 -21
- {proc_tap-0.2.0 → proc_tap-0.3.0}/pyproject.toml +50 -2
- {proc_tap-0.2.0 → proc_tap-0.3.0/src/proc_tap.egg-info}/PKG-INFO +73 -22
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proc_tap.egg-info/SOURCES.txt +12 -1
- proc_tap-0.3.0/src/proc_tap.egg-info/requires.txt +27 -0
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proctap/__init__.py +2 -2
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proctap/backends/__init__.py +8 -4
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proctap/backends/base.py +2 -1
- proc_tap-0.3.0/src/proctap/backends/converter.py +489 -0
- proc_tap-0.3.0/src/proctap/backends/linux.py +1389 -0
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proctap/backends/macos.py +2 -2
- proc_tap-0.3.0/src/proctap/backends/pipewire_native.py +1376 -0
- proc_tap-0.3.0/src/proctap/backends/windows.py +148 -0
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proctap/contrib/__init__.py +9 -2
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proctap/contrib/discord_source.py +9 -7
- proc_tap-0.3.0/src/proctap/contrib/filters/__init__.py +54 -0
- proc_tap-0.3.0/src/proctap/contrib/filters/base.py +49 -0
- proc_tap-0.3.0/src/proctap/contrib/filters/chain.py +131 -0
- proc_tap-0.3.0/src/proctap/contrib/filters/dsp.py +205 -0
- proc_tap-0.3.0/src/proctap/contrib/filters/dynamics.py +190 -0
- proc_tap-0.3.0/src/proctap/contrib/filters/vad.py +113 -0
- proc_tap-0.3.0/src/proctap/contrib/whisper_transcribe.py +494 -0
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proctap/core.py +77 -12
- proc_tap-0.3.0/tests/test_converter_optimizations.py +339 -0
- proc_tap-0.3.0/tests/test_pipewire_native.py +275 -0
- proc_tap-0.2.0/src/proc_tap.egg-info/requires.txt +0 -15
- proc_tap-0.2.0/src/proctap/backends/linux.py +0 -521
- proc_tap-0.2.0/src/proctap/backends/windows.py +0 -85
- {proc_tap-0.2.0 → proc_tap-0.3.0}/LICENSE +0 -0
- {proc_tap-0.2.0 → proc_tap-0.3.0}/setup.cfg +0 -0
- {proc_tap-0.2.0 → proc_tap-0.3.0}/setup.py +0 -0
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proc_tap.egg-info/dependency_links.txt +0 -0
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proc_tap.egg-info/top_level.txt +0 -0
- {proc_tap-0.2.0 → proc_tap-0.3.0}/src/proctap/_native.pyi +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: proc-tap
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
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** |
|
|
79
|
+
| **Linux** | ✅ **Fully Supported** | PipeWire Native / PulseAudio | Per-process isolation, auto-fallback (v0.4.0+) |
|
|
72
80
|
| **macOS** | 🧪 **Experimental** | Core Audio Process Tap | macOS 14.4+ (Sonoma) required |
|
|
73
81
|
|
|
74
|
-
<sub>\* Linux
|
|
82
|
+
<sub>\* Linux is fully supported with PipeWire/PulseAudio (v0.4.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 (
|
|
94
|
+
→ Windows (fully supported) | Linux (fully supported, v0.4.0+) | macOS (experimental, 14.4+)
|
|
87
95
|
|
|
88
96
|
- ⚡ **Platform-optimized backends**
|
|
89
97
|
→ Windows: ActivateAudioInterfaceAsync (modern WASAPI)
|
|
90
|
-
→ Linux:
|
|
98
|
+
→ Linux: PipeWire Native API / PulseAudio (fully supported, v0.4.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):
|
|
@@ -147,13 +171,21 @@ pip install -e .
|
|
|
147
171
|
- WASAPI support
|
|
148
172
|
- **No admin privileges required**
|
|
149
173
|
|
|
150
|
-
**Linux (
|
|
151
|
-
- Linux with PulseAudio or PipeWire
|
|
174
|
+
**Linux (Fully Supported - v0.4.0+):**
|
|
175
|
+
- Linux with PulseAudio or PipeWire
|
|
152
176
|
- Python 3.10+
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
177
|
+
- **Auto-detection:** Automatically selects best available backend
|
|
178
|
+
- **Native PipeWire API** (recommended):
|
|
179
|
+
- `libpipewire-0.3-dev`: `sudo apt-get install libpipewire-0.3-dev`
|
|
180
|
+
- Ultra-low latency: ~2-5ms
|
|
181
|
+
- Auto-selected when available
|
|
182
|
+
- **PipeWire subprocess:**
|
|
183
|
+
- `pw-record`: install with `sudo apt-get install pipewire-media-session`
|
|
184
|
+
- **PulseAudio fallback:**
|
|
185
|
+
- `pulsectl` library: automatically installed
|
|
186
|
+
- `parec` command: `sudo apt-get install pulseaudio-utils`
|
|
187
|
+
- ✅ **Per-process isolation** using null-sink strategy
|
|
188
|
+
- ✅ **Graceful fallback** chain: Native → PipeWire subprocess → PulseAudio
|
|
157
189
|
|
|
158
190
|
**macOS (Experimental):**
|
|
159
191
|
- macOS 14.4 (Sonoma) or later
|
|
@@ -239,15 +271,29 @@ asyncio.run(main())
|
|
|
239
271
|
|
|
240
272
|
### Audio Format
|
|
241
273
|
|
|
242
|
-
**
|
|
274
|
+
**Native Backend Format** (Windows WASAPI, hardcoded in C++):
|
|
243
275
|
|
|
244
276
|
| Parameter | Value | Description |
|
|
245
277
|
|-----------|-------|-------------|
|
|
246
|
-
| Sample Rate | **44,100 Hz** | CD quality (fixed) |
|
|
247
|
-
| Channels | **2** | Stereo (fixed) |
|
|
248
|
-
| Bit Depth | **16-bit** | PCM format (fixed) |
|
|
278
|
+
| Sample Rate | **44,100 Hz** | CD quality (fixed in C++) |
|
|
279
|
+
| Channels | **2** | Stereo (fixed in C++) |
|
|
280
|
+
| Bit Depth | **16-bit** | PCM format (fixed in C++) |
|
|
249
281
|
|
|
250
|
-
|
|
282
|
+
**Output Format Conversion** (v0.2.1+):
|
|
283
|
+
|
|
284
|
+
The `StreamConfig` class controls the **output format** through automatic conversion:
|
|
285
|
+
- Native format → converted to match your `StreamConfig` settings
|
|
286
|
+
- Supports sample rate conversion (e.g., 44.1kHz → 48kHz)
|
|
287
|
+
- Supports channel conversion (mono ↔ stereo)
|
|
288
|
+
- Supports bit depth conversion (8/16/24/32-bit)
|
|
289
|
+
- Zero overhead when formats match (automatic bypass)
|
|
290
|
+
|
|
291
|
+
Example:
|
|
292
|
+
```python
|
|
293
|
+
# Get audio as 48kHz mono 24-bit
|
|
294
|
+
config = StreamConfig(sample_rate=48000, channels=1, width=3)
|
|
295
|
+
tap = ProcTap(pid, config=config)
|
|
296
|
+
```
|
|
251
297
|
|
|
252
298
|
---
|
|
253
299
|
|
|
@@ -312,7 +358,7 @@ finally:
|
|
|
312
358
|
## 🐧 Linux Example
|
|
313
359
|
|
|
314
360
|
```python
|
|
315
|
-
from proctap import
|
|
361
|
+
from proctap import ProcessAudioCapture, StreamConfig
|
|
316
362
|
import wave
|
|
317
363
|
|
|
318
364
|
pid = 12345 # Your target process ID
|
|
@@ -330,7 +376,7 @@ def on_data(pcm, frames):
|
|
|
330
376
|
config = StreamConfig(sample_rate=44100, channels=2)
|
|
331
377
|
|
|
332
378
|
try:
|
|
333
|
-
with
|
|
379
|
+
with ProcessAudioCapture(pid, config=config, on_data=on_data):
|
|
334
380
|
print("⚠️ Make sure the process is actively playing audio!")
|
|
335
381
|
input("Recording... Press Enter to stop.\n")
|
|
336
382
|
finally:
|
|
@@ -348,7 +394,7 @@ finally:
|
|
|
348
394
|
## 🍎 macOS Example
|
|
349
395
|
|
|
350
396
|
```python
|
|
351
|
-
from proctap import
|
|
397
|
+
from proctap import ProcessAudioCapture, StreamConfig
|
|
352
398
|
import wave
|
|
353
399
|
|
|
354
400
|
pid = 12345 # Your target process ID
|
|
@@ -366,7 +412,7 @@ def on_data(pcm, frames):
|
|
|
366
412
|
config = StreamConfig(sample_rate=48000, channels=2)
|
|
367
413
|
|
|
368
414
|
try:
|
|
369
|
-
with
|
|
415
|
+
with ProcessAudioCapture(pid, config=config, on_data=on_data):
|
|
370
416
|
print("⚠️ Make sure the process is actively playing audio!")
|
|
371
417
|
print("⚠️ On first run, macOS will prompt for permission.")
|
|
372
418
|
input("Recording... Press Enter to stop.\n")
|
|
@@ -403,9 +449,14 @@ pip install -e .
|
|
|
403
449
|
- Windows SDK
|
|
404
450
|
- CMake (if you modularize the C++ code)
|
|
405
451
|
|
|
406
|
-
**Linux
|
|
452
|
+
**Linux:**
|
|
453
|
+
- No C++ compiler required (pure Python)
|
|
454
|
+
- System dependencies: `pulseaudio-utils` or `pipewire` with `libpipewire-0.3-dev`
|
|
455
|
+
|
|
456
|
+
**macOS:**
|
|
407
457
|
- No C++ compiler required (pure Python)
|
|
408
|
-
-
|
|
458
|
+
- Swift toolchain (optional, for building the Swift CLI helper)
|
|
459
|
+
- If Swift is not available, pre-built binary is included in the package
|
|
409
460
|
|
|
410
461
|
---
|
|
411
462
|
|
|
@@ -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** |
|
|
29
|
+
| **Linux** | ✅ **Fully Supported** | PipeWire Native / PulseAudio | Per-process isolation, auto-fallback (v0.4.0+) |
|
|
30
30
|
| **macOS** | 🧪 **Experimental** | Core Audio Process Tap | macOS 14.4+ (Sonoma) required |
|
|
31
31
|
|
|
32
|
-
<sub>\* Linux
|
|
32
|
+
<sub>\* Linux is fully supported with PipeWire/PulseAudio (v0.4.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 (
|
|
44
|
+
→ Windows (fully supported) | Linux (fully supported, v0.4.0+) | macOS (experimental, 14.4+)
|
|
45
45
|
|
|
46
46
|
- ⚡ **Platform-optimized backends**
|
|
47
47
|
→ Windows: ActivateAudioInterfaceAsync (modern WASAPI)
|
|
48
|
-
→ Linux:
|
|
48
|
+
→ Linux: PipeWire Native API / PulseAudio (fully supported, v0.4.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):
|
|
@@ -105,13 +121,21 @@ pip install -e .
|
|
|
105
121
|
- WASAPI support
|
|
106
122
|
- **No admin privileges required**
|
|
107
123
|
|
|
108
|
-
**Linux (
|
|
109
|
-
- Linux with PulseAudio or PipeWire
|
|
124
|
+
**Linux (Fully Supported - v0.4.0+):**
|
|
125
|
+
- Linux with PulseAudio or PipeWire
|
|
110
126
|
- Python 3.10+
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
127
|
+
- **Auto-detection:** Automatically selects best available backend
|
|
128
|
+
- **Native PipeWire API** (recommended):
|
|
129
|
+
- `libpipewire-0.3-dev`: `sudo apt-get install libpipewire-0.3-dev`
|
|
130
|
+
- Ultra-low latency: ~2-5ms
|
|
131
|
+
- Auto-selected when available
|
|
132
|
+
- **PipeWire subprocess:**
|
|
133
|
+
- `pw-record`: install with `sudo apt-get install pipewire-media-session`
|
|
134
|
+
- **PulseAudio fallback:**
|
|
135
|
+
- `pulsectl` library: automatically installed
|
|
136
|
+
- `parec` command: `sudo apt-get install pulseaudio-utils`
|
|
137
|
+
- ✅ **Per-process isolation** using null-sink strategy
|
|
138
|
+
- ✅ **Graceful fallback** chain: Native → PipeWire subprocess → PulseAudio
|
|
115
139
|
|
|
116
140
|
**macOS (Experimental):**
|
|
117
141
|
- macOS 14.4 (Sonoma) or later
|
|
@@ -197,15 +221,29 @@ asyncio.run(main())
|
|
|
197
221
|
|
|
198
222
|
### Audio Format
|
|
199
223
|
|
|
200
|
-
**
|
|
224
|
+
**Native Backend Format** (Windows WASAPI, hardcoded in C++):
|
|
201
225
|
|
|
202
226
|
| Parameter | Value | Description |
|
|
203
227
|
|-----------|-------|-------------|
|
|
204
|
-
| Sample Rate | **44,100 Hz** | CD quality (fixed) |
|
|
205
|
-
| Channels | **2** | Stereo (fixed) |
|
|
206
|
-
| Bit Depth | **16-bit** | PCM format (fixed) |
|
|
228
|
+
| Sample Rate | **44,100 Hz** | CD quality (fixed in C++) |
|
|
229
|
+
| Channels | **2** | Stereo (fixed in C++) |
|
|
230
|
+
| Bit Depth | **16-bit** | PCM format (fixed in C++) |
|
|
207
231
|
|
|
208
|
-
|
|
232
|
+
**Output Format Conversion** (v0.2.1+):
|
|
233
|
+
|
|
234
|
+
The `StreamConfig` class controls the **output format** through automatic conversion:
|
|
235
|
+
- Native format → converted to match your `StreamConfig` settings
|
|
236
|
+
- Supports sample rate conversion (e.g., 44.1kHz → 48kHz)
|
|
237
|
+
- Supports channel conversion (mono ↔ stereo)
|
|
238
|
+
- Supports bit depth conversion (8/16/24/32-bit)
|
|
239
|
+
- Zero overhead when formats match (automatic bypass)
|
|
240
|
+
|
|
241
|
+
Example:
|
|
242
|
+
```python
|
|
243
|
+
# Get audio as 48kHz mono 24-bit
|
|
244
|
+
config = StreamConfig(sample_rate=48000, channels=1, width=3)
|
|
245
|
+
tap = ProcTap(pid, config=config)
|
|
246
|
+
```
|
|
209
247
|
|
|
210
248
|
---
|
|
211
249
|
|
|
@@ -270,7 +308,7 @@ finally:
|
|
|
270
308
|
## 🐧 Linux Example
|
|
271
309
|
|
|
272
310
|
```python
|
|
273
|
-
from proctap import
|
|
311
|
+
from proctap import ProcessAudioCapture, StreamConfig
|
|
274
312
|
import wave
|
|
275
313
|
|
|
276
314
|
pid = 12345 # Your target process ID
|
|
@@ -288,7 +326,7 @@ def on_data(pcm, frames):
|
|
|
288
326
|
config = StreamConfig(sample_rate=44100, channels=2)
|
|
289
327
|
|
|
290
328
|
try:
|
|
291
|
-
with
|
|
329
|
+
with ProcessAudioCapture(pid, config=config, on_data=on_data):
|
|
292
330
|
print("⚠️ Make sure the process is actively playing audio!")
|
|
293
331
|
input("Recording... Press Enter to stop.\n")
|
|
294
332
|
finally:
|
|
@@ -306,7 +344,7 @@ finally:
|
|
|
306
344
|
## 🍎 macOS Example
|
|
307
345
|
|
|
308
346
|
```python
|
|
309
|
-
from proctap import
|
|
347
|
+
from proctap import ProcessAudioCapture, StreamConfig
|
|
310
348
|
import wave
|
|
311
349
|
|
|
312
350
|
pid = 12345 # Your target process ID
|
|
@@ -324,7 +362,7 @@ def on_data(pcm, frames):
|
|
|
324
362
|
config = StreamConfig(sample_rate=48000, channels=2)
|
|
325
363
|
|
|
326
364
|
try:
|
|
327
|
-
with
|
|
365
|
+
with ProcessAudioCapture(pid, config=config, on_data=on_data):
|
|
328
366
|
print("⚠️ Make sure the process is actively playing audio!")
|
|
329
367
|
print("⚠️ On first run, macOS will prompt for permission.")
|
|
330
368
|
input("Recording... Press Enter to stop.\n")
|
|
@@ -361,9 +399,14 @@ pip install -e .
|
|
|
361
399
|
- Windows SDK
|
|
362
400
|
- CMake (if you modularize the C++ code)
|
|
363
401
|
|
|
364
|
-
**Linux
|
|
402
|
+
**Linux:**
|
|
403
|
+
- No C++ compiler required (pure Python)
|
|
404
|
+
- System dependencies: `pulseaudio-utils` or `pipewire` with `libpipewire-0.3-dev`
|
|
405
|
+
|
|
406
|
+
**macOS:**
|
|
365
407
|
- No C++ compiler required (pure Python)
|
|
366
|
-
-
|
|
408
|
+
- Swift toolchain (optional, for building the Swift CLI helper)
|
|
409
|
+
- If Swift is not available, pre-built binary is included in the package
|
|
367
410
|
|
|
368
411
|
---
|
|
369
412
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "proc-tap"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
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
|
|
|
@@ -47,7 +49,9 @@ Issues = "https://github.com/m96-chan/ProcTap/issues"
|
|
|
47
49
|
dev = [
|
|
48
50
|
"pytest",
|
|
49
51
|
"mypy",
|
|
50
|
-
"types-setuptools"
|
|
52
|
+
"types-setuptools",
|
|
53
|
+
"types-psutil",
|
|
54
|
+
"scipy-stubs",
|
|
51
55
|
]
|
|
52
56
|
docs = [
|
|
53
57
|
"mkdocs-material>=9.0.0",
|
|
@@ -56,7 +60,51 @@ docs = [
|
|
|
56
60
|
linux = [
|
|
57
61
|
"pulsectl>=23.5.0",
|
|
58
62
|
]
|
|
63
|
+
# Contrib modules with optional dependencies
|
|
64
|
+
contrib = [
|
|
65
|
+
"faster-whisper>=1.0.0",
|
|
66
|
+
]
|
|
67
|
+
# High-quality resampling using libsamplerate (optional, scipy fallback available)
|
|
68
|
+
# Note: samplerate package may fail to build on Windows with Python 3.13+ due to
|
|
69
|
+
# C compiler compatibility issues (as of 2025-01). Non-Windows platforms and
|
|
70
|
+
# Python <3.13 should work fine. If installation fails, scipy's polyphase
|
|
71
|
+
# filtering provides excellent quality as a fallback (though 30-50% slower).
|
|
72
|
+
# This is an optional optimization - the converter works well without it.
|
|
73
|
+
hq-resample = [
|
|
74
|
+
"samplerate>=0.1.0; python_version < '3.13' or sys_platform != 'win32'",
|
|
75
|
+
]
|
|
59
76
|
|
|
60
77
|
[tool.setuptools.packages.find]
|
|
61
78
|
where = ["src"]
|
|
62
79
|
include = ["proctap*"]
|
|
80
|
+
|
|
81
|
+
[tool.pytest.ini_options]
|
|
82
|
+
testpaths = ["tests"]
|
|
83
|
+
python_files = ["test_*.py"]
|
|
84
|
+
python_classes = ["Test*"]
|
|
85
|
+
python_functions = ["test_*"]
|
|
86
|
+
addopts = [
|
|
87
|
+
"-v",
|
|
88
|
+
"--tb=short",
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
[tool.mypy]
|
|
92
|
+
python_version = "3.10"
|
|
93
|
+
warn_return_any = true
|
|
94
|
+
warn_unused_configs = true
|
|
95
|
+
disallow_untyped_defs = false
|
|
96
|
+
ignore_missing_imports = false
|
|
97
|
+
|
|
98
|
+
# Platform-specific and optional dependencies
|
|
99
|
+
[[tool.mypy.overrides]]
|
|
100
|
+
module = [
|
|
101
|
+
"pulsectl",
|
|
102
|
+
"pulsectl.*",
|
|
103
|
+
"discord",
|
|
104
|
+
"discord.*",
|
|
105
|
+
"faster_whisper",
|
|
106
|
+
"faster_whisper.*",
|
|
107
|
+
"samplerate",
|
|
108
|
+
"samplerate.*",
|
|
109
|
+
]
|
|
110
|
+
ignore_missing_imports = true
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: proc-tap
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
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** |
|
|
79
|
+
| **Linux** | ✅ **Fully Supported** | PipeWire Native / PulseAudio | Per-process isolation, auto-fallback (v0.4.0+) |
|
|
72
80
|
| **macOS** | 🧪 **Experimental** | Core Audio Process Tap | macOS 14.4+ (Sonoma) required |
|
|
73
81
|
|
|
74
|
-
<sub>\* Linux
|
|
82
|
+
<sub>\* Linux is fully supported with PipeWire/PulseAudio (v0.4.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 (
|
|
94
|
+
→ Windows (fully supported) | Linux (fully supported, v0.4.0+) | macOS (experimental, 14.4+)
|
|
87
95
|
|
|
88
96
|
- ⚡ **Platform-optimized backends**
|
|
89
97
|
→ Windows: ActivateAudioInterfaceAsync (modern WASAPI)
|
|
90
|
-
→ Linux:
|
|
98
|
+
→ Linux: PipeWire Native API / PulseAudio (fully supported, v0.4.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):
|
|
@@ -147,13 +171,21 @@ pip install -e .
|
|
|
147
171
|
- WASAPI support
|
|
148
172
|
- **No admin privileges required**
|
|
149
173
|
|
|
150
|
-
**Linux (
|
|
151
|
-
- Linux with PulseAudio or PipeWire
|
|
174
|
+
**Linux (Fully Supported - v0.4.0+):**
|
|
175
|
+
- Linux with PulseAudio or PipeWire
|
|
152
176
|
- Python 3.10+
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
177
|
+
- **Auto-detection:** Automatically selects best available backend
|
|
178
|
+
- **Native PipeWire API** (recommended):
|
|
179
|
+
- `libpipewire-0.3-dev`: `sudo apt-get install libpipewire-0.3-dev`
|
|
180
|
+
- Ultra-low latency: ~2-5ms
|
|
181
|
+
- Auto-selected when available
|
|
182
|
+
- **PipeWire subprocess:**
|
|
183
|
+
- `pw-record`: install with `sudo apt-get install pipewire-media-session`
|
|
184
|
+
- **PulseAudio fallback:**
|
|
185
|
+
- `pulsectl` library: automatically installed
|
|
186
|
+
- `parec` command: `sudo apt-get install pulseaudio-utils`
|
|
187
|
+
- ✅ **Per-process isolation** using null-sink strategy
|
|
188
|
+
- ✅ **Graceful fallback** chain: Native → PipeWire subprocess → PulseAudio
|
|
157
189
|
|
|
158
190
|
**macOS (Experimental):**
|
|
159
191
|
- macOS 14.4 (Sonoma) or later
|
|
@@ -239,15 +271,29 @@ asyncio.run(main())
|
|
|
239
271
|
|
|
240
272
|
### Audio Format
|
|
241
273
|
|
|
242
|
-
**
|
|
274
|
+
**Native Backend Format** (Windows WASAPI, hardcoded in C++):
|
|
243
275
|
|
|
244
276
|
| Parameter | Value | Description |
|
|
245
277
|
|-----------|-------|-------------|
|
|
246
|
-
| Sample Rate | **44,100 Hz** | CD quality (fixed) |
|
|
247
|
-
| Channels | **2** | Stereo (fixed) |
|
|
248
|
-
| Bit Depth | **16-bit** | PCM format (fixed) |
|
|
278
|
+
| Sample Rate | **44,100 Hz** | CD quality (fixed in C++) |
|
|
279
|
+
| Channels | **2** | Stereo (fixed in C++) |
|
|
280
|
+
| Bit Depth | **16-bit** | PCM format (fixed in C++) |
|
|
249
281
|
|
|
250
|
-
|
|
282
|
+
**Output Format Conversion** (v0.2.1+):
|
|
283
|
+
|
|
284
|
+
The `StreamConfig` class controls the **output format** through automatic conversion:
|
|
285
|
+
- Native format → converted to match your `StreamConfig` settings
|
|
286
|
+
- Supports sample rate conversion (e.g., 44.1kHz → 48kHz)
|
|
287
|
+
- Supports channel conversion (mono ↔ stereo)
|
|
288
|
+
- Supports bit depth conversion (8/16/24/32-bit)
|
|
289
|
+
- Zero overhead when formats match (automatic bypass)
|
|
290
|
+
|
|
291
|
+
Example:
|
|
292
|
+
```python
|
|
293
|
+
# Get audio as 48kHz mono 24-bit
|
|
294
|
+
config = StreamConfig(sample_rate=48000, channels=1, width=3)
|
|
295
|
+
tap = ProcTap(pid, config=config)
|
|
296
|
+
```
|
|
251
297
|
|
|
252
298
|
---
|
|
253
299
|
|
|
@@ -312,7 +358,7 @@ finally:
|
|
|
312
358
|
## 🐧 Linux Example
|
|
313
359
|
|
|
314
360
|
```python
|
|
315
|
-
from proctap import
|
|
361
|
+
from proctap import ProcessAudioCapture, StreamConfig
|
|
316
362
|
import wave
|
|
317
363
|
|
|
318
364
|
pid = 12345 # Your target process ID
|
|
@@ -330,7 +376,7 @@ def on_data(pcm, frames):
|
|
|
330
376
|
config = StreamConfig(sample_rate=44100, channels=2)
|
|
331
377
|
|
|
332
378
|
try:
|
|
333
|
-
with
|
|
379
|
+
with ProcessAudioCapture(pid, config=config, on_data=on_data):
|
|
334
380
|
print("⚠️ Make sure the process is actively playing audio!")
|
|
335
381
|
input("Recording... Press Enter to stop.\n")
|
|
336
382
|
finally:
|
|
@@ -348,7 +394,7 @@ finally:
|
|
|
348
394
|
## 🍎 macOS Example
|
|
349
395
|
|
|
350
396
|
```python
|
|
351
|
-
from proctap import
|
|
397
|
+
from proctap import ProcessAudioCapture, StreamConfig
|
|
352
398
|
import wave
|
|
353
399
|
|
|
354
400
|
pid = 12345 # Your target process ID
|
|
@@ -366,7 +412,7 @@ def on_data(pcm, frames):
|
|
|
366
412
|
config = StreamConfig(sample_rate=48000, channels=2)
|
|
367
413
|
|
|
368
414
|
try:
|
|
369
|
-
with
|
|
415
|
+
with ProcessAudioCapture(pid, config=config, on_data=on_data):
|
|
370
416
|
print("⚠️ Make sure the process is actively playing audio!")
|
|
371
417
|
print("⚠️ On first run, macOS will prompt for permission.")
|
|
372
418
|
input("Recording... Press Enter to stop.\n")
|
|
@@ -403,9 +449,14 @@ pip install -e .
|
|
|
403
449
|
- Windows SDK
|
|
404
450
|
- CMake (if you modularize the C++ code)
|
|
405
451
|
|
|
406
|
-
**Linux
|
|
452
|
+
**Linux:**
|
|
453
|
+
- No C++ compiler required (pure Python)
|
|
454
|
+
- System dependencies: `pulseaudio-utils` or `pipewire` with `libpipewire-0.3-dev`
|
|
455
|
+
|
|
456
|
+
**macOS:**
|
|
407
457
|
- No C++ compiler required (pure Python)
|
|
408
|
-
-
|
|
458
|
+
- Swift toolchain (optional, for building the Swift CLI helper)
|
|
459
|
+
- If Swift is not available, pre-built binary is included in the package
|
|
409
460
|
|
|
410
461
|
---
|
|
411
462
|
|
|
@@ -13,8 +13,19 @@ src/proctap/_native.pyi
|
|
|
13
13
|
src/proctap/core.py
|
|
14
14
|
src/proctap/backends/__init__.py
|
|
15
15
|
src/proctap/backends/base.py
|
|
16
|
+
src/proctap/backends/converter.py
|
|
16
17
|
src/proctap/backends/linux.py
|
|
17
18
|
src/proctap/backends/macos.py
|
|
19
|
+
src/proctap/backends/pipewire_native.py
|
|
18
20
|
src/proctap/backends/windows.py
|
|
19
21
|
src/proctap/contrib/__init__.py
|
|
20
|
-
src/proctap/contrib/discord_source.py
|
|
22
|
+
src/proctap/contrib/discord_source.py
|
|
23
|
+
src/proctap/contrib/whisper_transcribe.py
|
|
24
|
+
src/proctap/contrib/filters/__init__.py
|
|
25
|
+
src/proctap/contrib/filters/base.py
|
|
26
|
+
src/proctap/contrib/filters/chain.py
|
|
27
|
+
src/proctap/contrib/filters/dsp.py
|
|
28
|
+
src/proctap/contrib/filters/dynamics.py
|
|
29
|
+
src/proctap/contrib/filters/vad.py
|
|
30
|
+
tests/test_converter_optimizations.py
|
|
31
|
+
tests/test_pipewire_native.py
|