Remove path and duration from the decoded song
This commit is contained in:
parent
719f6baaa4
commit
f446e4ade7
62
src/song.rs
62
src/song.rs
|
@ -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]
|
||||
|
|
Loading…
Reference in New Issue
Block a user