Skip to content

Commit 6b36145

Browse files
Add mpeg_aac_decoder example (alfg#50)
* Add mpeg_aac_decoder example * Convert mpeg_aac_decoder example to it's own package
1 parent 49ce73d commit 6b36145

File tree

4 files changed

+248
-0
lines changed

4 files changed

+248
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/Cargo.lock
2+
/target
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "mpeg_aac_decoder"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
[dependencies]
7+
mp4 = "0.8.1"
8+
fdk-aac = "0.4.0"
9+
rodio = { version = "0.13.0", default-features = false }
64.5 KB
Binary file not shown.
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
use fdk_aac::dec::{Decoder, DecoderError, Transport};
2+
use rodio::{OutputStream, Sink, Source};
3+
use std::fs::File;
4+
use std::io::{BufReader, Read, Seek};
5+
use std::ops::Range;
6+
use std::time::Duration;
7+
8+
fn main() {
9+
let path = "audio_aac.m4a";
10+
let file = File::open(path).expect("Error opening file");
11+
12+
let metadata = file.metadata().expect("Error getting file metadata");
13+
let size = metadata.len();
14+
let buf = BufReader::new(file);
15+
16+
let decoder = MpegAacDecoder::new(buf, size).expect("Error creating decoder");
17+
18+
let output_stream = OutputStream::try_default();
19+
let (_stream, handle) = output_stream.expect("Error creating output stream");
20+
let sink = Sink::try_new(&handle).expect("Error creating sink");
21+
22+
sink.append(decoder);
23+
sink.play();
24+
sink.set_volume(0.5);
25+
sink.sleep_until_end();
26+
}
27+
28+
pub struct MpegAacDecoder<R>
29+
where
30+
R: Read + Seek,
31+
{
32+
mp4_reader: mp4::Mp4Reader<R>,
33+
decoder: Decoder,
34+
current_pcm_index: usize,
35+
current_pcm: Vec<i16>,
36+
track_id: u32,
37+
position: u32,
38+
}
39+
40+
impl<R> MpegAacDecoder<R>
41+
where
42+
R: Read + Seek,
43+
{
44+
pub fn new(reader: R, size: u64) -> Result<MpegAacDecoder<R>, &'static str> {
45+
let decoder = Decoder::new(Transport::Adts);
46+
let mp4 = mp4::Mp4Reader::read_header(reader, size).or(Err("Error reading MPEG header"))?;
47+
let mut track_id: Option<u32> = None;
48+
{
49+
for track in mp4.tracks().iter() {
50+
let media_type = track.media_type().or(Err("Error getting media type"))?;
51+
match media_type {
52+
mp4::MediaType::AAC => {
53+
track_id = Some(track.track_id());
54+
break;
55+
}
56+
_ => {}
57+
}
58+
}
59+
}
60+
match track_id {
61+
Some(track_id) => {
62+
return Ok(MpegAacDecoder {
63+
mp4_reader: mp4,
64+
decoder: decoder,
65+
current_pcm_index: 0,
66+
current_pcm: Vec::new(),
67+
track_id: track_id,
68+
position: 1,
69+
});
70+
}
71+
None => {
72+
return Err("No aac track found");
73+
}
74+
}
75+
}
76+
}
77+
78+
impl<R> Iterator for MpegAacDecoder<R>
79+
where
80+
R: Read + Seek,
81+
{
82+
type Item = i16;
83+
fn next(&mut self) -> Option<i16> {
84+
if self.current_pcm_index == self.current_pcm.len() {
85+
let mut pcm = vec![0; 8192];
86+
let result = match self.decoder.decode_frame(&mut self.current_pcm) {
87+
Err(DecoderError::NOT_ENOUGH_BITS) => {
88+
let sample_result = self.mp4_reader.read_sample(self.track_id, self.position);
89+
let sample = sample_result.expect("Error reading sample")?;
90+
let tracks = self.mp4_reader.tracks();
91+
let track = tracks.get(self.track_id as usize - 1).expect("No track ID");
92+
let adts_header = construct_adts_header(track, &sample).expect("ADTS bytes");
93+
let adts_bytes = mp4::Bytes::copy_from_slice(&adts_header);
94+
let bytes = [adts_bytes, sample.bytes].concat();
95+
self.position += 1;
96+
let _bytes_read = match self.decoder.fill(&bytes) {
97+
Ok(bytes_read) => bytes_read,
98+
Err(_) => return None,
99+
};
100+
self.decoder.decode_frame(&mut pcm)
101+
}
102+
val => val,
103+
};
104+
if let Err(err) = result {
105+
println!("DecoderError: {}", err);
106+
return None;
107+
}
108+
let decoded_fram_size = self.decoder.decoded_frame_size();
109+
if decoded_fram_size < pcm.len() {
110+
let _ = pcm.split_off(decoded_fram_size);
111+
}
112+
self.current_pcm = pcm;
113+
self.current_pcm_index = 0;
114+
}
115+
let value = self.current_pcm[self.current_pcm_index];
116+
self.current_pcm_index += 1;
117+
return Some(value);
118+
}
119+
}
120+
121+
impl<R> Source for MpegAacDecoder<R>
122+
where
123+
R: Read + Seek,
124+
{
125+
fn current_frame_len(&self) -> Option<usize> {
126+
let frame_size: usize = self.decoder.decoded_frame_size();
127+
Some(frame_size)
128+
}
129+
fn channels(&self) -> u16 {
130+
let num_channels: i32 = self.decoder.stream_info().numChannels;
131+
num_channels as _
132+
}
133+
fn sample_rate(&self) -> u32 {
134+
let sample_rate: i32 = self.decoder.stream_info().sampleRate;
135+
sample_rate as _
136+
}
137+
fn total_duration(&self) -> Option<Duration> {
138+
return None;
139+
}
140+
}
141+
142+
fn get_bits(byte: u16, range: Range<u16>) -> u16 {
143+
let shaved_left = byte << range.start - 1;
144+
let moved_back = shaved_left >> range.start - 1;
145+
let shave_right = moved_back >> 16 - range.end;
146+
return shave_right;
147+
}
148+
149+
fn get_bits_u8(byte: u8, range: Range<u8>) -> u8 {
150+
let shaved_left = byte << range.start - 1;
151+
let moved_back = shaved_left >> range.start - 1;
152+
let shave_right = moved_back >> 8 - range.end;
153+
return shave_right;
154+
}
155+
156+
pub fn construct_adts_header(track: &mp4::Mp4Track, sample: &mp4::Mp4Sample) -> Option<Vec<u8>> {
157+
// B: Only support 0 (MPEG-4)
158+
// D: Only support 1 (without CRC)
159+
// byte7 and byte9 not included without CRC
160+
let adts_header_length = 7;
161+
162+
// AAAA_AAAA
163+
let byte0 = 0b1111_1111;
164+
165+
// AAAA_BCCD
166+
let byte1 = 0b1111_0001;
167+
168+
// EEFF_FFGH
169+
let mut byte2 = 0b0000_0000;
170+
let object_type = match track.audio_profile() {
171+
Ok(mp4::AudioObjectType::AacMain) => 1,
172+
Ok(mp4::AudioObjectType::AacLowComplexity) => 2,
173+
Ok(mp4::AudioObjectType::AacScalableSampleRate) => 3,
174+
Ok(mp4::AudioObjectType::AacLongTermPrediction) => 4,
175+
Err(_) => return None,
176+
};
177+
let adts_object_type = object_type - 1;
178+
byte2 = (byte2 << 2) | adts_object_type; // EE
179+
180+
let sample_freq_index = match track.sample_freq_index() {
181+
Ok(mp4::SampleFreqIndex::Freq96000) => 0,
182+
Ok(mp4::SampleFreqIndex::Freq88200) => 1,
183+
Ok(mp4::SampleFreqIndex::Freq64000) => 2,
184+
Ok(mp4::SampleFreqIndex::Freq48000) => 3,
185+
Ok(mp4::SampleFreqIndex::Freq44100) => 4,
186+
Ok(mp4::SampleFreqIndex::Freq32000) => 5,
187+
Ok(mp4::SampleFreqIndex::Freq24000) => 6,
188+
Ok(mp4::SampleFreqIndex::Freq22050) => 7,
189+
Ok(mp4::SampleFreqIndex::Freq16000) => 8,
190+
Ok(mp4::SampleFreqIndex::Freq12000) => 9,
191+
Ok(mp4::SampleFreqIndex::Freq11025) => 10,
192+
Ok(mp4::SampleFreqIndex::Freq8000) => 11,
193+
Ok(mp4::SampleFreqIndex::Freq7350) => 12,
194+
// 13-14 = reserved
195+
// 15 = explicit frequency (forbidden in adts)
196+
Err(_) => return None,
197+
};
198+
byte2 = (byte2 << 4) | sample_freq_index; // FFFF
199+
byte2 = (byte2 << 1) | 0b1; // G
200+
201+
let channel_config = match track.channel_config() {
202+
// 0 = for when channel config is sent via an inband PCE
203+
Ok(mp4::ChannelConfig::Mono) => 1,
204+
Ok(mp4::ChannelConfig::Stereo) => 2,
205+
Ok(mp4::ChannelConfig::Three) => 3,
206+
Ok(mp4::ChannelConfig::Four) => 4,
207+
Ok(mp4::ChannelConfig::Five) => 5,
208+
Ok(mp4::ChannelConfig::FiveOne) => 6,
209+
Ok(mp4::ChannelConfig::SevenOne) => 7,
210+
// 8-15 = reserved
211+
Err(_) => return None,
212+
};
213+
byte2 = (byte2 << 1) | get_bits_u8(channel_config, 6..6); // H
214+
215+
// HHIJ_KLMM
216+
let mut byte3 = 0b0000_0000;
217+
byte3 = (byte3 << 2) | get_bits_u8(channel_config, 7..8); // HH
218+
byte3 = (byte3 << 4) | 0b1111; // IJKL
219+
220+
let frame_length = adts_header_length + sample.bytes.len() as u16;
221+
byte3 = (byte3 << 2) | get_bits(frame_length, 3..5) as u8; // MM
222+
223+
// MMMM_MMMM
224+
let byte4 = get_bits(frame_length, 6..13) as u8;
225+
226+
// MMMO_OOOO
227+
let mut byte5 = 0b0000_0000;
228+
byte5 = (byte5 << 3) | get_bits(frame_length, 14..16) as u8;
229+
byte5 = (byte5 << 5) | 0b11111; // OOOOO
230+
231+
// OOOO_OOPP
232+
let mut byte6 = 0b0000_0000;
233+
byte6 = (byte6 << 6) | 0b111111; // OOOOOO
234+
byte6 = (byte6 << 2) | 0b00; // PP
235+
236+
return Some(vec![byte0, byte1, byte2, byte3, byte4, byte5, byte6]);
237+
}

0 commit comments

Comments
 (0)