diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f1c466..ee60017 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## blissify 0.3.11 +* Bump bliss version + ## blissify 0.3.10 * Fix compilation for non-linux OSes diff --git a/Cargo.lock b/Cargo.lock index 507c907..1db5a51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,22 +69,22 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bindgen" -version = "0.64.0" +version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "cexpr", "clang-sys", + "itertools", "lazy_static", "lazycell", - "peeking_take_while", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -95,20 +95,19 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bliss-audio" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7554b018920fa4216ee13d67e5dbc9a1ac2fc745e22001e38f8d30d81bea33" +version = "0.7.0" dependencies = [ "adler32", "anyhow", "bliss-audio-aubio-rs", "dirs 5.0.1", + "extended-isolation-forest", "ffmpeg-next", "ffmpeg-sys-next", "indicatif 0.17.7", @@ -130,25 +129,25 @@ dependencies = [ [[package]] name = "bliss-audio-aubio-rs" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb6b0b33b16bdb7489951c56294f4f9c321d91047ae29aebb91dfcd84a09086f" +checksum = "2bfb72ae2d8bdd563b7218c6f6f423c17350052d8a9f69a8fc018220537fa1bf" dependencies = [ "bliss-audio-aubio-sys", ] [[package]] name = "bliss-audio-aubio-sys" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd4d47e7b82164c30a806717cf5562f87e5b136b79b3d942c9ad789134116f2f" +checksum = "3a5b978c743f6450be98229b052d996ed1cc0507274e9c68a7effeb51e8a13ec" dependencies = [ "cc", ] [[package]] name = "blissify" -version = "0.3.10" +version = "0.3.11" dependencies = [ "anyhow", "bliss-audio", @@ -338,6 +337,18 @@ dependencies = [ "termcolor", ] +[[package]] +name = "extended-isolation-forest" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db5193a74618ae2f7ea9c7feda2772192e0e3c04d9cbd2beb5ee9b0916d7eb3f" +dependencies = [ + "num-traits", + "rand 0.8.5", + "rand_distr", + "serde", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -352,20 +363,20 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "ffmpeg-next" -version = "6.1.1" +version = "7.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e72c72e8dcf638fb0fb03f033a954691662b5dabeaa3f85a6607d101569fccd" +checksum = "a681d69bf41d1c9edc7c6a2b09b69d0b96e9b916d200b7ec5b10de61f559eb31" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "ffmpeg-sys-next", "libc", ] [[package]] name = "ffmpeg-sys-next" -version = "6.1.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2529ad916d08c3562c754c21bc9b17a26c7882c0f5706cc2cd69472175f1620" +checksum = "972a460dd8e901b737ce0482bf71a837e1751e3dd7c8f8b0a4ead808e7f174a5" dependencies = [ "bindgen", "cc", @@ -546,13 +557,19 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libredox" version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.5.0", "libc", "redox_syscall 0.4.1", ] @@ -680,6 +697,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -716,12 +734,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "pkg-config" version = "0.3.28" @@ -835,6 +847,16 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + [[package]] name = "rawpointer" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index 746467f..8ca7db3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "blissify" -version = "0.3.10" +version = "0.3.11" authors = ["Polochon-street "] edition = "2021" license = "GPL-3.0-only" @@ -17,7 +17,7 @@ default = ["bliss-audio/library"] rpi = ["bliss-audio/rpi"] [dependencies] -bliss-audio = "0.6.11" +bliss-audio = "0.7.0" mpd = "0.0.12" dirs = "3.0.1" tempdir = "0.3.7" diff --git a/src/main.rs b/src/main.rs index 15e9807..8d4f317 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,10 +9,9 @@ use anyhow::{bail, Context, Result}; use bliss_audio::library::{AppConfigTrait, BaseConfig, Library, LibrarySong}; use bliss_audio::playlist::{ - closest_to_first_song_by_key, cosine_distance, euclidean_distance, song_to_song_by_key, - DistanceMetric, + closest_to_songs, cosine_distance, euclidean_distance, song_to_song, DistanceMetricBuilder, }; -use bliss_audio::{BlissError, BlissResult, Song}; +use bliss_audio::{BlissError, BlissResult}; use clap::{App, Arg, ArgMatches, SubCommand}; #[cfg(not(test))] use log::warn; @@ -39,11 +38,13 @@ use std::{io::Read, os::unix::net::UnixStream}; use termion::input::TermRead; use termion::raw::IntoRawMode; +use bliss_audio::decoder::ffmpeg::FFmpeg as Decoder; + /// The main struct that stores both the Library object, and some other /// helper functions to make everything work properly. struct MPDLibrary { // A library object, containing database-related objects. - pub library: Library, + pub library: Library, /// A connection to the MPD server, used for retrieving song's paths, /// currently played songs, and queue tracks. #[cfg(not(test))] @@ -334,16 +335,15 @@ impl MPDLibrary { Ok(()) } - fn queue_from_current_song_custom( + fn queue_from_current_song_custom( &self, number_songs: usize, - distance: G, - sort_by: F, + distance: &dyn DistanceMetricBuilder, + mut sort_by: F, dedup: bool, ) -> Result<()> where - F: FnMut(&LibrarySong<()>, &mut Vec>, G, fn(&LibrarySong<()>) -> Song), - G: DistanceMetric + Copy, + F: FnMut(&[LibrarySong<()>], &mut [LibrarySong<()>], &dyn DistanceMetricBuilder), { let mut mpd_conn = self.mpd_conn.lock().unwrap(); mpd_conn.random(false)?; @@ -354,10 +354,10 @@ impl MPDLibrary { let path = self.mpd_to_bliss_path(&mpd_song)?; let playlist = self.library.playlist_from_custom( - &path.to_string_lossy().clone(), + &[&path.to_string_lossy().clone()], number_songs, distance, - sort_by, + &mut sort_by, dedup, )?; let current_pos = mpd_song.place.unwrap().pos; @@ -500,8 +500,12 @@ impl MPDLibrary { .join("\n") ); } - songs - .sort_by_cached_key(|song| n32(current_song.bliss_song.distance(&song.bliss_song))); + songs.sort_by_cached_key(|song| { + n32(euclidean_distance( + ¤t_song.bliss_song.analysis.as_arr1(), + &song.bliss_song.analysis.as_arr1(), + )) + }); // TODO put a proper dedup here //dedup_playlist(&mut songs, None); for (i, song) in songs[1..number_choices + 1].iter().enumerate() { @@ -783,20 +787,20 @@ fn main() -> Result<()> { }; let sort = match sub_m.is_present("seed") { - false => closest_to_first_song_by_key, - true => song_to_song_by_key, + false => closest_to_songs, + true => song_to_song, }; if sub_m.is_present("dedup") { library.queue_from_current_song_custom( number_songs, - distance_metric, + &distance_metric, sort, true, )?; } else { library.queue_from_current_song_custom( number_songs, - distance_metric, + &distance_metric, sort, false, )?; @@ -818,7 +822,7 @@ fn main() -> Result<()> { #[cfg(test)] mod test { use super::*; - use bliss_audio::Analysis; + use bliss_audio::{Analysis, Song}; use mpd::error::Result; use mpd::song::{Id, QueuePlace, Song as MPDSong}; use pretty_assertions::assert_eq; @@ -992,7 +996,7 @@ mod test { .unwrap(); } assert_eq!( - library.queue_from_current_song_custom(20, euclidean_distance, closest_to_first_song_by_key, true).unwrap_err().to_string(), + library.queue_from_current_song_custom(20, &euclidean_distance, closest_to_songs, true).unwrap_err().to_string(), String::from("No song is currently playing. Add a song to start the playlist from, and try again."), ); } @@ -1031,8 +1035,8 @@ mod test { library .queue_from_current_song_custom( 20, - euclidean_distance, - closest_to_first_song_by_key, + &euclidean_distance, + closest_to_songs, true ) .unwrap_err() @@ -1155,12 +1159,7 @@ mod test { .unwrap(); } library - .queue_from_current_song_custom( - 20, - euclidean_distance, - closest_to_first_song_by_key, - false, - ) + .queue_from_current_song_custom(20, &euclidean_distance, closest_to_songs, false) .unwrap(); let playlist = library