iTunes ratings
Mar. 13th, 2005 11:46 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
A while back I opined that iTunes ratings were essentially useless, mostly because there's no way I'm going to go and manually rate every song in my library; then I started thinking about ways that they might be made useful. I have a lot of Smart Playlists and such that are based on play counts, but play counts have the problem that they penalize long classical and jazz pieces that I actually like quite a lot. I don't necessarily listen to them as many times, because they're long, but going by time spent listening to them, they get their due. So an auto-rating script that depended on time spent listening might be a useful way to do the initial population of the library with ratings, at least as a starting point.
It couldn't be a linear scale, since the distribution of songs I listen to is probably so sharply peaked that it would blow out the scale. A logarithmic scale seemed reasonable. But as far as I can tell AppleScript has no real math library (Apple's FAQ answers the question "how do I use trigonometry?" by listing a bunch of Taylor-series-based AppleScript implementations of trig functions; gee, thanks a lot). So I had to improvise with a crude function that basically linearly interpolates between powers of the base.
Anyway, here was what I came up with:
It's not very efficient and takes several minutes to rate my library. But it does all right. There are some weird tweaks in there. Interestingly, the rating is actually represented internally as a number from 0 to 100. But the maximum rating of 5 stars is only given to songs rated exactly 100, so I scaled up the range a little and then clipped to 100 afterwards to give the 5 stars to a few more songs. Also, there's a minimum cutoff in there to keep stuff I haven't listened to at all from skewing the curve.
Of course, these ratings are penalizing newer music that I haven't had the time to listen to a lot. It's only intended as a start.
It couldn't be a linear scale, since the distribution of songs I listen to is probably so sharply peaked that it would blow out the scale. A logarithmic scale seemed reasonable. But as far as I can tell AppleScript has no real math library (Apple's FAQ answers the question "how do I use trigonometry?" by listing a bunch of Taylor-series-based AppleScript implementations of trig functions; gee, thanks a lot). So I had to improvise with a crude function that basically linearly interpolates between powers of the base.
Anyway, here was what I came up with:
on poorMansLogarithm(x) set lowBound to 1 set factor to 2 set answer to 0 repeat 100 times if x > lowBound then set answer to answer + 1 else set answer to answer + ((x - lowBound / factor) / (lowBound - lowBound / factor)) return answer end if set lowBound to lowBound * factor end repeat return answer end poorMansLogarithm tell application "iTunes" set tunes to the selection of the front browser window set maxTimePlayed to 0 set minTimePlayed to (duration of item 1 of tunes) * (played count of item 1 of tunes) set minTimePlayedCutoff to 30 repeat with i from 1 to count of tunes set currentTrack to item i of tunes set timePlayed to (duration of currentTrack) * (played count of currentTrack) if (timePlayed > maxTimePlayed) then set maxTimePlayed to timePlayed if (timePlayed < minTimePlayed) then set minTimePlayed to timePlayed end repeat if (minTimePlayed < minTimePlayedCutoff) then set minTimePlayed to minTimePlayedCutoff set maxRating to my poorMansLogarithm(maxTimePlayed) set minRating to my poorMansLogarithm(minTimePlayed) set ratingScale to 115.0 / (maxRating - minRating) repeat with i from 1 to count of tunes set currentTrack to item i of tunes set timePlayed to (duration of currentTrack) * (played count of currentTrack) set newRating to my poorMansLogarithm(timePlayed) set newRating to (newRating - minRating) * ratingScale if (newRating > 100) then set newRating to 100 if (newRating < 0) then set newRating to 0 set rating of currentTrack to newRating end repeat end tell
It's not very efficient and takes several minutes to rate my library. But it does all right. There are some weird tweaks in there. Interestingly, the rating is actually represented internally as a number from 0 to 100. But the maximum rating of 5 stars is only given to songs rated exactly 100, so I scaled up the range a little and then clipped to 100 afterwards to give the 5 stars to a few more songs. Also, there's a minimum cutoff in there to keep stuff I haven't listened to at all from skewing the curve.
Of course, these ratings are penalizing newer music that I haven't had the time to listen to a lot. It's only intended as a start.
no subject
Date: 2005-03-13 08:54 pm (UTC)no subject
Date: 2005-03-14 12:39 am (UTC)no subject
Date: 2005-03-14 04:58 am (UTC)I actually sort of dislike AppleScript as a language; it has a COBOLesque verbosity to it. The idea of a programming language with an internationalizable command vocabulary is kind of interesting, though.
no subject
Date: 2005-03-14 05:04 am (UTC)no subject
Date: 2005-03-14 05:23 am (UTC)I rate on-the-fly using Synergy, so while there will be unrated songs in my library, I generally rate them as I hear them (and have Smart Playlists set to make sure they're on my usual playlists).
no subject
Date: 2005-03-14 06:39 pm (UTC)Now that I've got a rough set of ratings, it should make sense to use them as criteria in Smart Playlists and such. Up to now I haven't done so.
no subject
Date: 2005-03-14 05:42 am (UTC)Stopped me in time. Do note "do shell script", though, as a potentially easy was of calculating logs.
I find I never use ratings, though it seems like I should. At one time I thought about using them as code for some other factor -- I was starting with the idea of rating Pop music with 5-star-high, and Classical with 1-star-high, and wondered about using some variant making use of the 1 through 100 internal ranking ... but never got around to it, or even formulated the idea properly.
no subject
Date: 2005-03-14 06:48 am (UTC)