diff --git a/src/audio/mp3.rs b/src/audio/mp3.rs index 9a502d7..31a2282 100644 --- a/src/audio/mp3.rs +++ b/src/audio/mp3.rs @@ -22,12 +22,19 @@ use crate::util::content_type::ContentType; const ID3V2_IDENTIFIER: [u8; 3] = [0x49, 0x44, 0x33]; const ID3V2_HEADER_LENGTH: usize = 10; const MP3_HEADER_LENGTH: usize = 4; -const MP3_HEADER_SYNC_WORD_MASK: u32 = 0xFFE00000; // 11111111111000000000000000000000 -const MP3_HEADER_VERSION_MASK: u32 = 0x180000; // 00000000000110000000000000000000 -const MP3_HEADER_LAYER_MASK: u32 = 0x60000; // 00000000000001100000000000000000 -const MP3_HEADER_BITRATE_MASK: u32 = 0xF000; // 00000000000000001111000000000000 -const MP3_HEADER_SAMPLING_RATE_MASK: u32 = 0xC00; // 00000000000000000000110000000000 -const MP3_HEADER_PADDING_MASK: u32 = 0x200; // 00000000000000000000001000000000 +const MP3_HEADER_SYNC_WORD_MASK: u32 = 0xFFE00000; // 11111111111000000000000000000000 +const MP3_HEADER_VERSION_MASK: u32 = 0x00180000; // 00000000000110000000000000000000 +const MP3_HEADER_LAYER_MASK: u32 = 0x00060000; // 00000000000001100000000000000000 +const MP3_HEADER_BITRATE_MASK: u32 = 0x0000F000; // 00000000000000001111000000000000 +const MP3_HEADER_SAMPLING_RATE_MASK: u32 = 0x00000C00; // 00000000000000000000110000000000 +const MP3_HEADER_PADDING_MASK: u32 = 0x00000200; // 00000000000000000000001000000000 + +// const MP3_HEADER_SYNC_WORD_MASK: u32 = 0xFFF00000; // 11111111111100000000000000000000 +// const MP3_HEADER_VERSION_MASK: u32 = 0xC0000; // 00000000000011000000000000000000 +// const MP3_HEADER_LAYER_MASK: u32 = 0x30000; // 00000000000000110000000000000000 +// const MP3_HEADER_BITRATE_MASK: u32 = 0x7800; // 00000000000000000111100000000000 +// const MP3_HEADER_SAMPLING_RATE_MASK: u32 = 0x600; // 00000000000000000000011000000000 +// const MP3_HEADER_PADDING_MASK: u32 = 0x100; // 00000000000000000000000100000000 #[derive(Debug)] enum AudioVersion { @@ -97,8 +104,8 @@ fn get_bitrate(header: u32, audio_version: &AudioVersion, layer: &LayerIndex) -> AudioVersion::MpegV2 | AudioVersion::MpegV25 => { match layer { - LayerIndex::LayerI => return Some(32), - LayerIndex::LayerII | LayerIndex::LayerIII => return Some(16), + LayerIndex::LayerI => return Some(56), + LayerIndex::LayerII | LayerIndex::LayerIII => return Some(24), } } } @@ -441,9 +448,9 @@ pub fn rip_mp3(data: &[u8], start_index: usize) -> Option { // get tag length let mut tag_length_bytes: [u8; 4] = [0; 4]; for j in 0..4 { - tag_length_bytes[j] = data[i+ID3V2_IDENTIFIER.len()+5+j]; + tag_length_bytes[j] = data[i+ID3V2_IDENTIFIER.len()+3+j]; } - // convert from syncsafe to a normal integer + // convert syncsafe integer to a normal one let mut tag_length: u32 = 0; for j in 0..4 { tag_length = tag_length << 7; @@ -474,6 +481,7 @@ pub fn rip_mp3(data: &[u8], start_index: usize) -> Option { // check for sync word if !mp3_header & MP3_HEADER_SYNC_WORD_MASK == MP3_HEADER_SYNC_WORD_MASK { + println!("SYNCWORD NO"); break; } @@ -487,7 +495,7 @@ pub fn rip_mp3(data: &[u8], start_index: usize) -> Option { let audio_version: AudioVersion; match get_audio_version(mp3_header) { Some(version) => audio_version = version, - None => break, + None => {println!("VERSION NO {:032x}", mp3_header & MP3_HEADER_VERSION_MASK); break}, } println!("audio version is {:?}", audio_version); @@ -496,7 +504,7 @@ pub fn rip_mp3(data: &[u8], start_index: usize) -> Option { let layer: LayerIndex; match get_layer(mp3_header) { Some(l) => layer = l, - None => break, + None => {println!("LAYER NO"); break}, } println!("layer is {:?}", layer); @@ -506,7 +514,7 @@ pub fn rip_mp3(data: &[u8], start_index: usize) -> Option { let bitrate: u16; match get_bitrate(mp3_header, &audio_version, &layer) { Some(rate) => bitrate = rate, - None => break, + None => {println!("BITRATE NO"); break}, } println!("bitrate is {}", bitrate); @@ -519,7 +527,7 @@ pub fn rip_mp3(data: &[u8], start_index: usize) -> Option { let sampling_rate: u16; match get_sampling_rate(mp3_header, &audio_version) { Some(rate) => sampling_rate = rate, - None => break, + None => {println!("SAMPLING RATE NO"); break}, } println!("sampling rate is {}", sampling_rate); @@ -535,18 +543,22 @@ pub fn rip_mp3(data: &[u8], start_index: usize) -> Option { println!("padding is {}", padding); - - // finally calculate frame size - let frame_size: u32; + let slot_size: u32; match layer { - LayerIndex::LayerI => { - frame_size = (12 * bitrate as u32 * 1000 / sampling_rate as u32 + padding as u32) * 4; - } + LayerIndex::LayerI => slot_size = 4, + _ => slot_size = 1, + } - LayerIndex::LayerII | LayerIndex::LayerIII => { - frame_size = 144 * bitrate as u32 * 1000 / (sampling_rate as u32 + padding as u32); - } + let multiplier: u32; + match layer { + LayerIndex::LayerI => multiplier = 12, + _ => multiplier = 144000, } + + let slot_count: u32 = ((multiplier as u32 * (bitrate as u32 * 1000)) / sampling_rate as u32) + padding as u32; + + // finally calculate frame size + let frame_size: u32 = slot_count * slot_size; println!("frame size is {}", frame_size); // set cursor to the next frame diff --git a/src/main.rs b/src/main.rs index 8ed9378..9e877c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -141,9 +141,7 @@ fn main() { } else if file_paths.len() == 0 && &args[arg_index].to_lowercase() == "audio" { rip_type = RipType::AUDIO; - println!("[INFO] Not implemented"); - return; - // println!("Ripping AUDIO (MP3)"); + println!("Ripping AUDIO (MP3)"); } else { // that's a path to the file to be examined @@ -249,20 +247,20 @@ fn main() { RipType::AUDIO => { // find MP3 positions - // let mut cursor_index = 0; - // while (cursor_index as u64) < file_metadata.len() { - // match rip_mp3(&file_contents, cursor_index) { - // Some(pos) => { - // cursor_index = pos.end; - // println!("b {:?}", pos); - // positions.push(pos); - // } - // None => { - // // no MP3s were found - // break; - // } - // } - // } + let mut cursor_index = 0; + while (cursor_index as u64) < file_metadata.len() { + match rip_mp3(&file_contents, cursor_index) { + Some(pos) => { + cursor_index = pos.end; + println!("b {:?}", pos); + positions.push(pos); + } + None => { + // no MP3s were found + break; + } + } + } }