Skip to content

Commit

Permalink
simplify output stream in OpusSink
Browse files Browse the repository at this point in the history
  • Loading branch information
sdwoodbury committed Sep 15, 2023
1 parent 5845cba commit 6bb8968
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 91 deletions.
53 changes: 0 additions & 53 deletions extensions/warp-blink-wrtc/src/host_media/audio/opus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,56 +44,3 @@ impl Resampler {
}
}
}

pub enum ChannelMixerConfig {
None,
// average N channels into 1 channel
Average { to_sum: usize },
// split 1 channel into N equal channels
Split { to_split: usize },
}

pub enum ChannelMixerOutput {
None,
Single(f32),
Split { val: f32, repeated: usize },
}

pub struct ChannelMixer {
// sum and num_summed are used to take the average of multiple channels. ChannelMixerConfig tells how many samples must be averaged
sum: f32,
num_summed: usize,
config: ChannelMixerConfig,
}

impl ChannelMixer {
pub fn new(config: ChannelMixerConfig) -> Self {
Self {
config,
sum: 0.0,
num_summed: 0,
}
}
pub fn process(&mut self, sample: f32) -> ChannelMixerOutput {
match self.config {
ChannelMixerConfig::None => ChannelMixerOutput::Single(sample),
ChannelMixerConfig::Average { to_sum: num } => {
self.sum += sample;
self.num_summed += 1;
// using >= to prevent the ChannelMixer from being stuck. otherwise == would do.
if self.num_summed >= num {
let avg = self.sum / self.num_summed as f32;
self.sum = 0.0;
self.num_summed = 0;
ChannelMixerOutput::Single(avg)
} else {
ChannelMixerOutput::None
}
}
ChannelMixerConfig::Split { to_split } => ChannelMixerOutput::Split {
val: sample,
repeated: to_split,
},
}
}
}
45 changes: 7 additions & 38 deletions extensions/warp-blink-wrtc/src/host_media/audio/opus/sink/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
},
};

use super::{ChannelMixer, ChannelMixerConfig, ChannelMixerOutput, Resampler, ResamplerConfig};
use super::{Resampler, ResamplerConfig};

pub struct OpusSink {
peer_id: DID,
Expand Down Expand Up @@ -66,18 +66,6 @@ impl OpusSink {
};
let resampler = Resampler::new(resampler_config);

// webtrtc codec is guaranteed to have 1 channel
let channel_mixer_config = match 1.cmp(&sink_config.channels()) {
Ordering::Equal => ChannelMixerConfig::None,
Ordering::Greater => {
unreachable!("invalid channels for OpusSink. sink config has less than 1 channel")
}
Ordering::Less => ChannelMixerConfig::Split {
to_split: sink_config.channels() as _,
},
};
let channel_mixer = ChannelMixer::new(channel_mixer_config);

let cpal_config = cpal::StreamConfig {
channels: sink_config.channels(),
sample_rate: SampleRate(sink_config.sample_rate()),
Expand Down Expand Up @@ -109,7 +97,6 @@ impl OpusSink {
producer,
decoder,
resampler,
channel_mixer,
event_ch: event_ch2,
peer_id: peer_id2,
mp4_writer: mp4_logger2,
Expand All @@ -124,26 +111,20 @@ impl OpusSink {
});

let output_data_fn = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
let mut input_fell_behind = false;
// this is test code, left here for reference. it can be deleted later if needed.
// if *dump_consumer_queue.read() {
// *dump_consumer_queue.write() = false;
// unsafe {
// consumer.advance(consumer.len());
// }
// }
for sample in data {
*sample = match consumer.pop() {
Some(s) => s,
None => {
input_fell_behind = true;
0_f32
}

for frame in data.chunks_mut(cpal_config.channels as _) {
let value = consumer.pop().unwrap_or_default();
for sample in frame.iter_mut() {
*sample = value;
}
}
if input_fell_behind {
//log::trace!("output stream fell behind: try increasing latency");
}
};
let output_stream = output_device.build_output_stream(
&cpal_config,
Expand Down Expand Up @@ -247,7 +228,6 @@ struct DecodeMediaStreamArgs<T: Depacketizer> {
producer: AudioSampleProducer,
decoder: opus::Decoder,
resampler: Resampler,
channel_mixer: ChannelMixer,
event_ch: broadcast::Sender<BlinkEventKind>,
peer_id: DID,
mp4_writer: Arc<RwLock<Option<Box<dyn Mp4LoggerInstance>>>>,
Expand All @@ -265,7 +245,6 @@ where
mut producer,
mut decoder,
mut resampler,
mut channel_mixer,
event_ch,
peer_id,
mp4_writer,
Expand Down Expand Up @@ -353,17 +332,7 @@ where
let _ = automute_tx
.send(host_media::audio::automute::AutoMuteCmd::MuteFor(110));
'PROCESS_DECODED_SAMPLES: for audio_sample in to_send {
match channel_mixer.process(*audio_sample * multiplier) {
ChannelMixerOutput::Single(sample) => {
resampler.process(sample, &mut raw_samples);
}
ChannelMixerOutput::Split { val, repeated } => {
for _ in 0..repeated {
resampler.process(val, &mut raw_samples);
}
}
ChannelMixerOutput::None => {}
}
resampler.process(*audio_sample * multiplier, &mut raw_samples);
for sample in raw_samples.drain(..) {
if let Err(_e) = producer.push(sample) {
// this is test code, left here for reference. it can be deleted later if needed.
Expand Down

0 comments on commit 6bb8968

Please sign in to comment.