Move decode config into DecodeMode::Decode (#272)
Some checks failed
CI / Lint (push) Successful in 10m16s
CI / Test (beta, beta) (push) Failing after 6m11s
CI / Test (nightly, nightly) (push) Successful in 10m53s
CI / Test (stable) (push) Failing after 7s
CI / Test (true, driver tungstenite rustls, driver only) (push) Failing after 7s
CI / Test (true, gateway serenity tungstenite rustls, gateway only) (push) Failing after 6s
CI / Build docs (push) Successful in 10m0s
CI / Examples (push) Failing after 6s
Publish docs / Publish docs (push) Successful in 10m8s
CI / Test (true, Windows, windows-latest) (push) Has been cancelled
CI / Test (true, macOS, macOS-latest) (push) Has been cancelled

This commit is contained in:
Gnome!
2025-02-23 13:02:29 +00:00
committed by GnomedDev
parent 8956352f13
commit e8c134664b
8 changed files with 68 additions and 68 deletions

View File

@@ -1,5 +1,5 @@
#[cfg(all(feature = "driver", feature = "receive"))]
use crate::driver::{Channels, DecodeMode, SampleRate};
use crate::driver::DecodeMode;
#[cfg(feature = "driver")]
use crate::{
driver::{
@@ -61,18 +61,6 @@ pub struct Config {
/// [User speaking state]: crate::events::CoreEvent::VoiceTick
pub decode_mode: DecodeMode,
#[cfg(all(feature = "driver", feature = "receive"))]
/// Configures the channel layout for output audio when using [`DecodeMode::Decode`].
///
/// Defaults to [`Channels::Stereo`].
pub decode_channels: Channels,
#[cfg(all(feature = "driver", feature = "receive"))]
/// Configures the sample rate for output audio when using [`DecodeMode::Decode`].
///
/// Defaults to [`SampleRate::Hz48000`].
pub decode_sample_rate: SampleRate,
#[cfg(all(feature = "driver", feature = "receive"))]
/// Configures the amount of time after a user/SSRC is inactive before their decoder state
/// should be removed.
@@ -223,10 +211,6 @@ impl Default for Config {
#[cfg(all(feature = "driver", feature = "receive"))]
decode_mode: DecodeMode::Decrypt,
#[cfg(all(feature = "driver", feature = "receive"))]
decode_channels: Channels::Stereo,
#[cfg(all(feature = "driver", feature = "receive"))]
decode_sample_rate: SampleRate::Hz48000,
#[cfg(all(feature = "driver", feature = "receive"))]
decode_state_timeout: Duration::from_secs(60),
#[cfg(all(feature = "driver", feature = "receive"))]
playout_buffer_length: NonZeroUsize::new(5).unwrap(),
@@ -279,22 +263,6 @@ impl Config {
self
}
#[cfg(feature = "receive")]
/// Sets this `Config`'s channel layout for output audio when using [`DecodeMode::Decode`]
#[must_use]
pub fn decode_channels(mut self, decode_channels: Channels) -> Self {
self.decode_channels = decode_channels;
self
}
#[cfg(feature = "receive")]
/// Sets this `Config`'s sample rate for output audio when using [`DecodeMode::Decode`]
#[must_use]
pub fn decode_sample_rate(mut self, decode_sample_rate: SampleRate) -> Self {
self.decode_sample_rate = decode_sample_rate;
self
}
#[cfg(feature = "receive")]
/// Sets this `Config`'s received packet decoder cleanup timer.
#[must_use]

View File

@@ -16,10 +16,16 @@ pub enum DecodeMode {
/// Decrypts and decodes each received packet, correctly accounting for losses.
///
/// Larger per-packet CPU use.
Decode,
Decode(DecodeConfig),
}
impl DecodeMode {
/// Returns whether this mode will decrypt and decode received packets.
#[must_use]
pub fn should_decode(self) -> bool {
matches!(self, DecodeMode::Decode(..))
}
/// Returns whether this mode will decrypt received packets.
#[must_use]
pub fn should_decrypt(self) -> bool {
@@ -27,6 +33,32 @@ impl DecodeMode {
}
}
/// Configuration for [`DecodeMode::Decode`]
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)]
pub struct DecodeConfig {
/// Configures the channel layout for output audio.
///
/// Defaults to [`Channels::Stereo`].
pub channels: Channels,
/// Configures the sample rate for output audio.
///
/// Defaults to [`SampleRate::Hz48000`].
pub sample_rate: SampleRate,
}
impl DecodeConfig {
/// Creates a new [`DecodeConfig`] with the specified channels and sample rate.
#[must_use]
pub fn new(channels: Channels, sample_rate: SampleRate) -> Self {
Self {
channels,
sample_rate,
}
}
}
/// The channel layout of output audio when using [`DecodeMode::Decode`].
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)]
#[non_exhaustive]

View File

@@ -1,12 +1,12 @@
#![allow(missing_docs)]
use super::Interconnect;
use crate::driver::Config;
use crate::driver::DecodeConfig;
use dashmap::{DashMap, DashSet};
use serenity_voice_model::id::UserId;
pub enum UdpRxMessage {
SetConfig(Config),
SetConfig(DecodeConfig),
ReplaceInterconnect(Interconnect),
}

View File

@@ -329,10 +329,11 @@ impl Mixer {
#[cfg(feature = "receive")]
if let Some(conn) = &self.conn_active {
conn_failure |= conn
.udp_rx
.send(UdpRxMessage::SetConfig(new_config))
.is_err();
if let crate::driver::DecodeMode::Decode(decode_config) = new_config.decode_mode
{
let msg = UdpRxMessage::SetConfig(decode_config);
conn_failure |= conn.udp_rx.send(msg).is_err();
}
}
Ok(())

View File

@@ -5,7 +5,7 @@ mod ssrc_state;
use self::{decode_sizes::*, playout_buffer::*, ssrc_state::*};
use super::message::*;
use crate::driver::CryptoMode;
use crate::driver::{CryptoMode, DecodeMode};
use crate::{
constants::*,
driver::crypto::Cipher,
@@ -65,13 +65,12 @@ impl UdpRx {
Ok(UdpRxMessage::ReplaceInterconnect(i)) => {
*interconnect = i;
},
Ok(UdpRxMessage::SetConfig(c)) => {
let old_coder = (self.config.decode_channels, self.config.decode_sample_rate);
let new_coder = (c.decode_channels, c.decode_sample_rate);
self.config = c;
if old_coder != new_coder {
self.decoder_map.values_mut().for_each(|v| v.reconfigure_decoder(&self.config));
Ok(UdpRxMessage::SetConfig(new_config)) => {
if let DecodeMode::Decode(old_config) = &mut self.config.decode_mode {
if *old_config != new_config {
*old_config = new_config;
self.decoder_map.values_mut().for_each(|v| v.reconfigure_decoder(new_config));
}
}
},
Err(flume::RecvError::Disconnected) => break,

View File

@@ -3,6 +3,7 @@ use crate::{
driver::{
tasks::error::{Error, Result},
Channels,
DecodeConfig,
DecodeMode,
},
events::context_data::{RtpData, VoiceData},
@@ -29,29 +30,28 @@ pub struct SsrcState {
impl SsrcState {
pub fn new(pkt: &RtpPacket<'_>, crypto_mode: CryptoMode, config: &Config) -> Self {
let playout_capacity = config.playout_buffer_length.get() + config.playout_spike_length;
let (sample_rate, channels) = match config.decode_mode {
DecodeMode::Decode(config) => (config.sample_rate, config.channels),
DecodeMode::Decrypt | DecodeMode::Pass => Default::default(),
};
Self {
playout_buffer: PlayoutBuffer::new(playout_capacity, pkt.get_sequence().0),
crypto_mode,
decoder: OpusDecoder::new(
config.decode_sample_rate.into(),
config.decode_channels.into(),
)
.expect("Failed to create new Opus decoder for source."),
decoder: OpusDecoder::new(sample_rate.into(), channels.into())
.expect("Failed to create new Opus decoder for source."),
decode_size: PacketDecodeSize::TwentyMillis,
prune_time: Instant::now() + config.decode_state_timeout,
disconnected: false,
channels: config.decode_channels,
channels,
}
}
pub fn reconfigure_decoder(&mut self, config: &Config) {
self.decoder = OpusDecoder::new(
config.decode_sample_rate.into(),
config.decode_channels.into(),
)
.expect("Failed to create new Opus decoder for source.");
self.channels = config.decode_channels;
pub fn reconfigure_decoder(&mut self, config: DecodeConfig) {
self.decoder = OpusDecoder::new(config.sample_rate.into(), config.channels.into())
.expect("Failed to create new Opus decoder for source.");
self.channels = config.channels;
}
pub fn store_packet(&mut self, packet: StoredPacket, config: &Config) {
@@ -80,8 +80,7 @@ impl SsrcState {
decoded_voice: None,
};
let should_decode = config.decode_mode == DecodeMode::Decode;
let should_decode = config.decode_mode.should_decode();
if let Some((packet, decrypted)) = pkt {
let rtp = RtpPacket::new(&packet).unwrap();
let extensions = rtp.get_extension() != 0;

View File

@@ -32,12 +32,12 @@ pub struct VoiceData {
///
/// Valid audio data (`Some(audio)` where `audio.len >= 0`) typically contains 20ms of 16-bit PCM audio
/// using native endianness. This defaults to stereo audio at 48kHz, and can be configured via
/// [`Config::decode_channels`] and [`Config::decode_sample_rate`] -- channels are interleaved
/// [`DecodeConfig::sample_rate`] and [`DecodeConfig::sample_rate`] -- channels are interleaved
/// (i.e., `L, R, L, R, ...`) if stereo.
///
/// This value will be `None` if Songbird is not configured to decode audio.
///
/// [`Config::decode_channels`]: crate::Config::decode_channels
/// [`Config::decode_sample_rate`]: crate::Config::decode_sample_rate
/// [`DecodeConfig::decode_channels`]: crate::driver::DecodeConfig::channels
/// [`DecodeConfig::sample_rate`]: crate::driver::DecodeConfig::sample_rate
pub decoded_voice: Option<Vec<i16>>,
}