1use std::ffi::CStr;
2use std::fmt::{self, Debug, Display};
3use std::marker::Send;
4use std::mem::MaybeUninit;
5use std::ptr;
6use std::slice;
7use std::str;
8
9use faad2_sys::{self, NeAACDecHandle, c_char, c_uchar, c_ulong};
10
11unsafe fn static_cstr(ptr: *const c_char) -> &'static str {
12 str::from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes())
13}
14
15pub fn version() -> (&'static str, &'static str) {
16 unsafe {
17 let mut id: *const c_char = ptr::null();
18 let mut copyright: *const c_char = ptr::null();
19
20 faad2_sys::NeAACDecGetVersion(&mut id as *mut _, &mut copyright as *mut _);
21
22 (static_cstr(id), static_cstr(copyright))
23 }
24}
25
26pub struct Error(c_uchar);
27
28impl Error {
29 pub fn message(&self) -> &'static str {
30 unsafe {
31 static_cstr(faad2_sys::NeAACDecGetErrorMessage(self.0))
32 }
33 }
34}
35
36impl Display for Error {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 write!(f, "{}", self.message())
39 }
40}
41
42impl Debug for Error {
43 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44 write!(f, "Error {{ code: {:?}, message: {:?} }}", self.0, self.message())
45 }
46}
47
48struct DecoderHandle {
49 handle: NeAACDecHandle,
50}
51
52unsafe impl Send for DecoderHandle {}
53
54impl DecoderHandle {
55 fn alloc() -> Self {
56 let handle = unsafe { faad2_sys::NeAACDecOpen() };
57
58 if handle == ptr::null_mut() {
59 panic!("NeAACDecOpen failed")
60 } else {
61 DecoderHandle { handle }
62 }
63 }
64}
65
66impl Drop for DecoderHandle {
67 fn drop(&mut self) {
68 unsafe {
69 faad2_sys::NeAACDecClose(self.handle);
70 }
71 }
72}
73
74pub struct Decoder {
75 decoder: DecoderHandle,
76 sample_rate: usize,
77 channels: usize,
78}
79
80#[derive(Debug)]
81pub struct DecodeResult<'a> {
82 pub samples: &'a [f32],
83 pub bytes_consumed: usize,
84 pub channels: usize,
85 pub sample_rate: usize,
86}
87
88impl Decoder {
89 pub fn new(audio_specific_config: &[u8]) -> Result<Self, ()> {
90 unsafe {
91 let decoder = DecoderHandle::alloc();
92
93 let mut config = faad2_sys::NeAACDecGetCurrentConfiguration(decoder.handle);
94 (*config).outputFormat = faad2_sys::FAAD_FMT_FLOAT;
95 if faad2_sys::NeAACDecSetConfiguration(decoder.handle, config) != 1 {
96 return Err(());
97 }
98
99 let mut sample_rate: c_ulong = 0;
100 let mut channels: c_uchar = 0;
101
102 let err = faad2_sys::NeAACDecInit2(
103 decoder.handle,
104 audio_specific_config.as_ptr(),
105 audio_specific_config.len() as c_ulong,
106 &mut sample_rate as *mut _,
107 &mut channels as *mut _,
108 );
109
110 if err != 0 {
111 return Err(());
112 }
113
114 Ok(Decoder {
115 decoder,
116 sample_rate: sample_rate as usize,
117 channels: channels as usize,
118 })
119 }
120 }
121
122 pub fn sample_rate(&self) -> usize {
123 self.sample_rate
124 }
125
126 pub fn channels(&self) -> usize {
127 self.channels
128 }
129
130 pub fn decode(&mut self, data: &[u8]) -> Result<DecodeResult<'_>, Error> {
131 unsafe {
132 let mut frame_info = MaybeUninit::zeroed();
133
134 let samples = faad2_sys::NeAACDecDecode(
135 self.decoder.handle,
136 frame_info.as_mut_ptr(),
137 data.as_ptr(),
138 data.len() as c_ulong,
139 );
140
141 let frame_info = frame_info.assume_init();
142
143 if samples == ptr::null_mut() {
144 return Err(Error(frame_info.error));
145 }
146
147 let info = DecodeResult {
148 samples: slice::from_raw_parts::<f32>(samples as *const f32, frame_info.samples as usize),
149 bytes_consumed: frame_info.bytesconsumed as usize,
150 channels: frame_info.channels as usize,
151 sample_rate: frame_info.samplerate as usize,
152 };
153
154 self.channels = info.channels;
155 self.sample_rate = info.sample_rate;
156
157 Ok(info)
158 }
159 }
160}