Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
335 changes: 317 additions & 18 deletions Cargo.lock

Large diffs are not rendered by default.

20 changes: 17 additions & 3 deletions crates/chatd/src/media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ struct Live {
/// The room requires push-to-talk (a Tiny room's `ptt_only`, or no voice activation
/// there), whatever the user chose.
push_to_talk: bool,
/// A Tiny room's bitrate ceiling in kb/s, when known. Quality presets are applied against it.
room_bitrate: Option<u32>,
/// How mediad last said the call is protected, before whom the user verified is applied.
secured: Option<protocol::CallSecurity>,
}
Expand Down Expand Up @@ -229,6 +231,7 @@ fn new_call(conversation: Key, state: CallState) -> Live {
metering: false,
me: String::new(),
push_to_talk: false,
room_bitrate: None,
secured: None,
}
}
Expand Down Expand Up @@ -743,10 +746,10 @@ impl Calls {
drop(tester);
hub.changed(Change::Meter { level: None });
}
let (tuning, input, output, muted, mode, processing) = {
let (tuning, input, output, muted, mode, processing, quality) = {
let settings = hub.settings();
let mode = input_mode(&settings, false);
(settings.tuning(), settings.device(INPUT), settings.device(OUTPUT), settings.on(JOIN_MUTED), mode, settings.processing())
(settings.tuning(), settings.device(INPUT), settings.device(OUTPUT), settings.on(JOIN_MUTED), mode, settings.processing(), settings.voice_quality())
};
{
let mut slot = crate::hub::lock(&self.slot);
Expand All @@ -763,6 +766,7 @@ impl Calls {
let _ = active.request(&MediaRequest::Tune(tuning));
let _ = active.request(&MediaRequest::Input(mode));
let _ = active.request(&MediaRequest::Processing(processing));
let _ = active.request(&MediaRequest::Quality(quality));
// V9: everyone on this account whose volume for me is not the default.
let gains = hub.settings().gains(&conversation.account());
for (user_id, percent, muted) in gains {
Expand Down Expand Up @@ -793,6 +797,13 @@ impl Calls {
let _ = active.request(&MediaRequest::Tune(tuning));
let _ = active.request(&MediaRequest::Input(input_mode(&settings, push_to_talk)));
let _ = active.request(&MediaRequest::Processing(settings.processing()));
let quality = settings.voice_quality();
let _ = active.request(&MediaRequest::Quality(quality));
// Re-apply the room bitrate under the new quality cap when we know the room's.
let room_bitrate = crate::hub::lock(&active.live).room_bitrate;
if let Some(kbps) = room_bitrate {
let _ = active.request(&MediaRequest::Bitrate { kbps: quality.apply_room(kbps) });
}
}
if let Some(tester) = crate::hub::lock(&self.tester).as_mut() {
let _ = tester.send(&MediaRequest::Tune(tuning));
Expand Down Expand Up @@ -1254,10 +1265,13 @@ impl Calls {
if !self.update(hub, conversation, |live| {
changed = live.push_to_talk != push_to_talk;
live.push_to_talk = push_to_talk;
live.room_bitrate = Some(kbps);
}) {
return;
}
let _ = self.request(hub, &MediaRequest::Bitrate { kbps });
let quality = hub.settings().voice_quality();
let _ = self.request(hub, &MediaRequest::Bitrate { kbps: quality.apply_room(kbps) });
let _ = self.request(hub, &MediaRequest::Quality(quality));
if changed {
let mode = input_mode(&hub.settings(), push_to_talk);
let _ = self.request(hub, &MediaRequest::Input(mode));
Expand Down
4 changes: 3 additions & 1 deletion crates/chatd/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,9 @@ impl Chat {
| settings::PTT_RELEASE_MS
| settings::ECHO_CANCELLATION
| settings::NOISE_SUPPRESSION
| settings::AUTO_GAIN => self.hub.calls.retune(&self.hub),
| settings::AUTO_GAIN
| settings::INPUT_VOLUME
| settings::VOICE_QUALITY => self.hub.calls.retune(&self.hub),
settings::INPUT | settings::OUTPUT => self.hub.calls.redevice(&self.hub),
_ => {}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/mediad/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ symphonia = { version = "0.5", default-features = false, features = ["ogg", "mkv
# (`webrtc-audio-processing`) needs meson and ninja to build, and none of the other pure-Rust
# echo cancellers is WebRTC's. Pinned: a port moves fast, and a new version must be heard first.
sonora = "=0.2.0"
# Neural noise suppression (RNNoise), pure Rust. Used for the Enhanced noise mode.
nnnoiseless = "0.5.2"
# The watched picture is a JPEG on disk. The jpeg encoder is pure Rust.
image = { version = "0.25.10", default-features = false, features = ["jpeg"] }

Expand Down
2 changes: 1 addition & 1 deletion crates/mediad/src/harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ pub fn realtime(mic: (u32, usize), speaker: (u32, usize), seconds: f64) -> (crat

crate::rt::tick_thread();
let mut processor = Processor::new();
processor.set(Some(AudioProcessing { echo_cancellation: true, noise_suppression: true, auto_gain: true }));
processor.set(Some(AudioProcessing { echo_cancellation: true, auto_gain: true, noise: protocol::NoiseMode::Standard }));
let (mut encoder, mut decoder) = (Encoder::voice().unwrap(), Decoder::new().unwrap());
let mut limiter = Limiter::default();
let mut warm = None;
Expand Down
2 changes: 2 additions & 0 deletions crates/mediad/src/media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ pub(crate) fn listen(controls: &Controls, audio: &mut Audio, processor: &mut Pro
let captured = audio.capture(frame);
processor.set(controls.processing());
if captured {
// Mic volume before DSP so AGC/NS see the level the user chose, and the meter matches.
crate::process::apply_input_gain(frame, controls.tuning().input);
processor.capture(frame);
}
let heard = if captured { level(frame) } else { 0 };
Expand Down
8 changes: 7 additions & 1 deletion crates/mediad/src/opus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,13 @@ impl Encoder {
/// frames inside a talk spurt (the pauses between words) reach the far end as losses it has
/// to make up.
pub fn voice() -> Option<Encoder> {
Encoder::made(1, OPUS_APPLICATION_VOIP, VOICE_BITRATE, false)
Encoder::voice_quality(protocol::VoiceQuality::Standard)
}

/// Like [`Encoder::voice`], but High quality uses Opus's Audio application for clearer speech.
pub fn voice_quality(quality: protocol::VoiceQuality) -> Option<Encoder> {
let application = if quality.prefer_audio_application() { OPUS_APPLICATION_AUDIO } else { OPUS_APPLICATION_VOIP };
Encoder::made(1, application, VOICE_BITRATE, false)
}

fn made(channels: usize, application: i32, bitrate: i32, dtx: bool) -> Option<Encoder> {
Expand Down
1 change: 1 addition & 0 deletions crates/mediad/src/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ pub fn run() {
};
let mut frame = [0i16; FRAME_SAMPLES];
if audio.capture(&mut frame) {
crate::process::apply_input_gain(&mut frame, controls.tuning().input);
processor.capture(&mut frame);
loudest = loudest.max(level(&frame));
if loopback {
Expand Down
Loading
Loading