itunes tempo control

Has anyone tried to write an applescript that controls the tempo of tracks played back in itunes? If not, does anyone have advice on how I would get started or whether it is possible at all?

with “tempo” you mean 3/4 or 4/4 etc… ?
As there isn’t any iTunes function to provide you with this information you can’t expect any result by AppleScript.
Maybe some music editing applications might offer you this possibility but unfortunatedly I don’t have any experience with this kind of programms…

Good luck

I actually mean making a song play faster or slower. I teach dance classes, and it would be nice to be able to control the tempo in iTunes so I can slow things down sometimes.

Sorry, I didn’t get it the first time - now I see :slight_smile: Unfortunatedly the answer stays the same: as this is not an existing feature of iTunes (at least not in my 6.0.4 version) it can not be scripted. Eventually it can be done using some audio editing software.

Good work

I’ve been fooling around with this for a few days for my own amusement. Although iTunes itself can’t control playback tempi, recent versions of QuickTime Player can “ so the idea here is to get the Player to play through the files in an iTunes playlist.

The script below asks for a relative playback speed (ie. relative to the original speed of each track) and gets QuickTime Player to play all the track files in the currently displayed iTunes playlist, with that adjustment. (You have to select the playlist before running the script.) Each track starts off at the relative speed you’ve specified, but QT Player’s “Playback Speed” slider can be adjusted for individual numbers while they’re playing. The cue for closing the current Player window and going on to the next track is when the end of the current track is reached, so tracks can be skipped by hitting the Player’s “cut to end” button. The script simply pauses when the Player’s stop button’s clicked. To stop the script altogether before it’s completed the cycle, close the current Player window manually or quit the Player.

This is only an exploration of a few concepts, but someone might find it useful. Tested with iTunes 7.0, QuickTime Player 7.1.3 (not Pro), and OS X 10.4.7 on a G5 machine, in Script Editor and Script Menu. It uses GUI Scripting to set the Player’s “Playback Speed” slider position.

on main()
	-- Assuming that the required playlist is currently displayed in iTunes, locate its track files,
	-- ask the user for a relative play-back speed, and work out the slider setting.
	tell application "iTunes"
		set relativeSpeed to text returned of (display dialog "Play this list at what relative speed?" & return & "(0.5 to 3)" default answer "1" with icon note)
		set trackFiles to location of file tracks of view of front browser window
	end tell
	set sliderSetting to getSliderSetting(relativeSpeed)
	repeat with thisTrackFile in trackFiles
		-- (Re)open QuickTime Player's "A/V Controls" window, then load a track file.
		tell application "QuickTime Player"
			set show av controls window to true
			open thisTrackFile
		end tell
		tell application "System Events"
			-- If the screen saver's kicked in, kick it out again.
			if (process "ScreenSaverEngine" exists) then tell application "ScreenSaverEngine" to quit
			-- Set the value of the "Playback Speed" slider in QuickTime Player's "A/V Controls" window. (Uses GUI Scripting.)
			tell application process "QuickTime Player"
				set frontmost to true
				set speedSliderGroup to (first group of front window where (name of static texts contains "1x"))
				set speedSlider to (first slider of speedSliderGroup whose (minimum value is 2) and (maximum value is 8))
				set value of speedSlider to sliderSetting
			end tell
		end tell
		-- Start playing and wait until either the user closes the movie or the end of the track is reached.
		-- If the movie's been closed, stop the script too. Otherwise close the movie and continue.
		tell application "QuickTime Player"
			tell (get front movie) -- Resolve the 'front movie' reference to the current movie.
					repeat while (current time < duration)
						delay 0.2
					end repeat
				on error msg number 1 -- Can't get the movie's current time & duration because it's been closed.
					error number -128
				end try
			end tell
		end tell
	end repeat
end main

-- Calculate QuickTime Player's "Playback Speed" slider setting for a given relative speed.
-- The slider accepts real values between 2.0 (half speed) and 8.0 (3x speed).
-- The settings hinge logarithmically around 4.0 (normal (1x) speed), so that each slider setting
-- increases or decreases the speed relative to the original by 0.25 * (2 ^ (setting - 4.0 - 1)).
-- So, to get the setting from the relative speed, we need to find (log2 ((relative speed - original) * 4)) + 1 + 4.0.
on getSliderSetting(relativeSpeed)
	-- Ensure that the specified speed's within the allowed range.
	set relativeSpeed to relativeSpeed as number
	if (relativeSpeed < 0.5) then
		set relativeSpeed to 0.5
	else if (relativeSpeed > 3) then
		set relativeSpeed to 3
	end if
	-- Get the difference between the relative speed and the original, in quarters of the original.
	set originalSpeed to 1
	set slowing to (relativeSpeed < originalSpeed)
	if (slowing) then
		set quarters to (originalSpeed - relativeSpeed) * 4
		set quarters to (relativeSpeed - originalSpeed) * 4
	end if
	if (quarters < 1) then
		-- Less than 0.25 speed difference. Use linear scaling instead of logarithmic.
		-- The difference is unnoticeable in this range and it solves a couple of calculation problems!
		set settingDifference to quarters
		-- 0.25 or more speed difference. Use logarithmic scaling.
		-- This is a crude, brute-force way to "calculate" the log, but it's good enough here.
		-- If you have the Satimage OSAX, you can replace the next 5 lines with: set settingDifference to (ln quarters) / (ln 2) + 1
		set log2quarters to 0
		repeat while (2 ^ log2quarters < quarters)
			set log2quarters to log2quarters + 0.01
		end repeat
		set settingDifference to log2quarters + 1
	end if
	if (slowing) then
		set sliderSetting to 4.0 - settingDifference
		set sliderSetting to 4.0 + settingDifference
	end if
	return sliderSetting
end getSliderSetting


Ciao Jacques,
cool! In a first moment I had thought too that QuickTime Player could make the job, but I had overseen the “preferred rate” property in its dictionary :slight_smile:


Thanks, Jacques. That certainly simplifies the script! :slight_smile:

But it’s shown up a bit of a discrepancy (in QuickTime Player 7.1.3) between the slider in the A/V Controls window and the preferred rate setting. If I set the preferred rate to anything above 1.6 by script and then open the A/V Controls window, the Playback Speed slider’s plainly positioned too far to the right. If I use GUI Scripting to set the slider position, the slider ends up exactly where I expect it to be and the preferred rate reads back very close to what’s intended “ except between 1.61 and 1.99, where the preferred rate reported by my test script gradually falls behind the scripted slider setting until it reads about 1.75 for a slider setting of 1.99. At 2.0, the slider and the preferred rate suddenly jump back into sync. The same happens if I move the slider manually and use a script to read the resulting preferred rate value.

In my script, the user’s supposed to be able to see the slider and to make manual adjustments with it if necessary. In order not to disturb him/her with the sight of a wrongly positioned slider, I haven’t incorporated your suggestion for now. But I have made a mental note of the existence of the preferred rate setting! :slight_smile:

Nigel, thanks a million! I hadn’t thought of using Quicktime to play the files instead, but I think it’s great.
I had a problem with the script that you sent. It seems like it was unable to find the group to set speedSliderGroup to, but I wouldn’t worry about it. It’s enough for me to select one track and have it open in Quicktime with the slider visible. That way I can select the song I want to use for a dance, queue it up, and set the speed, but I can still make use of iTunes’ organization and I can still use my Apple remote to control Quicktime. That’s pretty much all I wanted.
You’ve definitely made my day!

(Here’s my incredibly pared down version that seems to work fine:)

tell application "iTunes"
	set trackFile to location of selection
end tell
tell application "QuickTime Player"
	set show av controls window to true
	open trackFile
end tell

Hi. I’m glad you were able to find something useful in the script. :slight_smile:

Thanks for the feedback about the speedSliderGroup problem. It’s possible either that your QuickTIme “A/V Controls” window has a different structure from mine or that it’s not opening as quickly on your machine and so the script’s trying to get the group too soon. I’ll build a window existence test into similar scripts in future!