I've been playing around with a function that will take a list of non-scale tones and use fix
to lower/raise their up
value one semitone so that they conform with a diatonic scale, e.g.
fix (|- up 1) "[1,3,6,8,10]" -- notes in range conform to [0,2,4,5,7,9,11]
Of course, I want this function to work across other octaves, for which I can provide it with a giant list of values to avoid (this works well and is tons of fun):
fix (|- up 1) "[-35,-33,-30,-28,-26,-23,-21,-18,-16,-14,-11,-9,-6,-4,-2,1,3,6,8,10,13,15,18,20,22,25,27,30,32,34,37,39,42,44,46]"
And I can programatically generate this list from a list of scale tones:
let showableAvoidList scaleIntervals = show completeAvoidList where
completeAvoidList = concat $ transposeScale avoidIntervals <$> [(-3)..3]
transposeScale avoidIntervals oct = (+ (oct * 12)) <$> avoidIntervals
avoidIntervals = filter (\n -> notElem n scaleIntervals) [0..11]
So that
showableAvoidList [0,2,4,5,7,9,11]
creates the giant list above.
But I thought that with parseBP_E
, I’d be able to use this result directly with fix
, e.g.
let fudgeToScale scaleIntervals = fix (|- up 1) (parseBP_E $ showableAvoidList scaleIntervals) where
showableAvoidList scaleIntervals = show completeAvoidList
completeAvoidList = concat $ transposeScale avoidIntervals <$> [(-3)..3]
transposeScale avoidIntervals oct = (+ (oct * 12)) <$> avoidIntervals
avoidIntervals = filter (\n -> notElem n scaleIntervals) [0..11]
but I don’t seem to have all the pieces there yet. Could someone help me with this?
Also, I have no idea how inefficient this might be. I would love to hear if there is a more efficient/idiomatic way to do this (e.g., can this be done with modulo? That was also a dead end for me)