Merge pull request #31 from sagudev/main

This commit is contained in:
Alex 2022-01-24 09:11:45 -05:00 committed by GitHub
commit b4d56ab841
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 88 additions and 8 deletions

View file

@ -36,6 +36,7 @@ fn main() {
properties.overall_bitrate().unwrap_or(0)
);
println!("Sample Rate: {}", properties.sample_rate().unwrap_or(0));
println!("Bit depth: {}", properties.bit_depth().unwrap_or(0));
println!("Channels: {}", properties.channels().unwrap_or(0));
println!("Duration: {}", duration_display);
}

View file

@ -15,6 +15,7 @@ pub struct ApeProperties {
overall_bitrate: u32,
audio_bitrate: u32,
sample_rate: u32,
bit_depth: u8,
channels: u8,
}
@ -25,6 +26,7 @@ impl From<ApeProperties> for FileProperties {
overall_bitrate: Some(input.overall_bitrate),
audio_bitrate: Some(input.audio_bitrate),
sample_rate: Some(input.sample_rate),
bit_depth: Some(input.bit_depth),
channels: Some(input.channels),
}
}
@ -38,6 +40,7 @@ impl ApeProperties {
overall_bitrate: u32,
audio_bitrate: u32,
sample_rate: u32,
bit_depth: u8,
channels: u8,
) -> Self {
Self {
@ -46,6 +49,7 @@ impl ApeProperties {
overall_bitrate,
audio_bitrate,
sample_rate,
bit_depth,
channels,
}
}
@ -70,6 +74,11 @@ impl ApeProperties {
self.sample_rate
}
/// Bits per sample
pub fn bit_depth(&self) -> u8 {
self.bit_depth
}
/// Channel count
pub fn channels(&self) -> u8 {
self.channels
@ -146,8 +155,7 @@ where
return Err(LoftyError::Ape("File contains no frames"));
}
// Unused
let _bits_per_sample = header_read.read_u16::<LittleEndian>()?;
let bits_per_sample = header_read.read_u16::<LittleEndian>()?;
let channels = header_read.read_u16::<LittleEndian>()?;
@ -174,6 +182,7 @@ where
overall_bitrate,
audio_bitrate,
sample_rate,
bit_depth: bits_per_sample as u8,
channels: channels as u8,
})
}
@ -202,8 +211,15 @@ where
let compression_level = header_first.read_u16::<LittleEndian>()?;
// Unused
let _format_flags = header_first.read_u16::<LittleEndian>()?;
let format_flags = header_first.read_u16::<LittleEndian>()?;
// https://github.com/fernandotcl/monkeys-audio/blob/5fe956c7e67c13daa80518a4cc7001e9fa185297/src/MACLib/MACLib.h#L74
let bit_depth = if (format_flags & 0b1) == 1 {
8
} else if (format_flags & 0b100) == 4 {
24
} else {
16
};
let blocks_per_frame = match version {
_ if version >= 3950 => 73728 * 4,
@ -245,6 +261,7 @@ where
overall_bitrate,
audio_bitrate,
sample_rate,
bit_depth,
channels: channels as u8,
})
}

View file

@ -18,7 +18,7 @@ pub(super) fn read_properties(
}
let sample_frames = comm.read_u32::<BigEndian>()?;
let _sample_size = comm.read_u16::<BigEndian>()?;
let sample_size = comm.read_u16::<BigEndian>()?;
let mut sample_rate_bytes = [0; 10];
comm.read_exact(&mut sample_rate_bytes)?;
@ -66,6 +66,7 @@ pub(super) fn read_properties(
overall_bitrate,
audio_bitrate,
sample_rate: Some(sample_rate),
bit_depth: Some(sample_size as u8),
channels: Some(channels),
})
}

View file

@ -32,6 +32,7 @@ pub struct WavProperties {
overall_bitrate: u32,
audio_bitrate: u32,
sample_rate: u32,
bit_depth: u8,
channels: u8,
}
@ -42,6 +43,7 @@ impl From<WavProperties> for FileProperties {
overall_bitrate: Some(input.overall_bitrate),
audio_bitrate: Some(input.audio_bitrate),
sample_rate: Some(input.sample_rate),
bit_depth: Some(input.bit_depth),
channels: Some(input.channels),
}
}
@ -55,6 +57,7 @@ impl WavProperties {
overall_bitrate: u32,
audio_bitrate: u32,
sample_rate: u32,
bit_depth: u8,
channels: u8,
) -> Self {
Self {
@ -63,6 +66,7 @@ impl WavProperties {
overall_bitrate,
audio_bitrate,
sample_rate,
bit_depth,
channels,
}
}
@ -87,6 +91,11 @@ impl WavProperties {
self.sample_rate
}
/// Bits per sample
pub fn bit_depth(&self) -> u8 {
self.bit_depth
}
/// Channel count
pub fn channels(&self) -> u8 {
self.channels
@ -186,6 +195,7 @@ pub(super) fn read_properties(
overall_bitrate,
audio_bitrate,
sample_rate,
bit_depth: bits_per_sample as u8,
channels,
})
}

View file

@ -23,6 +23,7 @@ impl From<Mp3Properties> for FileProperties {
overall_bitrate: Some(input.overall_bitrate),
audio_bitrate: Some(input.audio_bitrate),
sample_rate: Some(input.sample_rate),
bit_depth: None,
channels: Some(input.channels),
}
}

View file

@ -32,6 +32,7 @@ pub struct Mp4Properties {
overall_bitrate: u32,
audio_bitrate: u32,
sample_rate: u32,
bit_depth: Option<u8>,
channels: u8,
}
@ -42,6 +43,7 @@ impl From<Mp4Properties> for FileProperties {
overall_bitrate: Some(input.overall_bitrate),
audio_bitrate: Some(input.audio_bitrate),
sample_rate: Some(input.sample_rate),
bit_depth: input.bit_depth,
channels: Some(input.channels),
}
}
@ -55,6 +57,7 @@ impl Mp4Properties {
overall_bitrate: u32,
audio_bitrate: u32,
sample_rate: u32,
bit_depth: Option<u8>,
channels: u8,
) -> Self {
Self {
@ -63,6 +66,7 @@ impl Mp4Properties {
overall_bitrate,
audio_bitrate,
sample_rate,
bit_depth,
channels,
}
}
@ -87,6 +91,11 @@ impl Mp4Properties {
self.sample_rate
}
/// Bits per sample
pub fn bit_depth(&self) -> Option<u8> {
self.bit_depth
}
/// Channel count
pub fn channels(&self) -> u8 {
self.channels
@ -200,6 +209,7 @@ where
overall_bitrate: 0,
audio_bitrate: 0,
sample_rate: 0,
bit_depth: None,
channels: 0,
};
@ -335,15 +345,20 @@ where
if alac.ident == AtomIdent::Fourcc(*b"alac") {
properties.codec = Mp4Codec::ALAC;
// Skipping 13 bytes
// Skipping 9 bytes
// Version (4)
// Samples per frame (4)
// Compatible version (1)
data.seek(SeekFrom::Current(9))?;
// Sample size (1)
properties.bit_depth = Some(data.read_u8()?);
// Skipping 3 bytes
// Rice history mult (1)
// Rice initial history (1)
// Rice parameter limit (1)
data.seek(SeekFrom::Current(13))?;
data.seek(SeekFrom::Current(3))?;
properties.channels = data.read_u8()?;

View file

@ -32,6 +32,7 @@ where
let info = stream_info.read_u32::<BigEndian>()?;
let sample_rate = info >> 12;
let bits_per_sample = ((info >> 4) & 0b11111) + 1;
let channels = ((info >> 9) & 7) + 1;
// Read the remaining 32 bits of the total samples
@ -54,6 +55,7 @@ where
overall_bitrate,
audio_bitrate,
sample_rate: Some(sample_rate as u32),
bit_depth: Some(bits_per_sample as u8),
channels: Some(channels as u8),
})
}

View file

@ -26,6 +26,7 @@ impl From<OpusProperties> for FileProperties {
overall_bitrate: Some(input.overall_bitrate),
audio_bitrate: Some(input.audio_bitrate),
sample_rate: Some(input.input_sample_rate),
bit_depth: None,
channels: Some(input.channels),
}
}

View file

@ -29,6 +29,7 @@ impl From<VorbisProperties> for FileProperties {
overall_bitrate: Some(input.overall_bitrate),
audio_bitrate: Some(input.audio_bitrate),
sample_rate: Some(input.sample_rate),
bit_depth: None,
channels: Some(input.channels),
}
}

View file

@ -7,6 +7,7 @@ pub struct FileProperties {
pub(crate) overall_bitrate: Option<u32>,
pub(crate) audio_bitrate: Option<u32>,
pub(crate) sample_rate: Option<u32>,
pub(crate) bit_depth: Option<u8>,
pub(crate) channels: Option<u8>,
}
@ -17,6 +18,7 @@ impl Default for FileProperties {
overall_bitrate: None,
audio_bitrate: None,
sample_rate: None,
bit_depth: None,
channels: None,
}
}
@ -29,6 +31,7 @@ impl FileProperties {
overall_bitrate: Option<u32>,
audio_bitrate: Option<u32>,
sample_rate: Option<u32>,
bit_depth: Option<u8>,
channels: Option<u8>,
) -> Self {
Self {
@ -36,6 +39,7 @@ impl FileProperties {
overall_bitrate,
audio_bitrate,
sample_rate,
bit_depth,
channels,
}
}
@ -60,6 +64,11 @@ impl FileProperties {
self.sample_rate
}
/// Bits per sample (usually 16 or 24 bit)
pub fn bit_depth(&self) -> Option<u8> {
self.bit_depth
}
/// Channel count
pub fn channels(&self) -> Option<u8> {
self.channels

BIN
tests/files/assets/b.m4a Normal file

Binary file not shown.

View file

@ -13,17 +13,19 @@ const AIFF_PROPERTIES: FileProperties = FileProperties::new(
Some(1542),
Some(1536),
Some(48000),
Some(16),
Some(2),
);
const APE_PROPERTIES: ApeProperties =
ApeProperties::new(3990, Duration::from_millis(1428), 360, 360, 48000, 2);
ApeProperties::new(3990, Duration::from_millis(1428), 360, 360, 48000, 16, 2);
const FLAC_PROPERTIES: FileProperties = FileProperties::new(
Duration::from_millis(1428),
Some(321),
Some(275),
Some(48000),
Some(16),
Some(2),
);
@ -44,6 +46,17 @@ const MP4_PROPERTIES: Mp4Properties = Mp4Properties::new(
135,
124,
48000,
None,
2,
);
const ALAC_PROPERTIES: Mp4Properties = Mp4Properties::new(
Mp4Codec::ALAC,
Duration::from_millis(1428),
331,
124,
48000,
Some(16),
2,
);
@ -68,6 +81,7 @@ const WAV_PROPERTIES: WavProperties = WavProperties::new(
1542,
1536,
48000,
16,
2,
);
@ -123,6 +137,14 @@ fn mp4_properties() {
)
}
#[test]
fn alac_properties() {
assert_eq!(
get_properties::<Mp4File>("tests/files/assets/b.m4a").bit_depth(),
ALAC_PROPERTIES.bit_depth()
)
}
#[test]
fn opus_properties() {
assert_eq!(