use super::AudioDecoder;
use crate::Result;
#[cfg(not(target_arch = "wasm32"))]
use opus::{Channels, Decoder as OpusInner};
#[cfg(not(target_arch = "wasm32"))]
#[derive(Debug)]
pub struct NativeOpusDecoder {
inner: OpusInner,
sample_rate: u32,
channels: u8,
}
#[cfg(not(target_arch = "wasm32"))]
impl NativeOpusDecoder {
pub fn new(sample_rate: u32, channels: u8) -> Result<Self> {
let ch_enum = match channels {
1 => Channels::Mono,
2 => Channels::Stereo,
_ => return Err(crate::NetEqError::InvalidChannelCount(channels)),
};
let inner = OpusInner::new(sample_rate, ch_enum)
.map_err(|e| crate::NetEqError::DecoderError(format!("Opus init: {e}")))?;
Ok(Self {
inner,
sample_rate,
channels,
})
}
#[allow(dead_code)]
pub async fn new_async(sample_rate: u32, channels: u8) -> Result<Self> {
Self::new(sample_rate, channels)
}
}
#[cfg(not(target_arch = "wasm32"))]
impl AudioDecoder for NativeOpusDecoder {
fn sample_rate(&self) -> u32 {
self.sample_rate
}
fn channels(&self) -> u8 {
self.channels
}
fn decode(&mut self, encoded: &[u8]) -> Result<Vec<f32>> {
let max_samples = (self.sample_rate as usize * 120 / 1000) * self.channels as usize;
let mut buf = vec![0.0f32; max_samples];
let decoded_samples = self
.inner
.decode_float(encoded, &mut buf, false)
.map_err(|e| crate::NetEqError::DecoderError(format!("Opus decode: {e}")))?;
buf.truncate(decoded_samples * self.channels as usize);
Ok(buf)
}
}
#[cfg(target_arch = "wasm32")]
#[allow(dead_code)]
pub struct NativeOpusDecoder {
sample_rate: u32,
channels: u8,
}
#[cfg(target_arch = "wasm32")]
impl NativeOpusDecoder {
#[allow(dead_code)]
pub async fn new(sample_rate: u32, channels: u8) -> Result<Self> {
Ok(Self {
sample_rate,
channels,
})
}
}
#[cfg(target_arch = "wasm32")]
impl AudioDecoder for NativeOpusDecoder {
fn sample_rate(&self) -> u32 {
self.sample_rate
}
fn channels(&self) -> u8 {
self.channels
}
fn decode(&mut self, _encoded: &[u8]) -> Result<Vec<f32>> {
let samples = (self.sample_rate as f32 * 0.02) as usize * self.channels as usize;
Ok(vec![0.0; samples])
}
}