-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopus.rs
More file actions
99 lines (88 loc) · 3.58 KB
/
Copy pathopus.rs
File metadata and controls
99 lines (88 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use crate::audio::{hexdump_debug, Decoder, Encoder};
use crate::AudioConfig;
use opus::{Application, Channels, Decoder as OpusDecoder, Encoder as OpusEncoder};
pub struct OpusCodec {
config: AudioConfig,
encoder: OpusEncoder,
decoder: OpusDecoder,
}
pub fn parse_channel(channels: u16) -> Channels {
match channels {
1 => Channels::Mono,
2 => Channels::Stereo,
// tbh you can mod the opus lib for there, this restriction might just be
_ => panic!("unsupported channel count {}", channels)
}
}
pub fn parse_application(profile: &str) -> Application {
match profile {
"voip" => Application::Voip,
"lowdelay" => Application::LowDelay,
"lowlatency" => Application::LowDelay,
_ => Application::Audio
}
}
impl OpusCodec {
pub fn new(config: &AudioConfig) -> Self {
let channels = parse_channel(config.channels);
let mut encoder = OpusEncoder::new(config.sample_rate, channels, parse_application(&config.profile)).expect("opus encoder init failure") ;
let mut decoder = OpusDecoder::new(config.sample_rate, channels).expect("opus decoder init failure");
if config.bitrate == 0 {
encoder.set_bitrate(opus::Bitrate::Auto).expect("opus bitrate set to auto failure");
} else if config.bitrate < 0 {
encoder.set_bitrate(opus::Bitrate::Max).expect("opus bitrate set to max failure");
} else {
encoder.set_bitrate(opus::Bitrate::Bits(1024 * config.bitrate)).expect(&format!("opus bitrate set to {}kbps failure", config.bitrate));
}
encoder.set_inband_fec(config.fec).expect("opus inband fec set failure");
encoder.set_vbr(config.vbr).expect("opus vbr set failure");
// encoder.set_packet_loss_perc(value)
if let Some(percent) = config.packet_loss_perc {
if percent > 100 {
println!("this packet loss percent looks invalid to me...")
}
encoder.set_packet_loss_perc(percent as i32).expect("opus packet loss set failure");
}
if let Some(gain) = config.gain {
let gain_calculated: i32 = (gain * 255.0).round() as i32;
decoder.set_gain(gain_calculated).expect("opus gain set failure");
}
Self {
config: config.clone(),
encoder: encoder,
decoder: decoder
}
}
}
impl Encoder for OpusCodec {
fn encode(&mut self, input: &[f32], output: &mut Vec<u8>) -> Result<(), String> {
match self.encoder.encode_float(input, output) {
Ok(wrote) => {
output.resize(wrote, 0); // this will only shrink
// println!("encode {} bytes sample {}", wrote, input[69]);
// hexdump_debug(output);
Ok(())
},
Err(err) => {
// Err(format!("opus encoding got an error: {:?}", err))
Err(format!("opus encoding got an error: {:?} {:?} {}", err, input, input.len()))
}
}
}
}
impl Decoder for OpusCodec {
fn decode(&mut self, input: &[u8], output: &mut Vec<f32>) -> Result<(), String> {
// println!("in {} out {}", input.len(), output.len());
match self.decoder.decode_float(input, output, self.config.fec) {
Ok(_) => {
Ok(())
},
Err(err) => {
if self.config.debug {
hexdump_debug(input);
}
Err(format!("opus decoding got an error: {:?} input: {} output: {}", err, input.len(), output.len()))
},
}
}
}