Remove path and duration from the decoded song

This commit is contained in:
Anton Liaposhchenko 2024-02-16 17:09:20 +02:00
parent 719f6baaa4
commit f446e4ade7

View File

@ -33,11 +33,9 @@ use ndarray::{arr1, Array1};
use std::convert::TryInto;
use std::fmt;
use std::path::Path;
use std::path::PathBuf;
use std::sync::mpsc;
use std::sync::mpsc::Receiver;
use std::thread as std_thread;
use std::time::Duration;
use strum::{EnumCount, IntoEnumIterator};
use strum_macros::{EnumCount, EnumIter};
@ -46,12 +44,8 @@ use strum_macros::{EnumCount, EnumIter};
/// Simple object used to represent a Song, with its path, analysis, and
/// other metadata (artist, genre...)
pub struct Song {
/// Song's provided file path
pub path: PathBuf,
/// bliss analysis results
pub analysis: Analysis,
/// The song's duration
pub duration: Duration,
/// Version of the features the song was analyzed with.
/// A simple integer that is bumped every time a breaking change
/// is introduced in the features.
@ -215,12 +209,10 @@ impl Song {
/// decoding ([DecodingError](BlissError::DecodingError)) or an analysis
/// ([AnalysisError](BlissError::AnalysisError)) error.
pub fn from_path<P: AsRef<Path>>(path: P) -> BlissResult<Self> {
let raw_song = Song::decode(path.as_ref())?;
let samples = Song::decode(path.as_ref())?;
Ok(Song {
path: raw_song.path,
duration: raw_song.duration,
analysis: Song::analyze(&raw_song.sample_array)?,
analysis: Song::analyze(&samples)?,
features_version: FEATURES_VERSION,
})
}
@ -348,7 +340,7 @@ impl Song {
.unwrap()
}
pub(crate) fn decode(path: &Path) -> BlissResult<InternalSong> {
pub(crate) fn decode(path: &Path) -> BlissResult<Vec<f32>> {
ffmpeg::init().map_err(|e| {
BlissError::DecodingError(format!(
"ffmpeg init error while decoding file '{}': {:?}.",
@ -357,10 +349,7 @@ impl Song {
))
})?;
log::set_level(Level::Quiet);
let mut song = InternalSong {
path: path.into(),
..Default::default()
};
let mut ictx = ffmpeg::format::input(&path).map_err(|e| {
BlissError::DecodingError(format!(
"while opening format for file '{}': {:?}.",
@ -451,8 +440,7 @@ impl Song {
path.display()
);
drop(tx);
song.sample_array = child.join().unwrap()?;
return Ok(song);
return Ok(child.join().unwrap()?);
}
Err(e) => warn!("error while decoding file '{}': {}", path.display(), e),
};
@ -490,8 +478,7 @@ impl Song {
path.display()
);
drop(tx);
song.sample_array = child.join().unwrap()?;
return Ok(song);
return Ok(child.join().unwrap()?);
}
Err(e) => warn!("error while decoding {}: {}", path.display(), e),
};
@ -513,20 +500,10 @@ impl Song {
}
drop(tx);
song.sample_array = child.join().unwrap()?;
let duration_seconds = song.sample_array.len() as f32 / SAMPLE_RATE as f32;
song.duration = Duration::from_nanos((duration_seconds * 1e9_f32).round() as u64);
Ok(song)
Ok(child.join().unwrap()?)
}
}
#[derive(Default, Debug)]
pub(crate) struct InternalSong {
pub path: PathBuf,
pub duration: Duration,
pub sample_array: Vec<f32>,
}
fn resample_frame(
rx: Receiver<Audio>,
in_codec_format: Sample,
@ -672,9 +649,9 @@ mod tests {
}
fn _test_decode(path: &Path, expected_hash: &[u8]) {
let song = Song::decode(path).unwrap();
let samples = Song::decode(path).unwrap();
let mut hasher = Ripemd160::new();
for sample in song.sample_array.iter() {
for sample in samples.iter() {
hasher.update(sample.to_le_bytes().to_vec());
}
@ -736,26 +713,23 @@ mod tests {
#[test]
fn test_decode_right_capacity_vec() {
let path = Path::new("data/s16_mono_22_5kHz.flac");
let song = Song::decode(&path).unwrap();
let sample_array = song.sample_array;
let samples = Song::decode(&path).unwrap();
assert_eq!(
sample_array.len() + SAMPLE_RATE as usize,
sample_array.capacity()
samples.len() + SAMPLE_RATE as usize,
samples.capacity()
);
let path = Path::new("data/s32_stereo_44_1_kHz.flac");
let song = Song::decode(&path).unwrap();
let sample_array = song.sample_array;
let samples = Song::decode(&path).unwrap();
assert_eq!(
sample_array.len() + SAMPLE_RATE as usize,
sample_array.capacity()
samples.len() + SAMPLE_RATE as usize,
samples.capacity()
);
let path = Path::new("data/capacity_fix.ogg");
let song = Song::decode(&path).unwrap();
let sample_array = song.sample_array;
assert!(sample_array.len() as f32 / sample_array.capacity() as f32 > 0.90);
assert!(sample_array.len() as f32 / (sample_array.capacity() as f32) < 1.);
let samples = Song::decode(&path).unwrap();
assert!(samples.len() as f32 / samples.capacity() as f32 > 0.90);
assert!(samples.len() as f32 / (samples.capacity() as f32) < 1.);
}
#[test]