melody = {name:'melody', pos:125}
harmony = {name:'harmony', pos:30}
bass = {name:'bass', pos:-65}

# scales
cmajor = ["C","D","E","F","G","A","B"]
cminor = ["C","D","_E","F","G","_A","_B"]
blues = ["C","D","^D","E","G","A"]
persian = ["C","^C","E","F","^F","^G","B"]
japanese = ["C","^C","F","G","^A"]
hungarian = ["C","D","^D","^F","G","^G","B"]
pentatonic = ["C","D","E","G","A"]

#beats
signature = 4
whole = signature
half = signature/2
quarter = signature/4
eighth = signature/8
sixteenth = signature/16

# Edit this section to change the music
pianos = [melody, bass]
notes = pentatonic
measures = 5
tempo = 130
melodyBeats = [quarter]
bassBeats = [whole]
melodyOctaves = ["", "'"]
bassOctaves = [",,", ",", ""]
biasForNotes = [0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.14]

# Algorithm and setup, click arrow below to expand
do -> # fold
  getBiasedNote = () -> # fold
    # Returns a note based on the probability weights
    #   defined in biasForNotes.
    multiples = []
    weightedNoteIndexes = []
    for b in [0..notes.length - 1]
      multiples = biasForNotes[b] * 100
      for m in [0..multiples]
        weightedNoteIndexes.push(notes[b])
    max = weightedNoteIndexes.length - 1
    randomNum = Math.floor(Math.random() * (max + 1))
    biasedNote = weightedNoteIndexes[randomNum]
    return biasedNote

  addToSong = (noteType, beat) -> # fold
    # Returns a note with the octave and beat
    note = getBiasedNote()
    if noteType is 'melody' or noteType is 'harmony'
      octave = random melodyOctaves
    else if noteType is 'bass'
      octave = random bassOctaves
    if beat < 1
      beat = "/" + 1/beat + ' '
    else if beat is 1
      beat = ' '
    return note + octave + beat + ' '

  melody.beats = melodyBeats
  harmony.beats = melodyBeats
  bass.beats = bassBeats

  melody.notes = []
  harmony.notes = []
  bass.notes = []

  for [1..measures] # fold
    for p in pianos
      p.measure = 0
      p.measureNotes = []
      while p.measure < signature
        measureCheck = p.measure
        p.beat = random p.beats
        measureCheck += p.beat
        if measureCheck <= signature
          p.measureNotes += addToSong(p.name, p.beat)
          p.measure += p.beat
      p.notes.push([p.measureNotes])

  ht()
  sync melody, harmony, bass
  for p in pianos # fold
    p.piano = new Piano 88
    p.piano.fd p.pos
    for note in p.notes
      p.piano.play {tempo: tempo}, note[0]