Giter Club home page Giter Club logo

Comments (8)

Polochon-street avatar Polochon-street commented on June 18, 2024

Well, yes, « calm » or « loud » filters are useful for the end user, but then the entire user's library would need to be analyzed, could you do that with rhythmbox?

I thought it would be easier to have python bindings used to compute distance between songs, so that your rhythmbox plugin would just play similiar songs, and there would be no need to analyze the entire user's library?

(But I may be missing the point here, maybe @Phyks could help?)

from bliss.

fossfreedom avatar fossfreedom commented on June 18, 2024

ok - maybe i'm missing the logic ... so please help me :)

the current bliss library provides function call(s) to calculate tempo, amplitude, frequency rating, attack for one specific song

So what rhythmbox will need to do is loop through every song in the library and for each song create a bliss.bl_song(song_filename). Then get each value (tempo etc) and save those values in a "database" of some-sort.

What I'm looking for is to start at a specific song and find the next closest/similar song - so the plugin will need to manipulate the values stored in the "database" above to find the similar song.

What I thought lele's "analyze" did was to calculate "calm" or "loud" for a given song - those calculations for a song looks fairly complex and I admit I dont fully understand how "calm" or "loud" is calculated from the individual tempo/amplitude/frequency/rating figures if we had to do the same thing in python using "bliss.bl_song".

So if instead I could call "analyze" for each song and it returns "calm" or "loud" then I can store "calm" or "loud" for each song in the rhythmbox "database" - it would be very-very simple then just to find the next "calm" or "loud" song.

from bliss.

Polochon-street avatar Polochon-street commented on June 18, 2024

I think I get it - you want to store a figure that would represent how « loud » or « calm » are each song, and then, when starting at a specific song, go to the next closest song by looking for the closest calm/loud figure?

You could get such a figure here , but you would misuse the lib (well, at least not use it to its full potential).

If you want to compute the similiarity of two songs, you could use bl_cosine_similarity(file1, file2, vector1, vector2) that returns a value between -1 and 1 (1 being the closest possible (= same songs) and -1 the total opposite).
You could use this function « on-the-go » (like I do in leleleplayer, while(similarity > 0.5) { iterate_through_songs; }), or, as you said, you could store a « database » of the quadruplet { amplitude, frequencies, tempo, attack } for each song and perform directly the similarity computation on this database, sparing you the task of re-analyzing some of the songs each time you want to find similar songs.

TL;DR:

  • use bl_cosine_similarity(file1, file2, ... ) to compute similarity between two audio files (used for on-the-go playing)
  • bl_analyze(file, ...) to store analyzed results in some database
  • If a song is calm, bl_analyze() returns BL_CALM, if its loud, BL_LOUD

Hope I've been clear enough and didn't miss the point, and don't hesitate to ask more questions! :)

from bliss.

fossfreedom avatar fossfreedom commented on June 18, 2024

ok - ta. The explanation above about bl_cosine_similarity is just what I needed - think the doc strings for each function needs to be beefed up as you have described.

Maybe I'm thinking too far ahead - I'm thinking playlists - showing all possible songs that are similar to the chosen song. To get such a playlist I need to call bl_cosine_similarity for every song in the library - that will obviously take quite a bit of time for a large collection.

The various functions take filenames of the audiofiles themselves. I presume this is to calculate the bl_song struct values. How efficient is this process in terms of computing power/time?

Is it more efficient to store the struct values and have an API similar to bl_cosine_similarity that you can call with the structs themselves so that the library doesnt have to re-analyze the audiofile?

BTW - I see a "distance(filename1, filename2)" function by I don't see a bl_analyze() function nor a direct method on the bl_song object (just a bl_song.analyze(filename) method)

from bliss.

Phyks avatar Phyks commented on June 18, 2024

Yes, docstrings are what they are, and doc may not be optimal. This is really one of the first version :) I think you can PR if you can enhance that :)

Computing and indexing raw results for every song is what leleleplayer do, I think, at first import (@Polochon-street can confirm this). First import is quite long, but doable, even for a large collection (less than an hour on my 80GB if I remember correctly).

Actually, I see two use cases:

  • You play random songs, you just want to skip songs which are not similar enough, and this is done with bl_cosine_similarity (bl_distance does the same, but bl_cosine_similarity is expected to give better results).

  • You want to form "similar" playlists, in which case you have no other choice than to compute the so called force_vector on every song (hence using bl_analyze on every song and putting this in a library).

    My bindings are only here to expose the C API of the underlying lib.

In https://github.com/Polochon-street/bliss/blob/master/python/bliss/distance.py you have the distance functions. In https://github.com/Polochon-street/bliss/blob/master/python/bliss/bl_song.py you have the bl_song object (Python mapping and wrapper around the C struct) definition. You can access any field of the underlying C struct by using it as a dict, and you can analyze directly a song using the filename argument of the constructor. See https://github.com/Polochon-street/bliss/tree/master/python/test for some (basic) examples.

from bliss.

fossfreedom avatar fossfreedom commented on June 18, 2024

thanks - understood - except for the "force_vector" part - I don't really understand the typeof("struct force_vector") statements in the python-bindings and how you would invoke this from python.

Would do a PR ... if I fully understood the return values as @Polochon-street as eloquently described for the cosine function.

My last query is just wondering if we can avoid re-analyzing a song since it has been scanned already on startup and we've stored the bl_song values. Probably needs more C API calls that then subsequently needs a python binding or two.

from bliss.

Polochon-street avatar Polochon-street commented on June 18, 2024

I agree with everything @Phyks wrote, but I also agree that a function that computes the distance between two struct songs (and not re-analyzes files) is needed, so I wrote it (and tried not to break your bindings @Phyks :p).

So, yes, if you want to form « similiar » playlists, what you have to do is what @Phyks said: compute the force_vector with bl_analyze(), and then use the bl_cosine_distance() I wrote two minutes ago that doesn't need filenames as arguments, just struct force_vector_s (well, the quadruplet of value that you will have stored).

from bliss.

Phyks avatar Phyks commented on June 18, 2024

@fossfreedom force_vector is a C struct mapping with fields "attack", "tempo", "frequency" and "amplitude" corresponding to four different scores for the song. I should certainly map it also to a Python dict, which will be more Pythonic. Will do it in my next PR.

👍 for the function to avoid reanalyzing the file. Will map them also.

@Polochon-street ok, I double check it and PR if needed with the rest of the issues tomorrow.

from bliss.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.