mmcirvin: (Default)
[personal profile] mmcirvin
It's still all AppleScript, but a few simple optimizations make it much faster:

on poorMansLogarithm(x)
	
	set exponent to 4
	set bound to 32
	set prevBound to 16
	
	repeat
		if x > bound then
			set exponent to exponent + 1
			set prevBound to bound
			set bound to bound * 2
		else
			return exponent + x / prevBound - 1
		end if
	end repeat
	
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 32
	
	repeat with currentTrack in 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 maxLog to my poorMansLogarithm(maxTimePlayed)
	set minLog to my poorMansLogarithm(minTimePlayed)
	set ratingScale to 115.0 / (maxLog - minLog)
	
	repeat with currentTrack in tunes
		set timePlayed to (duration of currentTrack) * (played count of currentTrack)
		set newRating to ((my poorMansLogarithm(timePlayed)) - minLog) * 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



The biggest, besides general loop-body reduction, being that I don't care about accuracy of my "logarithm" below the scaling cutoff, so I can skip those loop iterations entirely.

Date: 2005-03-14 10:23 pm (UTC)
From: [identity profile] chicken-cem.livejournal.com
I tried to run the script but got the error, "Can't divid 115.0 by zero".

??

Date: 2005-03-15 05:02 am (UTC)
From: [identity profile] mmcirvin.livejournal.com
It uses the selection in the front browser window (because I adapted it from scripts by [livejournal.com profile] iayork that do something similar). If there's only one song selected, or all the things selected have been played for exactly the same length of time, it gets into trouble; I didn't bother with sensible error handling.

To run it on your whole library, just do select-all in the browser (or modify the line where it gets the variable tunes).

Date: 2005-03-15 12:56 am (UTC)
From: [identity profile] inkerx.livejournal.com
Hey, Matt, hope you don't mind if I try my hand at a Python version that works in Windows. Cool idea!

Date: 2005-03-15 05:02 am (UTC)
From: [identity profile] mmcirvin.livejournal.com
Go right ahead.

Date: 2005-03-15 06:39 am (UTC)
From: [identity profile] mmcirvin.livejournal.com
Here's a variant that still operates on the browser selection but always scales relative to your whole library, so that the ability to limit the selection might actually be useful-- mind you, being very new at scripting iTunes, I don't know how sensitive it is to file renamings and such; also, it's frustrating that it takes so much time just to calculate a scale factor:

on poorMansLogarithm(x)
	
	set exponent to 4
	set bound to 32
	set prevBound to 16
	
	repeat
		if x > bound then
			set exponent to exponent + 1
			set prevBound to bound
			set bound to bound * 2
		else
			return exponent + x / prevBound - 1
		end if
	end repeat
	
end poorMansLogarithm

tell application "iTunes"
	
	set myLibrary to the playlist "Library" of the source "Library"
	
	set maxTimePlayed to 0
	set minTimePlayed to (duration of track 1 of myLibrary) * (played count of track 1 of myLibrary)
	set minTimePlayedCutoff to 32
	
	repeat with currentTrack in every track of myLibrary
		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 maxLog to my poorMansLogarithm(maxTimePlayed)
	set minLog to my poorMansLogarithm(minTimePlayed)
	if (maxLog = minLog) then
		set ratingScale to 100.0
	else
		set ratingScale to 120.0 / (maxLog - minLog)
	end if
	
	set tunes to the selection of the front browser window
	repeat with currentTrack in tunes
		set timePlayed to (duration of currentTrack) * (played count of currentTrack)
		set newRating to ((my poorMansLogarithm(timePlayed)) - minLog) * 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

June 2025

S M T W T F S
1234567
89101112 1314
151617181920 21
22232425262728
2930     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 14th, 2025 09:20 pm
Powered by Dreamwidth Studios