use mp4::{AudioObjectType, ChannelConfig, Mp4Sample, SampleFreqIndex};
use std::ops::Range;
use crate::Error;
fn get_bits(byte: u16, range: Range<u16>) -> 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>) -> 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(
object_type: AudioObjectType,
sample_freq_index: SampleFreqIndex,
channel_config: ChannelConfig,
sample: &Mp4Sample,
) -> Result<Vec<u8>, Error> {
let adts_header_length = 7;
let byte0 = 0b1111_1111;
let byte1 = 0b1111_0001;
let mut byte2 = 0b0000_0000;
let object_type = match object_type {
AudioObjectType::AacLowComplexity => 2,
AudioObjectType::SpectralBandReplication => 2, AudioObjectType::ParametricStereo => 2, aot => return Err(Error::UnsupportedObjectType(aot)),
};
let adts_object_type = object_type - 1;
byte2 = (byte2 << 2) | adts_object_type;
let sample_freq_index = match sample_freq_index {
SampleFreqIndex::Freq96000 => 0,
SampleFreqIndex::Freq88200 => 1,
SampleFreqIndex::Freq64000 => 2,
SampleFreqIndex::Freq48000 => 3,
SampleFreqIndex::Freq44100 => 4,
SampleFreqIndex::Freq32000 => 5,
SampleFreqIndex::Freq24000 => 6,
SampleFreqIndex::Freq22050 => 7,
SampleFreqIndex::Freq16000 => 8,
SampleFreqIndex::Freq12000 => 9,
SampleFreqIndex::Freq11025 => 10,
SampleFreqIndex::Freq8000 => 11,
SampleFreqIndex::Freq7350 => 12,
};
byte2 = (byte2 << 4) | sample_freq_index; byte2 = (byte2 << 1) | 0b1;
let channel_config = match channel_config {
ChannelConfig::Mono => 1,
ChannelConfig::Stereo => 2,
ChannelConfig::Three => 3,
ChannelConfig::Four => 4,
ChannelConfig::Five => 5,
ChannelConfig::FiveOne => 6,
ChannelConfig::SevenOne => 7,
};
byte2 = (byte2 << 1) | get_bits_u8(channel_config, 6..6);
let mut byte3 = 0b0000_0000;
byte3 = (byte3 << 2) | get_bits_u8(channel_config, 7..8); byte3 = (byte3 << 4) | 0b1111;
let frame_length = adts_header_length + sample.bytes.len() as u16;
byte3 = (byte3 << 2) | get_bits(frame_length, 3..5) as u8;
let byte4 = get_bits(frame_length, 6..13) as u8;
let mut byte5 = 0b0000_0000;
byte5 = (byte5 << 3) | get_bits(frame_length, 14..16) as u8;
byte5 = (byte5 << 5) | 0b11111;
let mut byte6 = 0b0000_0000;
byte6 = (byte6 << 6) | 0b111111; byte6 = (byte6 << 2) | 0b00;
return Ok(vec![byte0, byte1, byte2, byte3, byte4, byte5, byte6])
}