silence_core/opus/
encode.rs1use opus::{Channels, Encoder};
4
5use crate::io::EncoderType;
6
7use crate::io::SoundPacket;
8
9pub fn create_opus_encoder(
20 sample_rate: u32,
21 opus_mode: opus::Application,
22 bitrate: opus::Bitrate,
23 channels: Channels,
24) -> anyhow::Result<Encoder> {
25 let mut encoder = opus::Encoder::new(sample_rate, channels, opus_mode)?;
26
27 encoder.set_bitrate(bitrate)?;
28
29 if matches!(opus_mode, opus::Application::Voip) {
30 encoder.set_inband_fec(true)?;
31 } else {
32 encoder.set_inband_fec(false)?;
33 }
34
35 Ok(encoder)
36}
37
38pub fn encode_sample_set_size_opus(
50 encoder: &mut Encoder,
51 samples: &[f32],
52 samples_per_frame: usize,
53) -> anyhow::Result<SoundPacket> {
54 let mut compressed_buffer = vec![0; 1500];
55
56 let encoded_bytes_count = encoder.encode_float(samples, &mut compressed_buffer)?;
57
58 Ok(SoundPacket {
59 encoder_type: EncoderType::Opus(encoder.get_inband_fec()?),
60 sample_rate: encoder.get_sample_rate()?,
61 channels: 2,
62 bytes: compressed_buffer[..encoded_bytes_count].to_vec(),
63 samples_per_frame: samples_per_frame as u64,
64 })
65}
66
67pub fn encode_samples_opus(
79 mut encoder: Encoder,
80 samples: &[f32],
81 frame_duration_ms: u32,
82 channels: Channels,
83) -> anyhow::Result<Vec<SoundPacket>> {
84 let samples_per_frame = (encoder.get_sample_rate()? * frame_duration_ms) / 1000;
85 let samples_per_frame = (samples_per_frame * channels as u32) as usize;
86 let mut sound_packets = vec![];
87
88 for sample_chunk in samples.chunks(samples_per_frame) {
89 let sample = if sample_chunk.len() < samples_per_frame {
90 let mut padded_frame = Vec::with_capacity(samples_per_frame);
91 padded_frame.extend_from_slice(sample_chunk);
92 padded_frame.resize(samples_per_frame, 0.);
93 padded_frame
94 } else {
95 sample_chunk.to_vec()
96 };
97
98 let sound_packet = encode_sample_set_size_opus(&mut encoder, &sample, samples_per_frame)?;
99
100 sound_packets.push(sound_packet);
101 }
102
103 Ok(sound_packets)
104}