Skip to main content

Low-latency macOS audio capture and processing (AEC/NS) powered by Rust

Project description

macloop

CI PyPI TestPyPI codecov

Low-latency macOS audio capture and processing for Python, powered by Rust.

  • System audio and microphone capture via ScreenCaptureKit
  • WebRTC-based AEC (echo cancellation) and NS (noise suppression)
  • Sync and async streaming APIs

Requirements

  • macOS (Apple Silicon or Intel)
  • Python 3.9+

Installation

pip install macloop

Quick Start (sync)

import macloop

sources = macloop.list_audio_sources()
display = next(s for s in sources if s["type"] == "display")

cfg = macloop.AudioProcessingConfig(
    sample_rate=16000,
    channels=1,
    sample_format="i16",
    enable_aec=True,
    enable_ns=False,
)

with macloop.Capture(
    display_id=display["display_id"],
    config=cfg,
    capture_system=True,
    capture_mic=True,
) as stream:
    for chunk in stream:
        print(chunk.source, len(chunk.samples))
        # chunk.samples is numpy.ndarray (int16 or float32)

Quick Start (asyncio)

import asyncio
import macloop

async def main():
    sources = macloop.list_audio_sources()
    display = next(s for s in sources if s["type"] == "display")
    cfg = macloop.AudioProcessingConfig()

    async with macloop.Capture(
        display_id=display["display_id"],
        config=cfg,
        capture_system=True,
        capture_mic=True,
    ) as stream:
        async for chunk in stream:
            print(chunk.source, len(chunk.samples))

asyncio.run(main())

Data Format

AudioChunk.samples is a numpy.ndarray:

  • np.int16 when sample_format="i16"
  • np.float32 when sample_format="f32"

This makes it convenient to pass chunks directly to model inference pipelines without extra conversion.

# Example: direct handoff to inference-friendly float32
import numpy as np
import macloop

sources = macloop.list_audio_sources()
display = next(s for s in sources if s["type"] == "display")
cfg = macloop.AudioProcessingConfig(sample_format="f32", sample_rate=16000, channels=1)

with macloop.Capture(display_id=display["display_id"], config=cfg) as stream:
    for chunk in stream:
        x = chunk.samples.astype(np.float32, copy=False)
        # model(x)

Sherpa ASR Demo

For speech-to-text (ASR), use this short example:

uv run --with sherpa-onnx --with huggingface_hub --with macloop \
  python examples/sherpa_asr_demo.py --seconds 5

It captures microphone audio with macloop, downloads a Sherpa model from Hugging Face (or uses --model-dir), and prints transcript text.

Notes

  • One capture target per stream: either display_id or pid.
  • For app capture use pid=....

License

MIT

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

macloop-0.1.2.tar.gz (35.6 kB view details)

Uploaded Source

Built Distribution

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

macloop-0.1.2-cp39-abi3-macosx_11_0_x86_64.macosx_11_0_arm64.macosx_11_0_universal2.whl (1.9 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64macOS 11.0+ universal2 (ARM64, x86-64)macOS 11.0+ x86-64

File details

Details for the file macloop-0.1.2.tar.gz.

File metadata

  • Download URL: macloop-0.1.2.tar.gz
  • Upload date:
  • Size: 35.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for macloop-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d209fb3cfb379062d0d2f3e8e474824a938539749938f53be6b0e67986f8ba0a
MD5 3ede925803f6a2780dec4c828c6eacf1
BLAKE2b-256 a65cd2818f52bc83f74b517ec9317bba3cc923284991a388307aa3519ec7130b

See more details on using hashes here.

Provenance

The following attestation bundles were made for macloop-0.1.2.tar.gz:

Publisher: publish.yml on kemsta/macloop

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file macloop-0.1.2-cp39-abi3-macosx_11_0_x86_64.macosx_11_0_arm64.macosx_11_0_universal2.whl.

File metadata

File hashes

Hashes for macloop-0.1.2-cp39-abi3-macosx_11_0_x86_64.macosx_11_0_arm64.macosx_11_0_universal2.whl
Algorithm Hash digest
SHA256 7e6e863d4e8707a1c40298bfc87843654221ea3d08a6113dd53bf49304114f0f
MD5 33a2dffabcfcf133efdf9ddd16457ff2
BLAKE2b-256 2f5a880c8be34896010f4e833bf3a820bdc5548697fd928ace9f5b37cfefa84b

See more details on using hashes here.

Provenance

The following attestation bundles were made for macloop-0.1.2-cp39-abi3-macosx_11_0_x86_64.macosx_11_0_arm64.macosx_11_0_universal2.whl:

Publisher: publish.yml on kemsta/macloop

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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