1mod common;
2mod decode;
3mod encode;
4
5use thiserror::Error;
6
7pub use decode::decode;
8pub use encode::encode;
9
10use std::io::{Read, Seek, SeekFrom};
11pub fn is_ogg_opus<T: Read + Seek>(mut d: T) -> bool {
12 let mut buff = [0u8; 8];
13 if let Ok(_) = d.seek(SeekFrom::Start(28)) {
14 if let Ok(d) = d.read(&mut buff) {
15 if d == 8 {
16 return buff == decode::OPUS_MAGIC_HEADER;
17 }
18 }
19 }
20 false
22}
23#[derive(Debug, Error)]
24pub enum Error {
25 #[error("Input audio was malformed")]
26 MalformedAudio,
27
28 #[error("Encoding error")]
29 OpusError(#[from] audiopus::Error),
30
31 #[error("Failed to decode ogg")]
32 OggReadError(#[from] ogg::OggReadError),
33
34 #[error("Failed to write in OGG")]
35 OggWriteError(#[from]std::io::Error),
36
37 #[error("Invalid samples per second")]
38 InvalidSps,
39}
40
41#[cfg(test)]
42mod tests {
43 use std::fs::{File};
44 use std::io::{Cursor};
45
46 fn read_file_i16(path: &str) -> Vec<i16> {
47 let mut f = File::open(path).expect("no file found");
48 let (_, b) = wav::read(&mut f).unwrap();
49 b.try_into_sixteen().unwrap()
50 }
51
52 #[test]
53 fn dec_enc_empty() {
54 let audio = Vec::new();
55 let opus = crate::encode::<16000, 1>(&audio).unwrap();
56 let enc_fin_range = crate::encode::get_final_range();
57 let (audio2, _) = crate::decode::<_,16000>(Cursor::new(opus)).unwrap();
58 let dec_fin_range = crate::decode::get_final_range();
59 assert_eq!(audio.len(), audio2.len()); assert_eq!(enc_fin_range, dec_fin_range);
61 }
62
63 #[test]
64 fn dec_enc_recording_big() {
65 let audio = read_file_i16("test_assets/big.wav");
66 let opus = crate::encode::<16000, 1>(&audio).unwrap();
67 let enc_fin_range = crate::encode::get_final_range();
68 let (a2,_) = crate::decode::<_,16000>(Cursor::new(opus)).unwrap();
69 let dec_fin_range = crate::decode::get_final_range();
70 assert_eq!(dec_fin_range, enc_fin_range);
71 assert_eq!(audio.len(), a2.len());
72 }
73
74 #[test]
75 fn dec_enc_recording_small() {
76 let audio = read_file_i16("test_assets/small.wav");
79 let opus = crate::encode::<16000, 1>(&audio).unwrap();
80 let enc_fin_range = crate::encode::get_final_range();
81 let (a2, _) = crate::decode::<_, 16000>(Cursor::new(opus)).unwrap();
82 let dec_fin_range = crate::decode::get_final_range();
83 assert_eq!(dec_fin_range, enc_fin_range);
84 assert_eq!(audio.len(), a2.len());
85 }
86
87 #[test]
88 fn dec_enc_recording_whole() {
92 let audio = read_file_i16("test_assets/small.wav");
93
94 let opus = crate::encode::<16000, 1>(&audio).unwrap();
95 let enc_fr1 = crate::encode::get_final_range();
96
97 let (audio2, _) = crate::decode::<_, 16000>(Cursor::new(opus)).unwrap();
98 let dec_fr1 = crate::decode::get_final_range();
99
100 let opus2 = crate::encode::<16000, 1>(&audio2).unwrap();
101 let enc_fr2 = crate::encode::get_final_range();
102
103 let (audio3, _) = crate::decode::<_, 16000>(Cursor::new(opus2)).unwrap();
104 let dec_fr2 = crate::decode::get_final_range();
105
106 assert_eq!(audio2.len(), audio3.len());
107 assert_eq!(enc_fr1, dec_fr1);
108 assert_eq!(enc_fr2, dec_fr2);
109 }
110}