silence_core/opus/decode.rs
1//! Eanbles raw sample decoding from opus.
2
3use anyhow::Result;
4use opus::Decoder;
5
6use crate::io::SoundPacket;
7
8///
9/// Create an [`opus`] decoder.
10///
11/// # Behavior
12/// Creates an [`opus`] decoder from a specified sample rate (`u32`).
13///
14/// # Error
15/// Returns an error when created with an invalid sample rate.
16///
17pub fn create_opus_decoder(sample_rate: u32) -> anyhow::Result<Decoder> {
18 let decoder: Decoder = Decoder::new(sample_rate, opus::Channels::Stereo)?;
19
20 Ok(decoder)
21}
22
23///
24/// Decodes a [`SoundPacket`] (encoded with the [`opus`] codec), into raw samples.
25///
26/// # Behavior
27/// The decoder takes `fec` (Forward Error Correction) as an argument.
28/// Decodes a sound packet with the [`opus`] decoder into raw samples (`Vec<f32>`).
29/// All additional information is included in the [`SoundPacket`] to maximise code efficiency.
30///
31/// # Error
32/// Returns an error if an error occured while decoding the sound packet.
33///
34pub fn decode_sample_set_size_opus(
35 decoder: &mut Decoder,
36 sound_packet: SoundPacket,
37 fec: bool,
38) -> Result<Vec<f32>> {
39 let mut buf = vec![0f32; sound_packet.samples_per_frame as usize];
40
41 decoder.decode_float(&sound_packet.bytes, &mut buf, fec)?;
42
43 Ok(buf)
44}
45
46///
47/// Decodes a list of [`SoundPacket`]-s, into one raw sample.
48///
49/// # Behavior
50/// The function takes a [`Decoder`] and a list of [`SoundPacket`]-s to decode. All information about the decoding process is included in said [`SoundPacket`]-s.
51///
52/// # Error
53/// Returns an error, if the [`SoundPacket`] is corrupted (Contains invalid data)
54///
55pub fn decode_samples_opus(
56 mut decoder: Decoder,
57 sound_packets: Vec<SoundPacket>,
58) -> anyhow::Result<Vec<f32>> {
59 let mut samples = vec![];
60
61 for sound_packet in sound_packets {
62 let crate::io::EncoderType::Opus(fec) = sound_packet.encoder_type;
63
64 let decoded_samples = decode_sample_set_size_opus(&mut decoder, sound_packet, fec)?;
65
66 samples.extend(decoded_samples);
67 }
68
69 Ok(samples)
70}