Skip to main content

Process-level audio tap for Windows

Project description

📡 ProcTap

Per-Process Audio Capture for Windows

PyPI version Python versions Downloads Platform

Build wheels License: MIT Code style GitHub stars


ProcTap is a Python library with a high-performance C++ backend that enables per-process audio capture on Windows 10/11 (20H1+) using ActivateAudioInterfaceAsync.

Capture audio from a specific process only — without system sounds or other app audio mixed in. Ideal for VRChat, games, DAWs, browsers, and AI audio analysis pipelines.


🚀 Features

  • 🎧 Capture audio from a single target process
    (VRChat, games, browsers, Discord, DAWs, streaming tools, etc.)

  • Uses ActivateAudioInterfaceAsync (modern WASAPI)
    → More stable than legacy IAudioClient2 loopback approaches

  • 🧵 Low-latency, thread-safe C++ engine → 44.1 kHz / stereo / 16-bit PCM format

  • 🐍 Python-friendly high-level API

    • Callback-based streaming
    • Async generator streaming (async for)
  • 🔌 Native extension for high-throughput PCM delivery

  • 🪟 Windows-only (10/11, 20H1+)


📦 Installation

From PyPI (coming soon):

pip install proctap

From TestPyPI (for testing pre-releases):

pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ proctap

From Source:

git clone https://github.com/m96-chan/ProcTap
cd ProcTap
pip install -e .

🛠 Requirements

  • Windows 10 / 11 (20H1 or later recommended)
  • Python 3.10+
  • WASAPI support
  • No admin privileges required
    (Per-process loopback capture works with standard user permissions)

🧰 Basic Usage (Callback API)

from proctap import ProcTap, StreamConfig

def on_chunk(pcm: bytes, frames: int):
    print(f"Received {len(pcm)} bytes ({frames} frames)")

pid = 12345  # Target process ID

tap = ProcTap(pid, StreamConfig(), on_data=on_chunk)
tap.start()

input("Recording... Press Enter to stop.\n")

tap.close()

🔁 Async Usage (Async Generator)

import asyncio
from proctap import ProcTap

async def main():
    tap = ProcTap(pid=12345)
    tap.start()

    async for chunk in tap.iter_chunks():
        print(f"PCM chunk size: {len(chunk)} bytes")

asyncio.run(main())

📄 API Overview

class ProcTap

Control Methods:

Method Description
start() Start WASAPI per-process capture
stop() Stop capture
close() Release native resources

Data Access:

Method Description
iter_chunks() Async generator yielding PCM chunks
read(timeout=1.0) Synchronous: read one chunk (blocking)

Properties:

Property Type Description
is_running bool Check if capture is active
pid int Get target process ID
config StreamConfig Get stream configuration

Utility Methods:

Method Description
set_callback(callback) Change or remove audio callback
get_format() Get audio format info (dict)

Audio Format

Note: The native extension uses a fixed audio format (hardcoded in C++):

Parameter Value Description
Sample Rate 44,100 Hz CD quality (fixed)
Channels 2 Stereo (fixed)
Bit Depth 16-bit PCM format (fixed)

The StreamConfig class exists for API compatibility but does not change the native backend format.


🎯 Use Cases

  • 🎮 Record audio from one game only
  • 🕶 Capture VRChat audio cleanly (without system sounds)
  • 🎙 Feed high-SNR audio into AI recognition models
  • 📹 Alternative to OBS "Application Audio Capture"
  • 🎧 Capture DAW/app playback for analysis tools

📚 Example: Save to WAV

from proctap import ProcTap
import wave

pid = 12345

wav = wave.open("output.wav", "wb")
wav.setnchannels(2)
wav.setsampwidth(2)  # 16-bit PCM
wav.setframerate(44100)  # Native format is 44.1 kHz

def on_data(pcm, frames):
    wav.writeframes(pcm)

with ProcTap(pid, on_data=on_data):
    input("Recording... Press Enter to stop.\n")

wav.close()

📚 Example: Synchronous Read API

from proctap import ProcTap

tap = ProcTap(pid=12345)
tap.start()

try:
    while True:
        chunk = tap.read(timeout=1.0)  # Blocking read
        if chunk:
            print(f"Got {len(chunk)} bytes")
            # Process audio data...
        else:
            print("Timeout, no data")
except KeyboardInterrupt:
    pass
finally:
    tap.close()

🏗 Build From Source

git clone https://github.com/m96-chan/ProcTap
cd ProcTap
pip install -e .

Requirements:

  • Visual Studio Build Tools
  • Windows SDK
  • CMake (if you modularize the C++ code)

🤝 Contributing

Contributions are welcome! We have structured issue templates to help guide your contributions:

Special Interest:

  • PRs from WASAPI/C++ experts are especially appreciated
  • Help with cross-platform compatibility research
  • Performance profiling and optimization

📄 License

MIT License

👤 Author

Yusuke Harada (m96-chan)
Windows Audio / VRChat Tools / Python / C++
https://github.com/m96-chan

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

proc_tap-0.1.1.tar.gz (18.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

proc_tap-0.1.1-cp311-cp311-win_amd64.whl (31.9 kB view details)

Uploaded CPython 3.11Windows x86-64

File details

Details for the file proc_tap-0.1.1.tar.gz.

File metadata

  • Download URL: proc_tap-0.1.1.tar.gz
  • Upload date:
  • Size: 18.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for proc_tap-0.1.1.tar.gz
Algorithm Hash digest
SHA256 bddfd5344143358c403dc8922ba5ccb491af92adbd262d55f776af94420636e7
MD5 1dc1539795ba8d1a81f81adfbc6cb458
BLAKE2b-256 a6fad6774645b0a817a5b95451174ab79e2c21dc6cb5e755fe491dffaea55606

See more details on using hashes here.

File details

Details for the file proc_tap-0.1.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: proc_tap-0.1.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 31.9 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for proc_tap-0.1.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 8b4f770e10ecbcf89242d290b511e22d62e5415a1026df0fbc76ac3f6c28764c
MD5 dafdf6e841a61f6bb9d8f22c02c3ab09
BLAKE2b-256 70b099b586c4871cedbf1b8d595f4b42f3c8e927709ab0042344fd0852340496

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page