1#![cfg_attr(not(cargo_c), forbid(unsafe_code))]
10#![cfg_attr(test, deny(warnings))]
11
12extern crate byteorder;
23extern crate tinyvec;
24#[cfg(feature = "ogg")]
25extern crate ogg;
26#[cfg(feature = "async_ogg")]
27#[macro_use]
28extern crate futures;
29#[cfg(feature = "async_ogg")]
30extern crate tokio_io;
31
32macro_rules! try {
33 ($expr:expr) => (match $expr {
34 $crate::std::result::Result::Ok(val) => val,
35 $crate::std::result::Result::Err(err) => {
36 return Err($crate::std::convert::From::from(err));
37 }
38 })
39}
40
41macro_rules! record_residue_pre_inverse {
56 ($residue_vectors:expr) => {
57}
63}
64
65macro_rules! record_residue_post_inverse {
66 ($residue_vectors:expr) => {
67}
73}
74
75macro_rules! record_pre_mdct {
76 ($audio_spectri:expr) => {
77}
83}
84
85macro_rules! record_post_mdct {
86 ($audio_spectri:expr) => {
87}
93}
94
95pub mod header;
96mod header_cached;
97mod huffman_tree;
98mod imdct;
99#[cfg(test)]
100mod imdct_test;
101pub mod audio;
102mod bitpacking;
103#[cfg(feature = "ogg")]
104pub mod inside_ogg;
105pub mod samples;
106
107#[cfg(feature = "ogg")]
108#[doc(no_inline)]
109pub use ogg::OggReadError;
110
111#[cfg(cargo_c)]
112mod capi;
113
114#[cfg(cargo_c)]
115pub use capi::*;
116
117#[derive(Debug)]
119pub enum VorbisError {
120 BadAudio(audio::AudioReadError),
121 BadHeader(header::HeaderReadError),
122 #[cfg(feature = "ogg")]
123 OggError(OggReadError),
124}
125
126impl std::error::Error for VorbisError {}
127
128impl std::fmt::Display for VorbisError {
129 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
130 write!(fmt, "{}", match self {
131 VorbisError::BadAudio(_) => "Vorbis bitstream audio decode problem",
132 VorbisError::BadHeader(_) => "Vorbis bitstream header decode problem",
133 #[cfg(feature = "ogg")]
134 VorbisError::OggError(_) => "Ogg decode problem",
135 })
136 }
137}
138
139impl From<audio::AudioReadError> for VorbisError {
140 fn from(err :audio::AudioReadError) -> VorbisError {
141 VorbisError::BadAudio(err)
142 }
143}
144
145impl From<header::HeaderReadError> for VorbisError {
146 fn from(err :header::HeaderReadError) -> VorbisError {
147 VorbisError::BadHeader(err)
148 }
149}
150
151#[cfg(feature = "ogg")]
152impl From<OggReadError> for VorbisError {
153 fn from(err :OggReadError) -> VorbisError {
154 VorbisError::OggError(err)
155 }
156}
157
158fn ilog(val :u64) -> u8 {
159 64 - val.leading_zeros() as u8
160}
161
162#[test]
163fn test_ilog() {
164 assert_eq!(ilog(0), 0);
166 assert_eq!(ilog(1), 1);
167 assert_eq!(ilog(2), 2);
168 assert_eq!(ilog(3), 2);
169 assert_eq!(ilog(4), 3);
170 assert_eq!(ilog(7), 3);
171}
172
173fn bit_reverse(n :u32) -> u32 {
174 let mut nn = n;
176 nn = ((nn & 0xAAAAAAAA) >> 1) | ((nn & 0x55555555) << 1);
177 nn = ((nn & 0xCCCCCCCC) >> 2) | ((nn & 0x33333333) << 2);
178 nn = ((nn & 0xF0F0F0F0) >> 4) | ((nn & 0x0F0F0F0F) << 4);
179 nn = ((nn & 0xFF00FF00) >> 8) | ((nn & 0x00FF00FF) << 8);
180 return (nn >> 16) | (nn << 16);
181}
182
183
184#[allow(dead_code)]
185fn print_u8_slice(arr :&[u8]) {
186 if arr.len() <= 4 {
187 for a in arr {
188 print!("0x{:02x} ", a);
189 }
190 println!("");
191 return;
192 }
193 println!("[");
194 let mut i :usize = 0;
195 while i * 4 < arr.len() - 4 {
196 println!("\t0x{:02x}, 0x{:02x}, 0x{:02x}, 0x{:02x},",
197 arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2], arr[i * 4 + 3]);
198 i += 1;
199 }
200 match arr.len() as i64 - i as i64 * 4 {
201 1 => println!("\t0x{:02x}];", arr[i * 4]),
202 2 => println!("\t0x{:02x}, 0x{:02x}];", arr[i * 4], arr[i * 4 + 1]),
203 3 => println!("\t0x{:02x}, 0x{:02x}, 0x{:02x}];",
204 arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2]),
205 4 => println!("\t0x{:02x}, 0x{:02x}, 0x{:02x}, 0x{:02x}];",
206 arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2], arr[i * 4 + 3]),
207 de => panic!("impossible value {}", de),
208 }
209}
210
211#[allow(dead_code)]
212fn print_u32_slice(arr :&[u32]) {
213 if arr.len() <= 4 {
214 for a in arr {
215 print!("0x{:02x} ", a);
216 }
217 println!("");
218 return;
219 }
220 println!("[");
221 let mut i :usize = 0;
222 while i * 4 < arr.len() - 4 {
223 println!("\t0x{:08x}, 0x{:08x}, 0x{:08x}, 0x{:08x},",
224 arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2], arr[i * 4 + 3]);
225 i += 1;
226 }
227 match arr.len() as i64 - i as i64 * 4 {
228 1 => println!("\t0x{:08x}];", arr[i * 4]),
229 2 => println!("\t0x{:08x}, 0x{:08x}];", arr[i * 4], arr[i * 4 + 1]),
230 3 => println!("\t0x{:08x}, 0x{:08x}, 0x{:08x}];",
231 arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2]),
232 4 => println!("\t0x{:08x}, 0x{:08x}, 0x{:08x}, 0x{:08x}];",
233 arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2], arr[i * 4 + 3]),
234 de => panic!("impossible value {}", de),
235 }
236}
237
238
239#[allow(dead_code)]
240fn print_f64_slice(arr :&[f64]) {
241 if arr.len() <= 4 {
242 for a in arr {
243 print!("0x{} ", a);
244 }
245 println!("");
246 return;
247 }
248 println!("[");
249 let mut i :usize = 0;
250 while i * 4 < arr.len() - 4 {
251 println!("\t{}, {}, {}, {},",
252 arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2], arr[i * 4 + 3]);
253 i += 1;
254 }
255 match arr.len() as i64 - i as i64 * 4 {
256 1 => println!("\t{}];", arr[i * 4]),
257 2 => println!("\t{}, {}];", arr[i * 4], arr[i * 4 + 1]),
258 3 => println!("\t{}, {}, {}];",
259 arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2]),
260 4 => println!("\t{}, {}, {}, {}];",
261 arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2], arr[i * 4 + 3]),
262 de => panic!("impossible value {}", de),
263 }
264}