Edited: See my next post for the details of changes made to this script
This script is similar to the on I posted above. Here is what it does:
After running through the setup, it pause for an initial_delay – by default, it is set to 4 hours. So you’ll get most of your deep sleep over with, and be in the second half of your sleep cycle, where most of your dreams occur, before anything happens.
Next it begins to run through cycles, each one louder than the last, until they top out at 100%, or you cancel it or start it over. at default, it will smoothly bring the volume from 0 to 25, then back down to 0, then pause for 5 minutes, then volume 0 - 30 - 0, pause again for 5 minutes, etc., until finally it tops out at volume 0 - 100 - 0.
The idea is that you will keep getting cues from the sound, until finally the cues will wake you up, although hopefully in a much more gentle and dream-friendly fashion than an alarm clock. you lie in bed, run through your dream a few times, then get up, record your dream, and tell the script to move on to the next sequence. you can also easily leave the script waiting for you (after selecting “Start Next Cycle”, but before selecting “Continue”) for several hours, if you want to stay awake for a bit.
the second time around, the initial_delay will be set to the intracycle_delay, which defaults to 1 hour. this should give you time to go to sleep, then the sequence repeats as above – eventually it will wake you up again, if the volume at max_vol is loud enough.
anyway, it can act like a gentle alarm clock, to help you with WBTB, and to boost your dream recall. also, you may get some dreamsigns from the sounds playing (before they are loud enough to wake you up)
by default, it will pause the track between volume spikes, and rewind the track a bit so that you don’t miss too much of what happens when the volume is very very quiet. there is now an option, pause_track, which can be set to false, which stops the script from pausing the track. You should then set min_vol to something at least barely audible, and set percent_to_rewind to 0. Oh, and min_vol will be scaled just like max_vol – at first, when max_vol * 0.25, min_vol will also be * 0.25, and so on. i haven’t tried this yet, but since i had the ability to set min_vol higher than 0, I thought I should include this option.
here is the code, which i will probably update several times, although i will be away from my computer for the next week or so.
[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, percent_of_max, intracycle_delay, pause_track
–default values
set length_of_pause to 5 * 60 – 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 50 – # 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
set max_vol to 100 – maximum volume, from 5 to 100
set sine_delay to 0.25 – delay between volume adjustments, in seconds
set initial_delay to 4 * 60 * 60 – delay between volume check and first pause, for the first cycle, in seconds
set intracycle_delay to 1 * 60 * 60 – delay between volume check and first pause, for all subsequent cycles, in seconds
set pause_track to true – whether or not to stop itunes from playing during the pauses. if you set this to false, you will want to set min_vol to something at least barely audible, and set percent_to_rewind to 0.
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
repeat
set percent_of_max to 25
run_cycle()
with timeout of 3 * 60 * 60 seconds
tell application “iTunes” to display dialog “Ready to start next cycle?” buttons {“Cancel”, “Continue to next cycle”} default button 2 giving up after 3 * 60 * 60
end timeout
if button returned of the result is “Cancel” then continue quit
end repeat
on run_cycle()
tell application “iTunes”
set sound volume to max_vol
play
if button returned of (display dialog “Volume Check @ 100%” buttons {“Cancel”, “Skip Volume Check”} default button 2 giving up after 10) is “Cancel” then continue quit
set sound volume to ((max_vol - min_vol) * 0.5) + min_vol
if button returned of (display dialog “Volume Check @ 50% of max” buttons {“Cancel”, “Skip Volume Check”} default button 2 giving up after 10) is “Cancel” then continue quit
set sound volume to ((max_vol - min_vol) * 0.25) + min_vol
if button returned of (display dialog “Volume Check @ 25% of max” buttons {“Cancel”, “Skip Volume Check”} default button 2 giving up after 10) 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) * percent_of_max / 100
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) * percent_of_max / 100
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 / " & ((initial_delay * 100 / 3600) as integer) / 100 & " hours 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 seconds_to_rewind is greater than 0 then
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
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) * percent_of_max / 100
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) * percent_of_max / 100
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) * percent_of_max / 100
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) * percent_of_max / 100
end repeat
end if
if length_of_pause is greater than 0 then
if pause_track is true then pause
activate
if percent_of_max is less than 100 then
with timeout of length_of_pause + 60 seconds
display dialog "Paused… Last cycle at " & percent_of_max & "% of max volume, next cycle at " & percent_of_max + 5 & “%” buttons {“Cancel”, “Skip This Pause”, “Start Next Cycle”} default button 3 giving up after length_of_pause
end timeout
if button returned of the result is “Cancel” then
exit repeat
continue quit
else if button returned of the result is “Start Next Cycle” then
set initial_delay to intracycle_delay
exit repeat
break
run_cycle()
end if
set percent_of_max to percent_of_max + 5
else
with timeout of length_of_pause + 60 seconds
display dialog “Paused… Cycling at max volume” buttons {“Cancel”, “Skip This Pause”, “Start Next Cycle”} default button 3 giving up after length_of_pause
end timeout
if button returned of the result is “Cancel” then
exit repeat
continue quit
else if button returned of the result is “Start Next Cycle” then
set initial_delay to intracycle_delay
exit repeat
break
run_cycle()
end if
end if
end if
end repeat
end tell
end run_cycle
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()
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
tell application “iTunes”
set sound volume to min_vol
play
end tell
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
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
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]