Skip to content

Commit

Permalink
Add a "disable-ffmpeg" feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Arzelier authored and Polochon-street committed Dec 24, 2023
1 parent cefd480 commit efcdd16
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 3 deletions.
13 changes: 12 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ update-aubio-bindings = ["bliss-audio-aubio-rs/bindgen"]
python-bindings = ["bliss-audio-aubio-rs/fftw3"]
# Enable the benchmarks with `cargo +nightly bench --features=bench`
bench = []
# Disable song decoding through ffmpeg - only use if you know what you
# are doing and want to decode songs yourself
disable-ffmpeg = []
library = [
"serde", "dep:rusqlite", "dep:dirs", "dep:tempdir",
"dep:anyhow", "dep:serde_ini", "dep:serde_json",
Expand Down Expand Up @@ -84,4 +87,12 @@ required-features = ["library"]

[[example]]
name = "playlist"
required-features = ["serde"]
required-features = ["serde", "ffmpeg"]

[[example]]
name = "distance"
required-features = ["ffmpeg"]

[[example]]
name = "analyze"
required-features = ["ffmpeg"]
6 changes: 6 additions & 0 deletions src/chroma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ mod test {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_chroma_desc() {
let song = Song::decode(Path::new("data/s16_mono_22_5kHz.flac")).unwrap();
let mut chroma_desc = ChromaDesc::new(SAMPLE_RATE, 12);
Expand All @@ -456,6 +457,7 @@ mod test {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_chroma_stft_decode() {
let signal = Song::decode(Path::new("data/s16_mono_22_5kHz.flac"))
.unwrap()
Expand Down Expand Up @@ -489,6 +491,7 @@ mod test {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_estimate_tuning_decode() {
let signal = Song::decode(Path::new("data/s16_mono_22_5kHz.flac"))
.unwrap()
Expand Down Expand Up @@ -606,6 +609,7 @@ mod bench {
}

#[bench]
#[cfg(not(feature = "disable-ffmpeg"))]
fn bench_chroma_desc(b: &mut Bencher) {
let song = Song::decode(Path::new("data/s16_mono_22_5kHz.flac")).unwrap();
let mut chroma_desc = ChromaDesc::new(SAMPLE_RATE, 12);
Expand All @@ -617,6 +621,7 @@ mod bench {
}

#[bench]
#[cfg(not(feature = "disable-ffmpeg"))]
fn bench_chroma_stft(b: &mut Bencher) {
let song = Song::decode(Path::new("data/s16_mono_22_5kHz.flac")).unwrap();
let mut chroma_desc = ChromaDesc::new(SAMPLE_RATE, 12);
Expand All @@ -628,6 +633,7 @@ mod bench {
}

#[bench]
#[cfg(not(feature = "disable-ffmpeg"))]
fn bench_chroma_stft_decode(b: &mut Bencher) {
let signal = Song::decode(Path::new("data/s16_mono_22_5kHz.flac"))
.unwrap()
Expand Down
4 changes: 4 additions & 0 deletions src/cue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl BlissCue {
/// Each returned [Song] has a populated [cue_info](Song::cue_info) object, that can be
/// be used to retrieve which CUE sheet was used to extract it, as well
/// as the corresponding audio file.
#[cfg(not(feature = "disable-ffmpeg"))]
pub fn songs_from_path<P: AsRef<Path>>(path: P) -> BlissResult<Vec<BlissResult<Song>>> {
let cue = BlissCue::from_path(&path)?;
let cue_files = cue.files();
Expand Down Expand Up @@ -86,6 +87,7 @@ impl BlissCue {
}

// List all BlissCueFile from a BlissCue.
#[cfg(not(feature = "disable-ffmpeg"))]
fn files(&self) -> Vec<BlissResult<BlissCueFile>> {
let mut cue_files = Vec::new();
for cue_file in self.cue.files.iter() {
Expand Down Expand Up @@ -196,6 +198,7 @@ mod tests {
use pretty_assertions::assert_eq;

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_empty_cue() {
let songs = BlissCue::songs_from_path("data/empty.cue").unwrap();
let error = songs[0].to_owned().unwrap_err();
Expand All @@ -206,6 +209,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_cue_analysis() {
let songs = BlissCue::songs_from_path("data/testcue.cue").unwrap();
let expected = vec![
Expand Down
9 changes: 9 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@
//! an example of how the [Library] struct works, and a real-life demo of bliss
//! implemented for [MPD](https://www.musicpd.org/).
//!
#![cfg_attr(
not(feature = "disable-ffmpeg"),
doc = r##"
//! # Examples
//!
//! ### Analyze & compute the distance between two songs
//!
//! ```no_run
//! use bliss_audio::{BlissResult, Song};
//!
Expand Down Expand Up @@ -62,6 +66,8 @@
//! Ok(())
//! }
//! ```
"##
)]
#![cfg_attr(feature = "bench", feature(test))]
#![warn(missing_docs)]
mod chroma;
Expand Down Expand Up @@ -152,6 +158,7 @@ pub type BlissResult<T> = Result<T, BlissError>;
/// Ok(())
/// }
/// ```
#[cfg(not(feature = "disable-ffmpeg"))]
pub fn analyze_paths<P: Into<PathBuf>, F: IntoIterator<Item = P>>(
paths: F,
) -> mpsc::IntoIter<(PathBuf, BlissResult<Song>)> {
Expand Down Expand Up @@ -199,6 +206,7 @@ pub fn analyze_paths<P: Into<PathBuf>, F: IntoIterator<Item = P>>(
/// Ok(())
/// }
/// ```
#[cfg(not(feature = "disable-ffmpeg"))]
pub fn analyze_paths_with_cores<P: Into<PathBuf>, F: IntoIterator<Item = P>>(
paths: F,
number_cores: NonZeroUsize,
Expand Down Expand Up @@ -270,6 +278,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_analyze_paths() {
let paths = vec![
"./data/s16_mono_22_5kHz.flac",
Expand Down
1 change: 1 addition & 0 deletions src/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ mod tests {
use std::path::Path;

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_loudness() {
let song = Song::decode(Path::new("data/s16_mono_22_5kHz.flac")).unwrap();
let mut loudness_desc = LoudnessDesc::default();
Expand Down
35 changes: 33 additions & 2 deletions src/song.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//! a look at Library is instead recommended.
extern crate crossbeam;
#[cfg(not(feature = "disable-ffmpeg"))]
extern crate ffmpeg_next as ffmpeg;
extern crate ndarray;

Expand All @@ -24,13 +25,21 @@ use crate::{CHANNELS, FEATURES_VERSION};
use ::log::warn;
use core::ops::Index;
use crossbeam::thread;
#[cfg(not(feature = "disable-ffmpeg"))]
use ffmpeg_next::codec::threading::{Config, Type as ThreadingType};
#[cfg(not(feature = "disable-ffmpeg"))]
use ffmpeg_next::util::channel_layout::ChannelLayout;
#[cfg(not(feature = "disable-ffmpeg"))]
use ffmpeg_next::util::error::Error;
#[cfg(not(feature = "disable-ffmpeg"))]
use ffmpeg_next::util::error::EINVAL;
#[cfg(not(feature = "disable-ffmpeg"))]
use ffmpeg_next::util::format::sample::{Sample, Type};
#[cfg(not(feature = "disable-ffmpeg"))]
use ffmpeg_next::util::frame::audio::Audio;
#[cfg(not(feature = "disable-ffmpeg"))]
use ffmpeg_next::util::log;
#[cfg(not(feature = "disable-ffmpeg"))]
use ffmpeg_next::util::log::level::Level;
use ffmpeg_next::{media, util};
use ndarray::{arr1, Array1};
Expand Down Expand Up @@ -84,6 +93,9 @@ pub struct Song {
#[derive(Debug, EnumIter, EnumCount)]
/// Indexes different fields of an [Analysis](Song::analysis).
///
#[cfg_attr(
not(feature = "disable-ffmpeg"),
doc = r##"
/// * Example:
/// ```no_run
/// use bliss_audio::{AnalysisIndex, BlissResult, Song};
Expand All @@ -94,7 +106,8 @@ pub struct Song {
/// Ok(())
/// }
/// ```
///
"##
)]
/// Prints the tempo value of an analysis.
///
/// Note that this should mostly be used for debugging / distance metric
Expand Down Expand Up @@ -296,6 +309,7 @@ impl Song {
/// The error type returned should give a hint as to whether it was a
/// decoding ([DecodingError](BlissError::DecodingError)) or an analysis
/// ([AnalysisError](BlissError::AnalysisError)) error.
#[cfg(not(feature = "disable-ffmpeg"))]
pub fn from_path<P: AsRef<Path>>(path: P) -> BlissResult<Self> {
let raw_song = Song::decode(path.as_ref())?;

Expand Down Expand Up @@ -437,6 +451,7 @@ impl Song {
.unwrap()
}

#[cfg(not(feature = "disable-ffmpeg"))]
pub(crate) fn decode(path: &Path) -> BlissResult<InternalSong> {
ffmpeg::init().map_err(|e| {
BlissError::DecodingError(format!(
Expand Down Expand Up @@ -658,6 +673,7 @@ pub(crate) struct InternalSong {
pub sample_array: Vec<f32>,
}

#[cfg(not(feature = "disable-ffmpeg"))]
fn resample_frame(
rx: Receiver<Audio>,
in_codec_format: Sample,
Expand Down Expand Up @@ -727,6 +743,7 @@ fn resample_frame(
Ok(sample_array)
}

#[cfg(not(feature = "disable-ffmpeg"))]
fn push_to_sample_array(frame: &ffmpeg::frame::Audio, sample_array: &mut Vec<f32>) {
if frame.samples() == 0 {
return;
Expand Down Expand Up @@ -772,6 +789,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_analyze() {
let song = Song::from_path(Path::new("data/s16_mono_22_5kHz.flac")).unwrap();
let expected_analysis = vec![
Expand Down Expand Up @@ -802,6 +820,7 @@ mod tests {
assert_eq!(FEATURES_VERSION, song.features_version);
}

#[cfg(not(feature = "disable-ffmpeg"))]
fn _test_decode(path: &Path, expected_hash: &[u8]) {
let song = Song::decode(path).unwrap();
let mut hasher = Ripemd160::new();
Expand All @@ -813,6 +832,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_tags() {
let song = Song::decode(Path::new("data/s16_mono_22_5kHz.flac")).unwrap();
assert_eq!(song.artist, Some(String::from("David TMX")));
Expand All @@ -830,6 +850,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_empty_tags() {
let song = Song::decode(Path::new("data/no_tags.flac")).unwrap();
assert_eq!(song.artist, None);
Expand All @@ -840,6 +861,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_resample_multi() {
let path = Path::new("data/s32_stereo_44_1_kHz.flac");
let expected_hash = [
Expand All @@ -850,6 +872,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_resample_stereo() {
let path = Path::new("data/s16_stereo_22_5kHz.flac");
let expected_hash = [
Expand All @@ -860,6 +883,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_decode_mono() {
let path = Path::new("data/s16_mono_22_5kHz.flac");
// Obtained through
Expand All @@ -873,6 +897,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_decode_mp3() {
let path = Path::new("data/s32_stereo_44_1_kHz.mp3");
// Obtained through
Expand All @@ -886,12 +911,14 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_dont_panic_no_channel_layout() {
let path = Path::new("data/no_channel.wav");
Song::decode(&path).unwrap();
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_decode_right_capacity_vec() {
let path = Path::new("data/s16_mono_22_5kHz.flac");
let song = Song::decode(&path).unwrap();
Expand Down Expand Up @@ -945,6 +972,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_decode_errors() {
assert_eq!(
Song::decode(Path::new("nonexistent")).unwrap_err(),
Expand All @@ -961,13 +989,15 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_index_analysis() {
let song = Song::from_path("data/s16_mono_22_5kHz.flac").unwrap();
assert_eq!(song.analysis[AnalysisIndex::Tempo], 0.3846389);
assert_eq!(song.analysis[AnalysisIndex::Chroma10], -0.95968974);
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_decode_wav() {
let expected_hash = [
0xf0, 0xe0, 0x85, 0x4e, 0xf6, 0x53, 0x76, 0xfa, 0x7a, 0xa5, 0x65, 0x76, 0xf9, 0xe1,
Expand All @@ -977,6 +1007,7 @@ mod tests {
}

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_debug_analysis() {
let song = Song::from_path("data/s16_mono_22_5kHz.flac").unwrap();
assert_eq!(
Expand Down Expand Up @@ -1097,7 +1128,7 @@ mod tests {
}
}

#[cfg(all(feature = "bench", test))]
#[cfg(all(feature = "bench", not(feature = "disable-ffmpeg"), test))]
mod bench {
extern crate test;
use crate::Song;
Expand Down
1 change: 1 addition & 0 deletions src/temporal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ mod tests {
use std::path::Path;

#[test]
#[cfg(not(feature = "disable-ffmpeg"))]
fn test_tempo_real() {
let song = Song::decode(Path::new("data/s16_mono_22_5kHz.flac")).unwrap();
let mut tempo_desc = BPMDesc::new(SAMPLE_RATE).unwrap();
Expand Down
Loading

0 comments on commit efcdd16

Please sign in to comment.