Comments (8)
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.
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.
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.
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.
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, butbl_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 usingbl_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.
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.
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.
@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.
@Polochon-street ok, I double check it and PR if needed with the rest of the issues tomorrow.
from bliss.
Related Issues (20)
- cosine_similarity producing similar result values? HOT 15
- libswresample dependency only available for very latest distros HOT 9
- trying to decode more than 7 files produces crash of the process HOT 10
- Fails to build with ffmpeg-6.0 HOT 3
- ReplayGain HOT 3
- ffmpeg garbage output HOT 2
- Online database HOT 4
- Segfault HOT 3
- Freeing struct upon BL_UNEXPECTED HOT 3
- Wrong usage example HOT 2
- Ranges for each analysis value HOT 4
- Probleme de compilation HOT 11
- use aubio for analysis? HOT 2
- build error with ffmpeg 2.8.8 HOT 2
- Classifying songs HOT 2
- ArchLinux PKGBUILD fix please HOT 1
- Status of this project HOT 2
- Failed test building on Debian/buster HOT 1
- Please tag the repository with a version number HOT 2
- Please drop "/usr/" in installation paths HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bliss.