amiika / ziffers

Numbered musical notation for composing algorithmic and generative melodies
MIT License
82 stars 5 forks source link

Refactor repeat alternate endings to generic cycles syntax #64

Closed amiika closed 2 years ago

amiika commented 2 years ago

Refactoring repeat alternate endings to more generic cycles syntax, kind of like in tidalcycles:

zplay "[: 1 2 <3;4> 5 :]" # Old
zplay "[: 1 2 <3 4> 5 :]" # New

zplay "[: 1 2<3 4; 4 5> 6 :]" # Old
zplay "[: 1 2<(3 4) (4 5)> 6 :]" # New

# New cycle features

zplay "1 2 <3 (4 3)> 5" # Without loop syntax plays only 1 2 3 4 5 with zplay
z1 "1 2 <3 (4 3)> 5" # Cycles using z1 or zloop
z1 "q2 <q e> 3 4 3 2 q4" # Cycles for note lengths etc.

z1 "(1 2)<+ - %>(1 4 2 3) # Cycle operations
z1 "(1 2)<3,4>(3 <4 5>) # Cycles inside euclid cycles
z1 "(i v vi)@(0 <1 2 012> 1) # Cycles for arpeggios
z1 "(1 2 3)<inverse>(<0 -1 3 2>) # Cycles transformation parameters (New syntax for list transformations as well)

z1 "<q2 q 3 5>" # This would be problematic - maybe error?
z1 "<q2 q 3 5> 3" # This would however be ok.
z1 "q" # Maybe this alone could mean rest 0.25?

This refactoring breaks the old syntax, but some support both could be also added for the old one ... not like anyone is actually using these and would mind ... right?

amiika commented 2 years ago

Need for recursive cycles?

z1 "<1 <3 4> 3>" # Useful ... or not?

For testing:

cycle = resolve_cycle(Thread.current[:tshared][:loop_i],v[:cycle]).to_z

def resolve_cycle(loop_i, item)
  if item.is_a?(Hash) && item[:cycle]
     resolve_cycle loop_i, item[:cycle][loop_i%item[:cycle].length]
  else
    ZiffArray.new(item.compact)
  end
end