From 335aa39f7c4cfc4701a21c8d2397bcb0cc7f6f24 Mon Sep 17 00:00:00 2001 From: Kasper Date: Tue, 2 Feb 2021 02:11:35 +0100 Subject: [PATCH] Add mpeg_aac_decoder example (#50) * Add mpeg_aac_decoder example * Convert mpeg_aac_decoder example to it's own package --- examples/mpeg_aac_decoder/.gitignore | 2 + examples/mpeg_aac_decoder/Cargo.toml | 9 + examples/mpeg_aac_decoder/audio_aac.m4a | Bin 0 -> 65998 bytes examples/mpeg_aac_decoder/src/main.rs | 237 ++++++++++++++++++++++++ 4 files changed, 248 insertions(+) create mode 100644 examples/mpeg_aac_decoder/.gitignore create mode 100644 examples/mpeg_aac_decoder/Cargo.toml create mode 100644 examples/mpeg_aac_decoder/audio_aac.m4a create mode 100644 examples/mpeg_aac_decoder/src/main.rs diff --git a/examples/mpeg_aac_decoder/.gitignore b/examples/mpeg_aac_decoder/.gitignore new file mode 100644 index 0000000..1b72444 --- /dev/null +++ b/examples/mpeg_aac_decoder/.gitignore @@ -0,0 +1,2 @@ +/Cargo.lock +/target diff --git a/examples/mpeg_aac_decoder/Cargo.toml b/examples/mpeg_aac_decoder/Cargo.toml new file mode 100644 index 0000000..97426c7 --- /dev/null +++ b/examples/mpeg_aac_decoder/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "mpeg_aac_decoder" +version = "0.1.0" +edition = "2018" + +[dependencies] +mp4 = "0.8.1" +fdk-aac = "0.4.0" +rodio = { version = "0.13.0", default-features = false } diff --git a/examples/mpeg_aac_decoder/audio_aac.m4a b/examples/mpeg_aac_decoder/audio_aac.m4a new file mode 100644 index 0000000000000000000000000000000000000000..5c3f57cc4b147898194133fc3966fc0a5b66f006 GIT binary patch literal 65998 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 REXX1JKLP(e^Z!rye*pM*I#mDw literal 0 HcmV?d00001 diff --git a/examples/mpeg_aac_decoder/src/main.rs b/examples/mpeg_aac_decoder/src/main.rs new file mode 100644 index 0000000..ee35f30 --- /dev/null +++ b/examples/mpeg_aac_decoder/src/main.rs @@ -0,0 +1,237 @@ +use fdk_aac::dec::{Decoder, DecoderError, Transport}; +use rodio::{OutputStream, Sink, Source}; +use std::fs::File; +use std::io::{BufReader, Read, Seek}; +use std::ops::Range; +use std::time::Duration; + +fn main() { + let path = "audio_aac.m4a"; + let file = File::open(path).expect("Error opening file"); + + let metadata = file.metadata().expect("Error getting file metadata"); + let size = metadata.len(); + let buf = BufReader::new(file); + + let decoder = MpegAacDecoder::new(buf, size).expect("Error creating decoder"); + + let output_stream = OutputStream::try_default(); + let (_stream, handle) = output_stream.expect("Error creating output stream"); + let sink = Sink::try_new(&handle).expect("Error creating sink"); + + sink.append(decoder); + sink.play(); + sink.set_volume(0.5); + sink.sleep_until_end(); +} + +pub struct MpegAacDecoder +where + R: Read + Seek, +{ + mp4_reader: mp4::Mp4Reader, + decoder: Decoder, + current_pcm_index: usize, + current_pcm: Vec, + track_id: u32, + position: u32, +} + +impl MpegAacDecoder +where + R: Read + Seek, +{ + pub fn new(reader: R, size: u64) -> Result, &'static str> { + let decoder = Decoder::new(Transport::Adts); + let mp4 = mp4::Mp4Reader::read_header(reader, size).or(Err("Error reading MPEG header"))?; + let mut track_id: Option = None; + { + for track in mp4.tracks().iter() { + let media_type = track.media_type().or(Err("Error getting media type"))?; + match media_type { + mp4::MediaType::AAC => { + track_id = Some(track.track_id()); + break; + } + _ => {} + } + } + } + match track_id { + Some(track_id) => { + return Ok(MpegAacDecoder { + mp4_reader: mp4, + decoder: decoder, + current_pcm_index: 0, + current_pcm: Vec::new(), + track_id: track_id, + position: 1, + }); + } + None => { + return Err("No aac track found"); + } + } + } +} + +impl Iterator for MpegAacDecoder +where + R: Read + Seek, +{ + type Item = i16; + fn next(&mut self) -> Option { + if self.current_pcm_index == self.current_pcm.len() { + let mut pcm = vec![0; 8192]; + let result = match self.decoder.decode_frame(&mut self.current_pcm) { + Err(DecoderError::NOT_ENOUGH_BITS) => { + let sample_result = self.mp4_reader.read_sample(self.track_id, self.position); + let sample = sample_result.expect("Error reading sample")?; + let tracks = self.mp4_reader.tracks(); + let track = tracks.get(self.track_id as usize - 1).expect("No track ID"); + let adts_header = construct_adts_header(track, &sample).expect("ADTS bytes"); + let adts_bytes = mp4::Bytes::copy_from_slice(&adts_header); + let bytes = [adts_bytes, sample.bytes].concat(); + self.position += 1; + let _bytes_read = match self.decoder.fill(&bytes) { + Ok(bytes_read) => bytes_read, + Err(_) => return None, + }; + self.decoder.decode_frame(&mut pcm) + } + val => val, + }; + if let Err(err) = result { + println!("DecoderError: {}", err); + return None; + } + let decoded_fram_size = self.decoder.decoded_frame_size(); + if decoded_fram_size < pcm.len() { + let _ = pcm.split_off(decoded_fram_size); + } + self.current_pcm = pcm; + self.current_pcm_index = 0; + } + let value = self.current_pcm[self.current_pcm_index]; + self.current_pcm_index += 1; + return Some(value); + } +} + +impl Source for MpegAacDecoder +where + R: Read + Seek, +{ + fn current_frame_len(&self) -> Option { + let frame_size: usize = self.decoder.decoded_frame_size(); + Some(frame_size) + } + fn channels(&self) -> u16 { + let num_channels: i32 = self.decoder.stream_info().numChannels; + num_channels as _ + } + fn sample_rate(&self) -> u32 { + let sample_rate: i32 = self.decoder.stream_info().sampleRate; + sample_rate as _ + } + fn total_duration(&self) -> Option { + return None; + } +} + +fn get_bits(byte: u16, range: Range) -> u16 { + let shaved_left = byte << range.start - 1; + let moved_back = shaved_left >> range.start - 1; + let shave_right = moved_back >> 16 - range.end; + return shave_right; +} + +fn get_bits_u8(byte: u8, range: Range) -> u8 { + let shaved_left = byte << range.start - 1; + let moved_back = shaved_left >> range.start - 1; + let shave_right = moved_back >> 8 - range.end; + return shave_right; +} + +pub fn construct_adts_header(track: &mp4::Mp4Track, sample: &mp4::Mp4Sample) -> Option> { + // B: Only support 0 (MPEG-4) + // D: Only support 1 (without CRC) + // byte7 and byte9 not included without CRC + let adts_header_length = 7; + + // AAAA_AAAA + let byte0 = 0b1111_1111; + + // AAAA_BCCD + let byte1 = 0b1111_0001; + + // EEFF_FFGH + let mut byte2 = 0b0000_0000; + let object_type = match track.audio_profile() { + Ok(mp4::AudioObjectType::AacMain) => 1, + Ok(mp4::AudioObjectType::AacLowComplexity) => 2, + Ok(mp4::AudioObjectType::AacScalableSampleRate) => 3, + Ok(mp4::AudioObjectType::AacLongTermPrediction) => 4, + Err(_) => return None, + }; + let adts_object_type = object_type - 1; + byte2 = (byte2 << 2) | adts_object_type; // EE + + let sample_freq_index = match track.sample_freq_index() { + Ok(mp4::SampleFreqIndex::Freq96000) => 0, + Ok(mp4::SampleFreqIndex::Freq88200) => 1, + Ok(mp4::SampleFreqIndex::Freq64000) => 2, + Ok(mp4::SampleFreqIndex::Freq48000) => 3, + Ok(mp4::SampleFreqIndex::Freq44100) => 4, + Ok(mp4::SampleFreqIndex::Freq32000) => 5, + Ok(mp4::SampleFreqIndex::Freq24000) => 6, + Ok(mp4::SampleFreqIndex::Freq22050) => 7, + Ok(mp4::SampleFreqIndex::Freq16000) => 8, + Ok(mp4::SampleFreqIndex::Freq12000) => 9, + Ok(mp4::SampleFreqIndex::Freq11025) => 10, + Ok(mp4::SampleFreqIndex::Freq8000) => 11, + Ok(mp4::SampleFreqIndex::Freq7350) => 12, + // 13-14 = reserved + // 15 = explicit frequency (forbidden in adts) + Err(_) => return None, + }; + byte2 = (byte2 << 4) | sample_freq_index; // FFFF + byte2 = (byte2 << 1) | 0b1; // G + + let channel_config = match track.channel_config() { + // 0 = for when channel config is sent via an inband PCE + Ok(mp4::ChannelConfig::Mono) => 1, + Ok(mp4::ChannelConfig::Stereo) => 2, + Ok(mp4::ChannelConfig::Three) => 3, + Ok(mp4::ChannelConfig::Four) => 4, + Ok(mp4::ChannelConfig::Five) => 5, + Ok(mp4::ChannelConfig::FiveOne) => 6, + Ok(mp4::ChannelConfig::SevenOne) => 7, + // 8-15 = reserved + Err(_) => return None, + }; + byte2 = (byte2 << 1) | get_bits_u8(channel_config, 6..6); // H + + // HHIJ_KLMM + let mut byte3 = 0b0000_0000; + byte3 = (byte3 << 2) | get_bits_u8(channel_config, 7..8); // HH + byte3 = (byte3 << 4) | 0b1111; // IJKL + + let frame_length = adts_header_length + sample.bytes.len() as u16; + byte3 = (byte3 << 2) | get_bits(frame_length, 3..5) as u8; // MM + + // MMMM_MMMM + let byte4 = get_bits(frame_length, 6..13) as u8; + + // MMMO_OOOO + let mut byte5 = 0b0000_0000; + byte5 = (byte5 << 3) | get_bits(frame_length, 14..16) as u8; + byte5 = (byte5 << 5) | 0b11111; // OOOOO + + // OOOO_OOPP + let mut byte6 = 0b0000_0000; + byte6 = (byte6 << 6) | 0b111111; // OOOOOO + byte6 = (byte6 << 2) | 0b00; // PP + + return Some(vec![byte0, byte1, byte2, byte3, byte4, byte5, byte6]); +}