A song analysis library for making playlists
Find a file
Polochon-street a3fcccbf2a
Merge pull request #21 from Polochon-street/fix-path-to-path-speed
Make the song-to-song method faster
2021-08-23 18:32:04 +02:00
.github/workflows Fix speed of "song to song" sorting method 2021-08-23 18:16:32 +02:00
data Some review comments 2021-06-15 19:34:17 +02:00
examples Some review comments 2021-06-15 19:34:17 +02:00
src Fix speed of "song to song" sorting method 2021-08-23 18:16:32 +02:00
.gitmodules Vendor aubio-rs pt.2 2021-05-16 14:47:42 +02:00
Cargo.lock Fix speed of "song to song" sorting method 2021-08-23 18:16:32 +02:00
Cargo.toml Add custom sorting for playlists 2021-07-28 22:10:32 +02:00
CHANGELOG.md Fix speed of "song to song" sorting method 2021-08-23 18:16:32 +02:00
README.md Merge pull request #19 from Polochon-street/bump-ffmpeg 2021-07-10 23:03:28 +02:00

crate build doc

bliss music analyser - Rust version

bliss-rs is the Rust improvement of bliss, a library used to make playlists by analyzing songs, and computing distance between them.

Like bliss, it eases the creation of « intelligent » playlists and/or continuous play, à la Spotify/Grooveshark Radio, as well as easing creating plug-ins for existing audio players. For instance, you can use it to make calm playlists to help you sleeping, fast playlists to get you started during the day, etc.

For now (and if you're looking for an easy-to use smooth play experience), blissify implements bliss for MPD.

There are also python bindings.

Note 1: the features bliss-rs outputs is not compatible with the ones used by C-bliss, since it uses different, more accurate values, based on actual literature. It is also faster.

Examples

For simple analysis / distance computing, a look at examples/distance.rs and examples/analyse.rs.

Ready to use examples:

Compute the distance between two songs

use bliss_audio::{BlissError, Song};

fn main() -> Result<(), BlissError> {
    let song1 = Song::new("/path/to/song1")?;
    let song2 = Song::new("/path/to/song2")?;
        
    println!("Distance between song1 and song2 is {}", song1.distance(&song2));
    Ok(())
}

Make a playlist from a song

use bliss_audio::{BlissError, Song};
use noisy_float::prelude::n32;

fn main() -> Result<(), BlissError> {
    let paths = vec!["/path/to/song1", "/path/to/song2", "/path/to/song3"];
    let mut songs: Vec<Song> = paths
        .iter()
        .map(|path| Song::new(path))
        .collect::<Result<Vec<Song>, BlissError>>()?;

    // Assuming there is a first song
    let first_song = songs.first().unwrap().to_owned();

    songs.sort_by_cached_key(|song| n32(first_song.distance(&song)));
    println!(
        "Playlist is: {:?}",
        songs
            .iter()
            .map(|song| &song.path)
            .collect::<Vec<&String>>()
    );
    Ok(())
}

Further use

Instead of reinventing ways to fetch a user library, play songs, etc, and embed that into bliss, it is easier to look at the Library trait.

By implementing a few functions to get songs from a media library, and store the resulting analysis, you get access to functions to analyze an entire library (with multithreading), and to make playlists easily.

See blissify for a reference implementation.

Acknowledgements

  • This library relies heavily on aubio's Rust bindings for the spectral / timbral analysis, so a big thanks to both the creators and contributors of librosa, and to @katyo for making aubio bindings for Rust.
  • The first part of the chroma extraction is basically a rewrite of librosa's chroma feature extraction from python to Rust, with just as little features as needed. Thanks to both creators and contributors as well.
  • Finally, a big thanks to Christof Weiss for pointing me in the right direction for the chroma feature summarization, which are basically also a rewrite from Python to Rust of some of the awesome notebooks by AudioLabs Erlangen, that you can find here.