Possible Holy grail Technique part II

I went kind of overboard with this, although there are still some rough edges. If anyone else wants to play with this and give me some feedback, that would be great. I’m happy to add more features.

As is, defaults to a pause of 5 minutes, and nice long sine-wave transitions, which IMHO sound better than linear transitions.

It also ‘rewinds’ the track such that when the volume reaches 50%, it will be playing the same part of the track as when the volume dropped to 50%.

I haven’t tried this in it’s current form – I did try a simple version a few nights ago, and it kept waking me up!

update: I tried this using the track from the Free Lucid Induction CD “Download”, and I starting hearing it during a really interesting dream, and I sort of knew what it was – I thought it was playing in the dreamworld though, because several minutes earlier in the dream, I was getting ready for bed, so I figured I had just turned it on and it was getting kind of loud, so I tried to turn it down using this really trippy remote, and then next thing I knew I was half-awake, and I grabbed the remote next to my pillow and turned it down… I think I might have had a shot if it hadn’t gotten so loud that it woke me up, but who knows… and then I couldn’t get back to sleep, although at least I was able to imprint a decent chunk of the dream. more details

I also use this code for doing stretches – every 45 seconds, a cresendo of music lets me know that it is time to move on to the next stretch. (on my fairly old G4, a pause of 40 seconds, a peak of 2 seconds and 250 steps adds up to a 45 second cycle, unless my computer is doing other things as well)

Save the following code as an Applescript Application.

[code]global length_of_pause, length_of_peak, number_of_steps, sine_wave, sine_time, seconds_to_rewind, percent_to_rewind, min_vol, max_vol, sine_delay, initial_delay

–default values
set length_of_pause to 300 --length of pause at minimum volume, in seconds
set length_of_peak to 0 --length of pause at maximum volume, in seconds
set number_of_steps to 200 --number of steps between min and max volume
set percent_to_rewind to 50 --percent to rewind
set min_vol to 0 --minimum volume, from 0 to 95, default 0
set max_vol to 100 --maximum volume, from 5 to 100, default 100
set sine_delay to 0.1 – delay between volume adjustments, in seconds helpful for slow/busy computers: if volume slider in iTunes doesn’t move smoothly, try using a small delay
set initial_delay to 3600 – delay between volume check and beginning of first pause, gives you a chance to fall asleep.

set sine_wave to {}
set sine_time to 0

tell application “iTunes” to display dialog “Custom or default?” & return & return & "( pause " & length_of_pause & " seconds, peak " & length_of_peak & " seconds, " & number_of_steps & " steps, rewind " & percent_to_rewind & "%, min volume " & min_vol & ", max volume " & max_vol & “, sine delay " & sine_delay * 1000 & " milliseconds and an initial delay of " & initial_delay & " seconds/ " & ((initial_delay * 100 / 60) as integer) / 100 & " minutes )” buttons {“Cancel”, “Customize”, “Use Defaults”} default button 3
if button returned of result is “Cancel” then
continue quit
else if button returned of result is “Customize” then
customize_timing()
else if button returned of result is “Use Defaults” then
generate_sine()
end if

tell application “iTunes”
set sound volume to max_vol
play
if button returned of (display dialog “Volume Check…” buttons {“Cancel”, “Skip Volume Check”} default button 2 giving up after 45) is “Cancel” then continue quit
if sine_delay is greater than 0 then
repeat with i from number_of_steps + 1 to 1 by -1
set sound volume to item i of sine_wave
delay sine_delay
end repeat
else
repeat with i from number_of_steps + 1 to 1 by -1
set sound volume to item i of sine_wave
end repeat
end if
if initial_delay is greater than 0 then
with timeout of initial_delay + 60 seconds
display dialog “Waiting " & initial_delay & " seconds / " & ((initial_delay * 100 / 60) as integer) / 100 & " minutes to Start…” buttons {“Cancel”, “Skip Initial Delay”} default button 2 giving up after initial_delay
end timeout
if button returned of the result is “Cancel” then continue quit
end if
repeat
if length_of_pause is greater than 0 then
pause
activate
with timeout of length_of_pause + 60 seconds
display dialog “Paused…” buttons {“Cancel”, “Skip This Pause”} default button 2 giving up after length_of_pause
end timeout
if button returned of the result is “Cancel” then continue quit
end if
set pos to player position
if pos - seconds_to_rewind is greater than 0 then
set player position to pos - seconds_to_rewind
else
set player position to 0
end if
play
if sine_delay is greater than 0 then
repeat with i from 1 to number_of_steps + 1 by 1
set sound volume to item i of sine_wave
delay sine_delay
end repeat
if length_of_peak is greater than 0 then
with timeout of length_of_peak + 60 seconds
display dialog “Playing…” buttons {“Cancel”, “Skip This Peak”} default button 2 giving up after length_of_peak
end timeout
if button returned of the result is “Cancel” then continue quit

		end if
		repeat with i from number_of_steps + 1 to 1 by -1
			set sound volume to item i of sine_wave
			delay sine_delay
		end repeat
	else
		repeat with i from 1 to number_of_steps + 1 by 1
			set sound volume to item i of sine_wave
		end repeat
		if length_of_peak is greater than 0 then delay length_of_peak
		repeat with i from number_of_steps + 1 to 1 by -1
			set sound volume to item i of sine_wave
		end repeat
	end if
end repeat

end tell

on customize_timing()
repeat
tell application “iTunes” to display dialog "Current settings: pause " & length_of_pause & " seconds, peak " & length_of_peak & " seconds, " & number_of_steps & " steps, rewind " & percent_to_rewind & "%, min vol " & min_vol & ", max " & max_vol & “, sine delay " & sine_delay * 1000 & " milliseconds and an initial delay of " & initial_delay & " seconds/ " & ((initial_delay * 100 / 60) as integer) / 100 & " minutes.” buttons {“Pauses / Delay”, “# of Steps / % of Rewind”, “Volume”}
if button returned of result is “Pauses / Delay” then
tell application “iTunes” to display dialog “Current settings: pause for " & length_of_pause & " seconds, peak for " & length_of_peak & " seconds, sine delay " & sine_delay * 1000 & " milliseconds and an initial delay of " & initial_delay & " seconds/ " & ((initial_delay * 100 / 60) as integer) / 100 & " minutes.” buttons {“Length of Pause”, “Length of Peak”, “Sine Delay/Initial Delay”}
if button returned of result is “Length of Pause” then
tell application “iTunes” to set length_of_pause to text returned of (display dialog “Enter length of pause in seconds” & return & “(currently " & length_of_pause & " seconds / " & ((length_of_pause * 100 / 60) as integer) / 100 & " minutes)” default answer length_of_pause) as integer
else if button returned of result is “Length of Peak” then
tell application “iTunes” to set length_of_peak to text returned of (display dialog “Enter length of peak in seconds” & return & “(currently " & length_of_peak & " seconds / " & ((length_of_peak * 100 / 60) as integer) / 100 & " minutes)” default answer length_of_peak) as integer
else if button returned of result is “Sine Delay/Initial Delay” then
tell application “iTunes” to display dialog “Current settings: sine delay " & sine_delay * 1000 & " milliseconds, initial delay of " & initial_delay & " seconds/ " & ((initial_delay * 100 / 60) as integer) / 100 & " minutes.” buttons {“Cancel”, “Sine Delay”, “Initial Delay”}
if button returned of result is “Cancel” then
continue quit
else if button returned of result is “Sine Delay” then
tell application “iTunes” to set new_sine_delay to (text returned of (display dialog “Enter length of delay between each of the " & number_of_steps & " steps” & return & “(currently " & sine_delay * 1000 & " milliseconds)” default answer sine_delay * 1000) as integer) / 1000
if new_sine_delay is not equal to sine_delay then
set sine_time to 0
set sine_delay to new_sine_delay
if sine_delay is less than 0 then set sine_delay to 0
end if
else if button returned of result is “Initial Delay” then
tell application “iTunes” to display dialog “Choose time scale for setting initial delay: currently " & initial_delay & " seconds / " & ((initial_delay * 100 / 60) as integer) / 100 & " minutes / " & ((initial_delay * 100 / 3600) as integer) / 100 & " hours.” buttons {“Seconds”, “Minutes”, “Hours”}
if button returned of result is “Seconds” then
tell application “iTunes” to set initial_delay to text returned of (display dialog “Enter initial delay in seconds” & return & “(currently " & initial_delay & " seconds)” default answer initial_delay) as integer
else if button returned of result is “Minutes” then
tell application “iTunes” to set initial_delay to ((text returned of (display dialog “Enter initial delay in minutes” & return & “(currently " & ((initial_delay * 100 / 60) as integer) / 100 & " minutes)” default answer ((initial_delay * 100 / 60) as integer) / 100)) * 60) as integer
else if button returned of result is “Hours” then
tell application “iTunes” to set initial_delay to ((text returned of (display dialog “Enter initial delay in hours” & return & “(currently " & ((initial_delay * 100 / 3600) as integer) / 100 & " hours)” default answer ((initial_delay * 100 / 3600) as integer))) * 3600) as integer
end if
end if
end if
else if button returned of result is “# of Steps / % of Rewind” then
tell application “iTunes” to display dialog “Current settings: " & number_of_steps & " steps, rewind of " & percent_to_rewind & " percent.” buttons {“Cancel”, “Change # of Steps”, “Change % of Rewind”}
if button returned of result is “Cancel” then
continue quit
else if button returned of result is “Change # of Steps” then
tell application “iTunes” to set new_number_of_steps to text returned of (display dialog “Enter number of steps from minimum volume to maximum volume” & return & “(currently " & number_of_steps & " steps)” default answer number_of_steps) as integer
if new_number_of_steps is not equal to number_of_steps then
set sine_time to 0
set number_of_steps to new_number_of_steps
if number_of_steps is less than 1 then set number_of_steps to 1
if number_of_steps is greater than 1000000 then set number_of_steps to 1000000
end if
else if button returned of result is “Change % of Rewind” then
tell application “iTunes” to set percent_to_rewind to text returned of (display dialog “Enter percentage of rewind” & return & "(currently " & percent_to_rewind & “%)” default answer percent_to_rewind) as integer
if percent_to_rewind is less than 0 then set percent_to_rewind to 0
if percent_to_rewind is greater than 100 then set percent_to_rewind to 100
end if
else if button returned of result is “Volume” then
tell application “iTunes” to display dialog "Current settings: minimum volume " & min_vol & ", max " & max_vol & “.” buttons {“Cancel”, “Change Minimum”, “Change Maximum”}
if button returned of result is “Cancel” then
continue quit
else if button returned of result is “Change Minimum” then
tell application “iTunes” to set min_vol to text returned of (display dialog “Enter minimum volume” & return & "(currently " & min_vol & “)” default answer min_vol) as integer
if min_vol is greater than or equal to max_vol then set min_vol to max_vol - 5
if min_vol is less than 0 then set min_vol to 0
if min_vol is greater than 100 then set min_vol to 100
else if button returned of result is “Change Maximum” then
tell application “iTunes” to set max_vol to text returned of (display dialog “Enter maximum volume” & return & "(currently " & max_vol & “)” default answer max_vol) as integer
if max_vol is less than or equal to min_vol then set max_vol to min_vol + 5
if max_vol is less than 0 then set max_vol to 0
if max_vol is greater than 100 then set max_vol to 100
end if
end if
tell application “iTunes” to display dialog “More adjustments, or continue?” buttons {“Cancel”, “Continue Customizing”, “Done”} default button 3
if button returned of result is “Cancel” then
continue quit
else if button returned of result is “Done” then
if sine_time is equal to 0 then
generate_sine()
tell application “iTunes” to display dialog “With " & number_of_steps & " steps, the round trip took " & sine_time & " seconds.” & return & return & “Total time from peak to peak is " & (sine_time + length_of_pause + length_of_peak) & " seconds.” buttons {“Cancel”, “Customize”, “Continue”} default button 3
if button returned of result is “Cancel” then
continue quit
else if button returned of result is “Continue” then
exit repeat
end if
else
exit repeat
end if
end if
end repeat
end customize_timing

on generate_sine()
tell application “iTunes”
set sound volume to min_vol
play
end tell
set sine_wave to {}
repeat with i from 0 to number_of_steps by 1
set sine_input to (i * pi / number_of_steps) - (0.5 * pi) (* input is in radians, from -0.5pi to 0.5pi (recall: 2pi = 360 degrees) )
set this_sine to (((sine_of(sine_input) + 1) * (max_vol - min_vol) / 2) + min_vol) (
if max-min = 100, then changes the results from (-1 to 1 to -1) to (0 to 2 to 0) to (0 to 100 to 0), and +0 brings them to (0 to 100 to 0)
)
set this_sine to this_sine as integer
copy this_sine to end of sine_wave
end repeat
if sine_delay is greater than 0 then
set sine_start_time to current date
tell application “iTunes”
repeat with i from 1 to number_of_steps + 1 by 1
set sound volume to item i of sine_wave
delay sine_delay / 1000
end repeat
repeat with i from number_of_steps + 1 to 1 by -1
set sound volume to item i of sine_wave
delay sine_delay / 1000
end repeat
end tell
set sine_time to (current date) - sine_start_time
else
set sine_start_time to current date
tell application “iTunes”
repeat with i from 1 to number_of_steps + 1 by 1
set sound volume to item i of sine_wave
end repeat
repeat with i from number_of_steps + 1 to 1 by -1
set sound volume to item i of sine_wave
end repeat
end tell
set sine_time to (current date) - sine_start_time
end if
set seconds_to_rewind to sine_time * percent_to_rewind / 100
end generate_sine

on sine_of(x)
(* https://www.apple.com/applescript/guidebook/sbrt/pgs/sbrt.02.htm AppleScript Guidebook: Essential Sub-Routines *)
set answer to 0
set numerator to x
set denominator to 1
set factor to -(x ^ 2)
repeat with i from 3 to 40 by 2
set answer to answer + numerator / denominator
set numerator to numerator * factor
set denominator to denominator * i * (i - 1)
end repeat
return answer
end sine_of[/code]

Optional add-on:

Insert this code before the peak and it will stop looping (stay on at max volume) beginning at a certain time you specify. Here, after 4:15 am (but not after 5, which stops it from triggering at 11 pm (since 11 > 4.25)). I was getting up at 4:45 so I figured might as well go for broke for the last 30 minutes…

tell application "Finder" set this_time to (time of (current date)) / 3600 if this_time is greater than 4.25 and this_time is less than 5 then exit repeat continue quit end if end tell