Skip to main content

ruopus

PyPI Docs License: MIT

A fast Opus audio codec for Python, powered by Rust

ruopus encodes and decodes Opus audio (RFC 6716) with first-class NumPy interop. The codec itself is a from-scratch Rust implementation with no C and no FFI, but day to day you just call Python methods that take and return NumPy arrays - the Rust is an implementation detail.

Features

  • Encode and decode: automatic mode selection (SILK / hybrid / CELT) with full control over bitrate, complexity, DTX, in-band FEC, bandwidth, and application profile
  • NumPy native: PCM crosses the boundary as (frames, channels) float32 (or int16) arrays, moved out of Rust with no extra copy
  • No GIL stalls: every encode/decode call releases the GIL
  • Ogg Opus files: single-call encode_ogg_opus / decode_ogg_opus for complete .opus files
  • Packet loss handling: concealment (decode_lost) and in-band FEC recovery (decode_fec)
  • Packet introspection: parse the TOC byte and frame structure of raw Opus packets without decoding audio
  • Surround: multistream decoding for 5.1/7.1 and other RFC 7845 layouts
  • Low-level access: the ruopus.lowlevel submodule exposes the SILK and CELT codecs and the LPC analysis pipeline directly, for research and custom codec work
  • Fully typed: ships with .pyi stubs and a py.typed marker

Installation

pip install ruopus

Requires Python 3.9+ and NumPy 1.22+. Pre-built wheels are available for Linux, macOS, and Windows (CPython 3.9-3.13) - no Rust toolchain needed.

Quick Start

import numpy as np
import ruopus

# Stereo encoder at 64 kbps, matching decoder
enc = ruopus.OpusEncoder(2, bitrate=64_000)
dec = ruopus.OpusDecoder(2)

# 20 ms stereo frame at 48 kHz -> 960 samples per channel
frame = np.zeros((960, 2), dtype=np.float32)

packet = enc.encode_auto(frame)        # bytes - encoded Opus packet
pcm    = dec.decode_packet(packet)     # (960, 2) float32 in [-1, 1]

Encoder input can be a 1-D interleaved array or a 2-D (frames, channels) array; both are accepted without extra copies.

Ogg Opus Files

Write and read complete .opus files in one call each:

import numpy as np
import ruopus

sr = 48_000
t = np.linspace(0, 3, sr * 3, dtype=np.float32)
pcm = np.column_stack([
    np.sin(2 * np.pi * 440 * t),   # left:  A4
    np.sin(2 * np.pi * 880 * t),   # right: A5
])

ogg = ruopus.encode_ogg_opus(pcm, channels=2, bitrate=128_000)
with open("output.opus", "wb") as f:
    f.write(ogg)

with open("output.opus", "rb") as f:
    decoded_pcm, head = ruopus.decode_ogg_opus(f.read())

print(f"{head.channel_count}-ch, {decoded_pcm.shape[0] / sr:.2f}s")

Packet Loss and FEC

import ruopus

dec = ruopus.OpusDecoder(2)
FRAME = 960  # 20 ms at 48 kHz

for pkt in stream:
    if pkt is None:
        pcm = dec.decode_lost(frame_size=FRAME)        # concealment
    else:
        pcm = dec.decode_packet(pkt)

# Recover a lost packet from in-band FEC carried by its successor
recovered = dec.decode_fec(next_pkt, frame_size=FRAME)

Choosing a Bitrate and Application

# Phone-quality voice
enc_voice = ruopus.OpusEncoder(
    1,
    bitrate=8_000,
    application=ruopus.Application.Voip,
    signal=ruopus.Signal.Voice,
)

# High-quality music
enc_music = ruopus.OpusEncoder(
    2,
    bitrate=128_000,
    application=ruopus.Application.Audio,
    signal=ruopus.Signal.Music,
)

# Low-latency game voice (CELT only)
enc_ld = ruopus.OpusEncoder(
    1,
    bitrate=32_000,
    application=ruopus.Application.RestrictedLowDelay,
)

Surround Decoding

import ruopus

# 5.1 surround: 4 elementary streams, 2 stereo-coupled
dec = ruopus.MultistreamDecoder(
    streams=4,
    coupled=2,
    mapping=[0, 4, 1, 2, 3, 5],   # L R C LFE Ls Rs
)
pcm = dec.decode_packet(raw_packet)   # (frames, 6) float32

Packet Inspection

import ruopus

pkt = ruopus.Packet(raw_bytes)
print(f"mode={pkt.toc.mode}, bandwidth={pkt.toc.bandwidth}, frames={len(pkt)}")

Low-Level API

For research or custom codec work, ruopus.lowlevel exposes the SILK and CELT layers and the LPC analysis pipeline directly, below the Opus packet format:

import numpy as np
import ruopus.lowlevel as ll

enc = ll.CeltEncoder(channels=1, complexity=10, bitrate=64_000)
frame = np.zeros(960, dtype=np.float32)
body = enc.encode(frame)   # raw CELT frame body, no Opus framing

Performance

Measured against libopus 1.6.1 (SIMD-enabled C), one core, pinned to a single performance core. Figures are x realtime.

Mode ruopus libopus
Decode, SILK wideband 16 kb/s 2095x 1171x
Decode, CELT fullband 64 kb/s 1389x 1566x
Encode, matched complexity (all modes) parity with libopus

See the full benchmark breakdown for the complete table and methodology.

Documentation

The full guide and API reference are at jmg049.github.io/ruopus, covering codec modes, frame sizes, FEC/loss handling, multistream layouts, and the low-level API in depth.

License

MIT License.

Links

Metadata

Release files for ruopus 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ruopus 0.1.2
File Size Uploaded Provenance
ruopus-0.1.2.tar.gz 337.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ruopus 0.1.2
File Interpreter ABI Platform
ruopus-0.1.2-cp313-cp313-manylinux_2_34_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.34+ x86-64 Details

Total release size: 1.3 MB

Release files / ruopus-0.1.2.tar.gz

Download URL ruopus-0.1.2.tar.gz
Size 337.8 kB
Tags Source
SHA-256 checksum
How to use checksums
40cb87bd6be2842fb3feb6683f0c9edaf9bddc97cb818601cb6a90e08f9ada3c
BLAKE2b-256 checksum
How to use checksums
2ca8476587d0d527f0e7dfd33fc6ec4a2534e71f2976b436bea107de89258228
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / ruopus-0.1.2-cp313-cp313-manylinux_2_34_x86_64.whl

Download URL ruopus-0.1.2-cp313-cp313-manylinux_2_34_x86_64.whl
Size 1.0 MB
Tags CPython 3.13 Linux glibc 2.34+ x86-64
SHA-256 checksum
How to use checksums
9610e4b9de3452dda0753b0d3c36cc7036fe9a5e3f8822e29829578da1ba7a17
BLAKE2b-256 checksum
How to use checksums
b8e42c37221482ad1064766e6b8a8964e1cf612bffcc4a230c0abcd71a434a9b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Security for ruopus 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page