use crate::bindings::{
OPUS_APPLICATION_AUDIO, OPUS_APPLICATION_RESTRICTED_LOWDELAY, OPUS_APPLICATION_VOIP, OPUS_AUTO,
OPUS_BANDWIDTH_FULLBAND, OPUS_BANDWIDTH_MEDIUMBAND, OPUS_BANDWIDTH_NARROWBAND,
OPUS_BANDWIDTH_SUPERWIDEBAND, OPUS_BANDWIDTH_WIDEBAND, OPUS_BITRATE_MAX, OPUS_FRAMESIZE_2_5_MS,
OPUS_FRAMESIZE_5_MS, OPUS_FRAMESIZE_10_MS, OPUS_FRAMESIZE_20_MS, OPUS_FRAMESIZE_40_MS,
OPUS_FRAMESIZE_60_MS, OPUS_FRAMESIZE_80_MS, OPUS_FRAMESIZE_100_MS, OPUS_FRAMESIZE_120_MS,
OPUS_FRAMESIZE_ARG, OPUS_SIGNAL_MUSIC, OPUS_SIGNAL_VOICE,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Application {
#[default]
Voip = OPUS_APPLICATION_VOIP as isize,
Audio = OPUS_APPLICATION_AUDIO as isize,
RestrictedLowDelay = OPUS_APPLICATION_RESTRICTED_LOWDELAY as isize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Channels {
Mono = 1,
Stereo = 2,
}
impl Channels {
#[must_use]
pub const fn as_usize(self) -> usize {
self as usize
}
#[must_use]
pub const fn as_i32(self) -> i32 {
self as i32
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum SampleRate {
Hz8000 = 8000,
Hz12000 = 12000,
Hz16000 = 16000,
Hz24000 = 24000,
#[default]
Hz48000 = 48000,
}
impl SampleRate {
#[must_use]
pub const fn as_i32(self) -> i32 {
self as i32
}
#[must_use]
pub const fn is_valid(self) -> bool {
matches!(
self,
Self::Hz8000 | Self::Hz12000 | Self::Hz16000 | Self::Hz24000 | Self::Hz48000
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Bandwidth {
Narrowband = OPUS_BANDWIDTH_NARROWBAND as isize,
Mediumband = OPUS_BANDWIDTH_MEDIUMBAND as isize,
Wideband = OPUS_BANDWIDTH_WIDEBAND as isize,
SuperWideband = OPUS_BANDWIDTH_SUPERWIDEBAND as isize,
Fullband = OPUS_BANDWIDTH_FULLBAND as isize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FrameSize {
Ms2_5 = 25,
Ms5 = 50,
Ms10 = 100,
Ms20 = 200,
Ms40 = 400,
Ms60 = 600,
}
impl FrameSize {
#[must_use]
pub const fn samples(self, sample_rate: SampleRate) -> usize {
(self as usize * (sample_rate as usize)) / 10_000
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Signal {
Auto = OPUS_AUTO as isize,
Voice = OPUS_SIGNAL_VOICE as isize,
Music = OPUS_SIGNAL_MUSIC as isize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExpertFrameDuration {
Auto = OPUS_FRAMESIZE_ARG as isize,
Ms2_5 = OPUS_FRAMESIZE_2_5_MS as isize,
Ms5 = OPUS_FRAMESIZE_5_MS as isize,
Ms10 = OPUS_FRAMESIZE_10_MS as isize,
Ms20 = OPUS_FRAMESIZE_20_MS as isize,
Ms40 = OPUS_FRAMESIZE_40_MS as isize,
Ms60 = OPUS_FRAMESIZE_60_MS as isize,
Ms80 = OPUS_FRAMESIZE_80_MS as isize,
Ms100 = OPUS_FRAMESIZE_100_MS as isize,
Ms120 = OPUS_FRAMESIZE_120_MS as isize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Complexity(u32);
impl Complexity {
#[must_use]
pub const fn new(complexity: u32) -> Self {
assert!(complexity <= 10, "Complexity must be between 0 and 10");
Self(complexity)
}
#[must_use]
pub const fn value(self) -> u32 {
self.0
}
}
impl Default for Complexity {
fn default() -> Self {
Self::new(10)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Bitrate {
Auto,
Max,
Custom(i32),
}
impl Bitrate {
#[must_use]
pub const fn value(self) -> i32 {
match self {
Self::Auto => OPUS_AUTO,
Self::Max => OPUS_BITRATE_MAX,
Self::Custom(bps) => bps,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn frame_size_samples_are_correct() {
assert_eq!(FrameSize::Ms20.samples(SampleRate::Hz48000), 960);
assert_eq!(FrameSize::Ms5.samples(SampleRate::Hz16000), 80);
assert_eq!(FrameSize::Ms2_5.samples(SampleRate::Hz8000), 20);
}
}