I’m seeing audible crackling when feeding a low-sample-rate MediaStreamTrack into AudioContext::create_media_stream_source.
Minimal repro file:
use std::error::Error;
use std::f32::consts::PI;
use std::thread;
use std::time::Duration;
use web_audio_api::context::{AudioContext, AudioContextOptions};
use web_audio_api::media_streams::{MediaStream, MediaStreamTrack};
use web_audio_api::node::AudioNode;
use web_audio_api::{AudioBuffer, AudioRenderCapacityOptions};
const SAMPLE_RATE: f32 = 8_000.0;
const FREQUENCY: f32 = 220.0;
const CHUNK_SIZE: usize = 128;
const DURATION_SECS: f32 = 5.0;
type FallibleBuffer = Result<AudioBuffer, Box<dyn Error + Send + Sync>>;
struct SineChunks {
phase: f32,
phase_step: f32,
chunks_left: usize,
}
impl SineChunks {
fn new(sample_rate: f32, frequency: f32, chunk_size: usize, duration_secs: f32) -> Self {
let chunks_left = (duration_secs * sample_rate / chunk_size as f32).ceil() as usize;
Self {
phase: 0.0,
phase_step: 2.0 * PI * frequency / sample_rate,
chunks_left,
}
}
}
impl Iterator for SineChunks {
type Item = FallibleBuffer;
fn next(&mut self) -> Option<Self::Item> {
if self.chunks_left == 0 {
return None;
}
self.chunks_left -= 1;
let mut channel = Vec::with_capacity(CHUNK_SIZE);
for _ in 0..CHUNK_SIZE {
channel.push(self.phase.sin() * 0.15);
self.phase += self.phase_step;
}
Some(Ok(AudioBuffer::from(vec![channel], SAMPLE_RATE)))
}
}
fn main() {
let context = AudioContext::new(AudioContextOptions::default());
let render_capacity = context.render_capacity();
render_capacity.set_onupdate(|event| {
eprintln!(
"renderCapacity: t={:.2}s avg={:.2} peak={:.2} underrun={:.2}",
event.timestamp, event.average_load, event.peak_load, event.underrun_ratio
);
});
render_capacity.start(AudioRenderCapacityOptions {
update_interval: 1.0,
});
let track = MediaStreamTrack::from_iter(SineChunks::new(
SAMPLE_RATE,
FREQUENCY,
CHUNK_SIZE,
DURATION_SECS,
));
let stream = MediaStream::from_tracks(vec![track]);
let source = context.create_media_stream_source(&stream);
source.connect(&context.destination());
context.resume_sync();
thread::sleep(Duration::from_secs_f32(DURATION_SECS));
render_capacity.stop();
context.close_sync();
}
Observation: with SAMPLE_RATE = 8_000.0, the output crackles noticeably. AudioRenderCapacity stays low while this happens, so it does not look like a render-capacity underrun.
I’m seeing audible crackling when feeding a low-sample-rate
MediaStreamTrackintoAudioContext::create_media_stream_source.Minimal repro file:
Observation: with
SAMPLE_RATE = 8_000.0, the output crackles noticeably.AudioRenderCapacitystays low while this happens, so it does not look like a render-capacity underrun.