Metadata-Version: 2.4
Name: arctan-vi
Version: 0.8.1
Requires-Dist: numpy>=2,<3
Requires-Dist: arctan-vi-livekit==0.8.1 ; extra == 'livekit'
Requires-Dist: arctan-vi-pipecat==0.8.1 ; python_full_version >= '3.11' and extra == 'pipecat'
Provides-Extra: livekit
Provides-Extra: pipecat
Summary: Arctan Voice Isolation for voice agents
Requires-Python: >=3.10, <3.15
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# Arctan Voice Isolation

Arctan Voice Isolation is a Python SDK for real-time voice isolation in voice
agents and audio pipelines.

It supports standard NumPy audio processing and integrations for LiveKit and
Pipecat.

## Installation

Install the base SDK:

```bash
pip install arctan-vi
```

Install a framework integration:

```bash
pip install "arctan-vi[livekit]"
pip install "arctan-vi[pipecat]"
```

Arctan Voice Isolation 0.8.1 supports CPython 3.10-3.14 on Linux x86-64
(`glibc` 2.28 or newer) and Windows x86-64. The Pipecat integration requires
Python 3.11 or newer.

## SDK key

Set your Arctan SDK key in the runtime environment:

```bash
export ARCTAN_SDK_KEY="arc_sk_live_..."
```

You can instead pass `license_key="arc_sk_live_..."` to a model, processor, or
framework integration. An explicit `license_key` takes precedence over
`ARCTAN_SDK_KEY`.

## Standard Python

### Process one stream

```python
import numpy as np
import arctan

config = arctan.ProcessorConfig(sample_rate=24_000, num_channels=1)
processor = arctan.Processor(config=config)

try:
    audio = np.zeros((config.num_channels, config.num_frames), dtype=np.float32)
    enhanced = processor.process(audio)
finally:
    processor.close()
```

`Processor.process()` accepts finite `float32` samples in `[-1.0, 1.0]`, shaped
as `channels x frames`. It returns a new `float32` array with the same shape.
Mono and stereo input are supported. Stereo is returned as dual-mono stereo.

The sample rate must remain stable for the lifetime of a processor. If
`num_frames` is omitted, the SDK selects the native frame size. An explicit
`num_frames` must contain a whole number of native processing blocks.

### Process concurrent streams

For concurrent streams in one worker, share one `Model` and create one
`ProcessorAsync` for each independent stream:

```python
import asyncio
import numpy as np
import arctan


async def main() -> None:
    model = arctan.Model()
    configs = []
    processors = []

    try:
        for _ in range(2):
            config = arctan.ProcessorConfig.optimal(model)
            configs.append(config)
            processors.append(arctan.ProcessorAsync(model=model, config=config))

        frames = [
            np.zeros((config.num_channels, config.num_frames), dtype=np.float32)
            for config in configs
        ]
        enhanced = await asyncio.gather(
            *(
                processor.process_async(frame)
                for processor, frame in zip(processors, frames)
            )
        )
        print(len(enhanced))
    finally:
        for processor in processors:
            processor.close()
        model.close()


asyncio.run(main())
```

Use exactly one processor per call or audio stream. Keep frames ordered within
each processor. Different processors may execute concurrently, but calls on a
single `ProcessorAsync` are serialized. Close every processor before closing
its shared model.

## LiveKit

Install the LiveKit integration:

```bash
pip install "arctan-vi[livekit]"
```

Pass an Arctan noise canceller to LiveKit audio input options:

```python
from arctan.livekit import arctan_enhancer
from livekit.agents import room_io

await session.start(
    agent=Assistant(),
    room=ctx.room,
    room_options=room_io.RoomOptions(
        audio_input=room_io.AudioInputOptions(
            noise_cancellation=arctan_enhancer.noise_canceller(),
        ),
    ),
)
```

Pass `license_key=` to `noise_canceller()` when the key is not provided through
`ARCTAN_SDK_KEY`. Create a separate noise-canceller instance for every
participant, call, or independent audio input.

## Pipecat

Install the Pipecat integration:

```bash
pip install "arctan-vi[pipecat]"
```

Pass an Arctan audio filter to the transport:

```python
from arctan.pipecat import arctan_enhancer
from pipecat.transports.base_transport import TransportParams

audio_filter = arctan_enhancer.ArctanAudioFilter()

transport_params = TransportParams(
    audio_in_enabled=True,
    audio_in_filter=audio_filter,
)
```

The Pipecat integration accepts mono PCM16 input and buffers arbitrary byte
chunks until a complete processing block is available. Create a separate
`ArctanAudioFilter` for every call or pipeline.

