Params not intializing

Okay, I’m in crazy land here.
I’m trying to work on a method to explore graceful modulations, but I’m running into a weird problem.
The startingdirection param, for some reason, is initializing to 2. (My code wants it to be 1 or -1.)
Any idea why this is happening?


debugmode = true

##| debugprint is a utility function to optionally print out debugging messages,
##|   controlled by the debugmode variable. If not set, defaults to false and prints nothing.
##|   label: a text string to explain what the value means.
##|   value: the value being displayed for debugging purposes. If nil, just displays the label.

#scrub
#small utility function to return clean string of any value, even nil
define :scrub do |value, mapniltothis = ""|
  (value == nil ? mapniltothis : value.to_s)
end

define :debugprint do |label, value=nil|
  if !local_variables.include? "debugmode".to_sym
    debugmode = false
  end #if debugmode defined
  
  if debugmode
    puts scrub(label)  + scrub(value)
  end #if debug
end #define



whole = 4.0
half =2.0
quarter =1.0
eighth =0.5
sixteenth =0.25
dotted =1.5
triplet =2.0 / 3


define :rosettastone do |keyvalue="d4", scalename=:dorian, startingdirection=1, stepsize=1, mode="thirds", howmanyloops=7|
  debugprint "top of rosettastone"
  debugprint "keyvalue: ", keyvalue
  debugprint "scalename: ", scalename
  debugprint "startingdirection: ", startingdirection
  debugprint "stepsize: ", stepsize
  debugprint "mode: ", mode
  debugprint "how many loops: ", howmanyloops
  debugprint "params should be untouched"
  debugprint ""
  debugprint ""
  debugprint ""
  
  
  
  noteshifter = {
    :locrian => [0,4],
    :phrygian => [4,1],
    :aeolian => [1,5],
    :minor => [1,5],
    :dorian => [5,2],
    :mixolydian => [2,6],
    :ionan => [5,3],
    :major => [5,3], #for convenience
    :lydian => [3,7]
  }
  debugprint noteshifter
  
  thisscale = scale keyvalue, scalename
  debugprint "thisscale: " , thisscale
  
  loopsplayed = 1
  
  currentdirection = startingdirection
  debugprint "currentdirection: ", currentdirection
  
  
  
  scaledegreelookup = (currentdirection + 1) / 2 
  debugprint "scaledegreelookup: ", scaledegreelookup
  #so 1 doubles to 2, divides by 2 remains 1
  #while -1 goes up to 0
  #and we get the 2nd array element for up or first for down

  notetochange = noteshifter[scalename][scaledegreelookup]
  debugprint "notetochange: ",  notetochange
  
  while loopsplayed != 0 do
    debugprint "loop ", loopsplayed
    case mode.downcase[0..2]
    
    when "sev"
      debugprint "sevenths mode"
      [0, 2, 4, 6].each do |note|
        play thisscale[note]
      end #each
      sleep quarter
      [1, 3, 5, 7].each do |note|
        play thisscale[note]
      end #each
      sleep quarter
      
    when "sca"
      debugprint "scale mode"
      thisscale.each do |note|
        play note
        sleep eighth
      end #each note
      
    when "tet"
      debugprint "tetrachord mode"
      [0,1,2,3].each do |note|
        play thisscale[note]
      end #each
      sleep quarter
      [0,1,2,3].each do |note|
        play thisscale[note]
        sleep eighth
      end #each
      [4,5,6,7].each do |note|
        play thisscale[note]
      end #each
      sleep quarter
      [4,5,6,7].each do |note|
        play thisscale[note]
        sleep eighth
      end #each
      
    when "fif"
      debugprint "fifths mode"
      (0..7).each do |fifths|
        debugprint "fifths: " , fifths
        play thisscale[0 + (5 * fifths) % 7]
        sleep eighth
      end #do
      
    when "thi"
      debugprint "thirds mode"
      (0..7).each do |third|
        play thisscale[third]
        play thisscale [(third + 2) % 7]
        sleep eighth
      end #each 0-7

    else
      puts mode + " is not a supported mode."
      puts "Supported modes: sevenths, scales, tetrachords, fifths"
      
    end #case
    
    
    debugprint "changing notes"
    (1..stepsize).each do |step|
      debugprint "note to change", notetochange
      debugprint "step,", step
      thisarray = thisscale.to_a
      debugprint "thisaray: ", thisarray
      thisarray[notetochange] += currentdirection 
      if notetochange == 0
        thisarray[7] += currentdirection 
      end #if
      debugprint "thisarray: ", thisarray
      thisscale = thisarray.ring
      debugprint "thisscale,", thisscale
      puts "notetochange before:", notetochange
      puts "currentdirection: ", currentdirection
      notetochange = (notetochange  + (4 * currentdirection)) #% 7
      debugprint "notetochange: ", notetochange
    end #each step

    sleep quarter #after each phrase

    debugprint "test if direction change needed"
    loopsplayed += (startingdirection * currentdirection)
    if loopsplayed > howmanyloops
        debugprint "direction change needed"
      currentdirection *= -1 #change direction
      debugprint "new direction", currentdirection
      scaledegreelookup = (currentdirection + 1) / 2 
    #   #so 1 doubles to 2, divides by 2 remains 1
    #   #while -1 goes up to 0
    #   #and we get the 2nd array element for 1, or first for 0

      debugprint "notetochange: ", notetochange
      debugprint "currentdirection: ", currentdirection
      notetochange = (notetochange + (currentdirection * 4)) % 7
      debugprint "notetochange: ",  notetochange


    else 
        debugprint "no direction change needed"
    end #if hit max loops



  end #while
end #define


rosettastone "d", :dorian, 2



Just try loading the file and running “rosettastone” with no args. Specifying the args also doesn’t fix the problem.
Makes no sense to me!
Thanks as always for the generous help.

Works as expected for me, does this persist after restarting
SP?

The call at the end:

rosettastone "d", :dorian, 2

Is passing a 2 to the third parameter, which is startingdirection.

If you want to be able to set arbitrary arguments, you can change the function definition to:

define :rosettastone do |keyvalue: "d4", scalename: :dorian, startingdirection: 1, stepsize: 1, mode: "thirds", howmanyloops: 7|

Then you can call it with arbitrary parameters, in any order, but you have to name them:

rosettastone keyvalue: "d", scalename: :dorian, stepsize: 2

That’s some detective work there @emlyn well-spotted!

1 Like

Yes, I finally figured that out. Pretty dumb on my part!
“I really hate this dumb machine,
I wish that they would sell it!
It never does just what I want,
But only what I tell it.”