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.5*pi to 0.5*pi (recall: 2*pi = 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]