StreamingAudioManager

Runtime PCM audio streaming — feed raw float32 PCM chunks and play them in real time. New in v2.56.0.

StreamingAudioManager provides runtime PCM audio streaming. Feed raw float32 PCM chunks from any source (TTS, synthesizer, game-engine audio) and play them in real time.

Import

import { StreamingAudioManager } from "@reactvision/react-viro";

API

// Create a named player
StreamingAudioManager.create(playerId: string): void;

// Begin streaming — must be called before pushSamples
StreamingAudioManager.beginStreaming(
  playerId: string,
  sampleRate: number,   // e.g. 22050, 44100, 48000
  channels: number      // 1 = mono, 2 = stereo
): void;

// Playback control
StreamingAudioManager.play(playerId: string): void;
StreamingAudioManager.pause(playerId: string): void;
StreamingAudioManager.setVolume(playerId: string, volume: number): void;  // 0.0–1.0
StreamingAudioManager.setMuted(playerId: string, muted: boolean): void;

// Push audio data — base64-encoded float32 PCM, interleaved, little-endian
StreamingAudioManager.pushSamples(playerId: string, base64Samples: string): void;

// Release resources
StreamingAudioManager.destroy(playerId: string): void;

Correct call order

// 1. Create
StreamingAudioManager.create("voice");

// 2. Configure stream format
StreamingAudioManager.beginStreaming("voice", 22050, 1);

// 3. Pre-fill buffer BEFORE play
StreamingAudioManager.pushSamples("voice", firstChunkBase64);

// 4. Start playback
StreamingAudioManager.play("voice");

// 5. Continue pushing on each chunk
StreamingAudioManager.pushSamples("voice", nextChunkBase64);

// 6. Clean up
StreamingAudioManager.destroy("voice");

🚧

Push before play

Call pushSamples with at least one chunk before play. If the ring buffer is empty when the audio thread starts consuming, you'll hear a glitch or silence (underrun).

Encoding samples

function float32ToBase64(samples: Float32Array): string {
  const bytes = new Uint8Array(samples.buffer);
  let binary = "";
  bytes.forEach((b) => (binary += String.fromCharCode(b)));
  return btoa(binary);
}

Architecture note

  • iOS: AVAudioEngine + AVAudioSourceNode render block drains a lock-free SPSC ring buffer (VROPCMRingBuffer, default 16,384 samples ≈ 185 ms at 44.1 kHz stereo).
  • Android: AudioTrack with WRITE_NON_BLOCKING. Excess samples are silently discarded when the hardware buffer is full.
  • The API is non-spatial. For spatialised streaming audio, use VROSoundGVR directly from C++.

Platform Support

PlatformSupported
iOS
Android