spiffyscore

Hex Artifact Content
Login

Artifact e9b556b4f37a3fa93ce6ccc0f662de2950e9efb5:


0000: 23 21 2f 75 73 72 2f 62 69 6e 2f 65 6e 76 20 70  #!/usr/bin/env p
0010: 79 74 68 6f 6e 0a 0a 66 72 6f 6d 20 5f 5f 66 75  ython..from __fu
0020: 74 75 72 65 5f 5f 20 69 6d 70 6f 72 74 20 64 69  ture__ import di
0030: 76 69 73 69 6f 6e 0a 69 6d 70 6f 72 74 20 6f 73  vision.import os
0040: 0a 69 6d 70 6f 72 74 20 72 61 6e 64 6f 6d 0a 69  .import random.i
0050: 6d 70 6f 72 74 20 73 79 73 0a 69 6d 70 6f 72 74  mport sys.import
0060: 20 74 69 6d 65 0a 72 61 6e 64 6f 6d 2e 73 65 65   time.random.see
0070: 64 28 74 69 6d 65 2e 74 69 6d 65 28 29 29 0a 0a  d(time.time())..
0080: 69 6d 70 6f 72 74 20 70 61 72 73 65 0a 69 6d 70  import parse.imp
0090: 6f 72 74 20 74 6f 70 73 6f 72 74 0a 69 6d 70 6f  ort topsort.impo
00a0: 72 74 20 79 61 6d 6c 0a 0a 64 65 66 20 6d 61 69  rt yaml..def mai
00b0: 6e 28 29 3a 0a 20 20 20 20 6b 65 79 20 3d 20 22  n():.    key = "
00c0: 41 22 0a 20 20 20 20 62 70 73 20 3d 20 36 30 2f  A".    bps = 60/
00d0: 36 30 0a 20 20 20 20 74 65 6d 70 6f 20 3d 20 31  60.    tempo = 1
00e0: 2f 62 70 73 0a 20 20 20 20 6d 61 78 5f 64 75 72  /bps.    max_dur
00f0: 61 74 69 6f 6e 20 3d 20 31 0a 0a 20 20 20 20 63  ation = 1..    c
0100: 6f 6d 70 6f 73 69 74 69 6f 6e 20 3d 20 79 61 6d  omposition = yam
0110: 6c 2e 6c 6f 61 64 28 6f 70 65 6e 28 22 73 63 6f  l.load(open("sco
0120: 72 65 2e 79 61 6d 6c 22 29 29 0a 0a 20 20 20 20  re.yaml"))..    
0130: 6d 61 78 5f 74 20 3d 20 30 20 20 23 20 6d 61 78  max_t = 0  # max
0140: 20 74 69 6d 65 20 65 6e 63 6f 75 6e 74 65 72 65   time encountere
0150: 64 20 73 6f 20 66 61 72 2e 20 55 73 65 64 20 66  d so far. Used f
0160: 6f 72 20 6d 6f 76 65 6d 65 6e 74 20 74 69 6d 69  or movement timi
0170: 6e 67 0a 20 20 20 20 70 72 6f 67 72 65 73 73 69  ng.    progressi
0180: 6f 6e 20 3d 20 22 63 68 6f 72 75 73 22 0a 0a 20  on = "chorus".. 
0190: 20 20 20 66 6f 72 20 6d 6f 76 65 6d 65 6e 74 20     for movement 
01a0: 69 6e 20 70 72 6f 67 72 65 73 73 69 6f 6e 2e 73  in progression.s
01b0: 70 6c 69 74 28 29 3a 0a 20 20 20 20 20 20 20 20  plit():.        
01c0: 66 6f 72 20 73 65 63 74 69 6f 6e 20 69 6e 20 5b  for section in [
01d0: 22 69 6e 74 72 6f 22 2c 20 22 63 6f 72 65 22 2c  "intro", "core",
01e0: 20 22 6f 75 74 72 6f 22 5d 3a 0a 20 20 20 20 20   "outro"]:.     
01f0: 20 20 20 20 20 20 20 69 66 20 73 65 63 74 69 6f         if sectio
0200: 6e 20 69 6e 20 63 6f 6d 70 6f 73 69 74 69 6f 6e  n in composition
0210: 5b 6d 6f 76 65 6d 65 6e 74 5d 2e 6b 65 79 73 28  [movement].keys(
0220: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ):.             
0230: 20 20 20 74 72 79 3a 0a 20 20 20 20 20 20 20 20     try:.        
0240: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 6e 64              rend
0250: 65 72 5f 6f 72 64 65 72 20 3d 20 74 6f 70 73 6f  er_order = topso
0260: 72 74 2e 74 6f 70 73 6f 72 74 28 5b 5b 63 6f 6d  rt.topsort([[com
0270: 70 6f 73 69 74 69 6f 6e 5b 6d 6f 76 65 6d 65 6e  position[movemen
0280: 74 5d 5b 73 65 63 74 69 6f 6e 5d 5b 69 6e 73 74  t][section][inst
0290: 72 75 6d 65 6e 74 5d 5b 22 73 79 6e 63 22 5d 2c  rument]["sync"],
02a0: 20 69 6e 73 74 72 75 6d 65 6e 74 5d 20 69 66 20   instrument] if 
02b0: 22 73 79 6e 63 22 20 69 6e 20 63 6f 6d 70 6f 73  "sync" in compos
02c0: 69 74 69 6f 6e 5b 6d 6f 76 65 6d 65 6e 74 5d 5b  ition[movement][
02d0: 73 65 63 74 69 6f 6e 5d 5b 69 6e 73 74 72 75 6d  section][instrum
02e0: 65 6e 74 5d 2e 6b 65 79 73 28 29 20 65 6c 73 65  ent].keys() else
02f0: 20 5b 4e 6f 6e 65 2c 20 69 6e 73 74 72 75 6d 65   [None, instrume
0300: 6e 74 5d 20 66 6f 72 20 69 6e 73 74 72 75 6d 65  nt] for instrume
0310: 6e 74 20 69 6e 20 63 6f 6d 70 6f 73 69 74 69 6f  nt in compositio
0320: 6e 5b 6d 6f 76 65 6d 65 6e 74 5d 5b 73 65 63 74  n[movement][sect
0330: 69 6f 6e 5d 5d 29 0a 20 20 20 20 20 20 20 20 20  ion]]).         
0340: 20 20 20 20 20 20 20 65 78 63 65 70 74 20 74 6f         except to
0350: 70 73 6f 72 74 2e 43 79 63 6c 65 45 72 72 6f 72  psort.CycleError
0360: 20 61 73 20 65 78 3a 0a 20 20 20 20 20 20 20 20   as ex:.        
0370: 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69 6e              prin
0380: 74 20 22 59 6f 75 72 20 69 6e 73 74 72 75 6d 65  t "Your instrume
0390: 6e 74 73 20 61 72 65 20 73 79 6e 63 65 64 20 69  nts are synced i
03a0: 6e 20 61 20 63 69 72 63 6c 65 21 20 54 68 69 73  n a circle! This
03b0: 20 6d 61 6b 65 73 20 6e 6f 20 73 65 6e 73 65 21   makes no sense!
03c0: 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ".              
03d0: 20 20 20 20 20 20 70 72 69 6e 74 20 6d 6f 76 65        print move
03e0: 6d 65 6e 74 2c 20 73 65 63 74 69 6f 6e 0a 20 20  ment, section.  
03f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0400: 20 20 70 72 69 6e 74 20 65 78 0a 20 20 20 20 20    print ex.     
0410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
0420: 79 73 2e 65 78 69 74 28 31 29 0a 20 20 20 20 20  ys.exit(1).     
0430: 20 20 20 20 20 20 20 20 20 20 20 0a 0a 23 20 20             ..#  
0440: 20 20 66 6f 72 20 63 6f 6d 70 5f 6e 61 6d 65 20    for comp_name 
0450: 69 6e 20 70 72 6f 67 72 65 73 73 69 6f 6e 2e 73  in progression.s
0460: 70 6c 69 74 28 29 3a 0a 23 20 20 20 20 20 20 20  plit():.#       
0470: 20 63 6f 6d 70 5f 73 74 61 72 74 5f 74 69 6d 65   comp_start_time
0480: 20 3d 20 6d 61 78 5f 74 0a 23 20 20 20 20 20 20   = max_t.#      
0490: 20 20 66 6f 72 20 69 6e 73 74 72 5f 6e 61 6d 65    for instr_name
04a0: 2c 20 69 6e 73 74 72 20 69 6e 20 63 6f 6d 70 6f  , instr in compo
04b0: 73 69 74 69 6f 6e 5b 63 6f 6d 70 5f 6e 61 6d 65  sition[comp_name
04c0: 5d 2e 69 74 65 72 69 74 65 6d 73 28 29 3a 0a 23  ].iteritems():.#
04d0: 20 20 20 20 20 20 20 20 20 20 20 20 67 65 6e 65              gene
04e0: 72 61 74 65 64 5f 73 63 6f 72 65 20 3d 20 67 65  rated_score = ge
04f0: 6e 65 72 61 74 65 5f 73 63 6f 72 65 28 69 6e 73  nerate_score(ins
0500: 74 72 5b 22 73 63 6f 72 65 22 5d 2c 20 69 6e 73  tr["score"], ins
0510: 74 72 5b 22 67 72 61 6d 6d 61 72 73 22 5d 29 20  tr["grammars"]) 
0520: 20 23 20 46 69 6c 6c 20 69 6e 20 74 68 65 20 73   # Fill in the s
0530: 63 6f 72 65 73 20 62 79 20 67 65 6e 65 72 61 74  cores by generat
0540: 69 6e 67 20 74 68 65 6d 20 62 61 73 65 64 20 6f  ing them based o
0550: 6e 20 74 68 65 20 67 72 61 6d 6d 61 72 73 0a 23  n the grammars.#
0560: 23 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69  #            pri
0570: 6e 74 20 67 65 6e 65 72 61 74 65 64 5f 73 63 6f  nt generated_sco
0580: 72 65 0a 23 20 20 20 20 20 20 20 20 20 20 20 20  re.#            
0590: 73 63 6f 72 65 20 3d 20 70 61 72 73 65 2e 70 61  score = parse.pa
05a0: 72 73 65 28 67 65 6e 65 72 61 74 65 64 5f 73 63  rse(generated_sc
05b0: 6f 72 65 2c 20 64 65 66 61 75 6c 74 5f 6f 63 74  ore, default_oct
05c0: 61 76 65 3d 69 6e 73 74 72 5b 22 6f 63 74 61 76  ave=instr["octav
05d0: 65 22 5d 29 20 20 23 20 52 65 74 75 72 6e 20 4e  e"])  # Return N
05e0: 6f 64 65 2f 43 68 6f 72 64 20 6f 62 6a 65 63 74  ode/Chord object
05f0: 73 0a 23 0a 23 20 20 20 20 20 20 20 20 20 20 20  s.#.#           
0600: 20 23 20 47 65 6e 65 72 61 74 65 20 74 69 6d 65   # Generate time
0610: 73 74 61 6d 70 73 20 66 6f 72 20 74 68 65 20 6e  stamps for the n
0620: 6f 74 65 73 20 0a 23 20 20 20 20 20 20 20 20 20  otes .#         
0630: 20 20 20 74 20 3d 20 63 6f 6d 70 5f 73 74 61 72     t = comp_star
0640: 74 5f 74 69 6d 65 0a 23 20 20 20 20 20 20 20 20  t_time.#        
0650: 20 20 20 20 66 6f 72 20 6e 6f 74 65 20 69 6e 20      for note in 
0660: 72 61 6e 67 65 28 6c 65 6e 28 73 63 6f 72 65 29  range(len(score)
0670: 29 3a 0a 23 20 20 20 20 20 20 20 20 20 20 20 20  ):.#            
0680: 20 20 20 20 73 63 6f 72 65 5b 6e 6f 74 65 5d 2e      score[note].
0690: 74 69 6d 65 20 3d 20 74 0a 23 20 20 20 20 20 20  time = t.#      
06a0: 20 20 20 20 20 20 20 20 20 20 73 63 6f 72 65 5b            score[
06b0: 6e 6f 74 65 5d 2e 64 75 72 61 74 69 6f 6e 20 2a  note].duration *
06c0: 3d 20 74 65 6d 70 6f 0a 23 20 20 20 20 20 20 20  = tempo.#       
06d0: 20 20 20 20 20 20 20 20 20 74 20 2b 3d 20 73 63           t += sc
06e0: 6f 72 65 5b 6e 6f 74 65 5d 2e 64 75 72 61 74 69  ore[note].durati
06f0: 6f 6e 0a 23 23 20 20 20 20 20 20 20 20 20 20 20  on.##           
0700: 20 20 20 20 20 70 72 69 6e 74 20 22 74 69 6d 65       print "time
0710: 20 64 69 66 66 65 72 65 6e 63 65 20 3d 22 2c 20   difference =", 
0720: 74 2d 63 6f 6d 70 5f 73 74 61 72 74 5f 74 69 6d  t-comp_start_tim
0730: 65 0a 23 23 20 20 20 20 20 20 20 20 20 20 20 20  e.##            
0740: 20 20 20 20 70 72 69 6e 74 20 22 69 6e 73 74 72      print "instr
0750: 75 6d 65 6e 74 20 64 75 72 61 74 69 6f 6e 20 3d  ument duration =
0760: 22 2c 63 6f 6d 70 6f 73 69 74 69 6f 6e 5b 63 6f  ",composition[co
0770: 6d 70 5f 6e 61 6d 65 5d 5b 69 6e 73 74 72 5f 6e  mp_name][instr_n
0780: 61 6d 65 5d 5b 22 64 75 72 61 74 69 6f 6e 22 5d  ame]["duration"]
0790: 0a 23 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .#              
07a0: 20 20 69 66 20 28 74 2d 63 6f 6d 70 5f 73 74 61    if (t-comp_sta
07b0: 72 74 5f 74 69 6d 65 29 20 3e 20 66 6c 6f 61 74  rt_time) > float
07c0: 28 63 6f 6d 70 6f 73 69 74 69 6f 6e 5b 63 6f 6d  (composition[com
07d0: 70 5f 6e 61 6d 65 5d 5b 69 6e 73 74 72 5f 6e 61  p_name][instr_na
07e0: 6d 65 5d 5b 22 64 75 72 61 74 69 6f 6e 22 5d 29  me]["duration"])
07f0: 3a 0a 23 23 20 20 20 20 20 20 20 20 20 20 20 20  :.##            
0800: 20 20 20 20 20 20 20 20 70 72 69 6e 74 20 22 68          print "h
0810: 65 72 65 22 0a 23 20 20 20 20 20 20 20 20 20 20  ere".#          
0820: 20 20 20 20 20 20 20 20 20 20 73 63 6f 72 65 20            score 
0830: 3d 20 73 63 6f 72 65 5b 3a 6e 6f 74 65 5d 0a 23  = score[:note].#
0840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0850: 20 20 20 20 62 72 65 61 6b 0a 23 20 20 20 20 20      break.#     
0860: 20 20 20 20 20 20 20 20 20 20 20 6d 61 78 5f 74             max_t
0870: 20 3d 20 74 20 69 66 20 74 20 3e 20 6d 61 78 5f   = t if t > max_
0880: 74 20 65 6c 73 65 20 6d 61 78 5f 74 0a 23 20 20  t else max_t.#  
0890: 20 20 20 20 20 20 20 20 20 20 63 6f 6d 70 6f 73            compos
08a0: 69 74 69 6f 6e 5b 63 6f 6d 70 5f 6e 61 6d 65 5d  ition[comp_name]
08b0: 5b 69 6e 73 74 72 5f 6e 61 6d 65 5d 5b 22 73 63  [instr_name]["sc
08c0: 6f 72 65 22 5d 20 3d 20 73 63 6f 72 65 0a 0a 20  ore"] = score.. 
08d0: 20 20 20 23 20 4d 75 73 74 20 62 65 20 64 6f 6e     # Must be don
08e0: 65 20 61 66 74 65 72 20 61 6c 6c 20 6e 6f 74 65  e after all note
08f0: 20 74 69 6d 65 73 20 6b 65 79 65 64 20 69 6e 2c   times keyed in,
0900: 20 65 6c 73 65 20 79 6f 75 20 63 61 6e 27 74 20   else you can't 
0910: 63 6f 6f 72 64 69 6e 61 74 65 20 6d 65 6c 6f 64  coordinate melod
0920: 69 65 73 20 77 69 74 68 20 74 68 65 20 72 68 79  ies with the rhy
0930: 74 68 6d 20 63 68 6f 72 64 73 0a 20 20 20 20 70  thm chords.    p
0940: 72 69 6e 74 20 27 27 27 66 31 20 20 30 20 20 35  rint '''f1  0  5
0950: 31 32 20 20 31 30 20 20 31 0a 20 20 20 20 20 20  12  10  1.      
0960: 20 20 20 20 20 20 66 32 20 30 20 38 31 39 32 20        f2 0 8192 
0970: 31 30 20 2e 32 34 20 2e 36 34 20 2e 38 38 20 2e  10 .24 .64 .88 .
0980: 37 36 20 2e 30 36 20 2e 35 20 2e 33 34 20 2e 30  76 .06 .5 .34 .0
0990: 38 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 33  8.            f3
09a0: 20 30 20 31 30 32 35 20 31 30 20 31 0a 20 20 20   0 1025 10 1.   
09b0: 20 27 27 27 0a 20 20 20 20 66 6f 72 20 63 6f 6d   '''.    for com
09c0: 70 5f 6e 61 6d 65 20 69 6e 20 70 72 6f 67 72 65  p_name in progre
09d0: 73 73 69 6f 6e 2e 73 70 6c 69 74 28 29 3a 0a 20  ssion.split():. 
09e0: 20 20 20 20 20 20 20 70 72 69 6e 74 20 22 3b 20         print "; 
09f0: 4d 6f 76 65 6d 65 6e 74 3a 22 2c 20 63 6f 6d 70  Movement:", comp
0a00: 5f 6e 61 6d 65 0a 20 20 20 20 20 20 20 20 66 6f  _name.        fo
0a10: 72 20 69 6e 73 74 72 5f 6e 61 6d 65 2c 20 69 6e  r instr_name, in
0a20: 73 74 72 20 69 6e 20 63 6f 6d 70 6f 73 69 74 69  str in compositi
0a30: 6f 6e 5b 63 6f 6d 70 5f 6e 61 6d 65 5d 2e 69 74  on[comp_name].it
0a40: 65 72 69 74 65 6d 73 28 29 3a 0a 20 20 20 20 20  eritems():.     
0a50: 20 20 20 20 20 20 20 63 6f 6d 70 6f 73 69 74 69         compositi
0a60: 6f 6e 5b 63 6f 6d 70 5f 6e 61 6d 65 5d 5b 69 6e  on[comp_name][in
0a70: 73 74 72 5f 6e 61 6d 65 5d 5b 22 73 63 6f 72 65  str_name]["score
0a80: 22 5d 20 3d 20 74 72 61 6e 73 6c 69 74 65 72 61  "] = translitera
0a90: 74 65 5f 73 63 6f 72 65 28 63 6f 6d 70 6f 73 69  te_score(composi
0aa0: 74 69 6f 6e 5b 63 6f 6d 70 5f 6e 61 6d 65 5d 5b  tion[comp_name][
0ab0: 69 6e 73 74 72 5f 6e 61 6d 65 5d 5b 22 73 63 6f  instr_name]["sco
0ac0: 72 65 22 5d 2c 20 6b 65 79 29 0a 23 20 20 20 20  re"], key).#    
0ad0: 20 20 20 20 20 20 20 20 70 72 69 6e 74 20 22 5c          print "\
0ae0: 6e 4d 6f 76 65 6d 65 6e 74 20 25 73 20 69 6e 73  nMovement %s ins
0af0: 74 72 75 6d 65 6e 74 20 25 73 22 20 25 20 28 63  trument %s" % (c
0b00: 6f 6d 70 5f 6e 61 6d 65 2c 20 69 6e 73 74 72 5f  omp_name, instr_
0b10: 6e 61 6d 65 29 0a 23 20 20 20 20 20 20 20 20 20  name).#         
0b20: 20 20 20 70 72 69 6e 74 20 63 6f 6d 70 6f 73 69     print composi
0b30: 74 69 6f 6e 5b 63 6f 6d 70 5f 6e 61 6d 65 5d 5b  tion[comp_name][
0b40: 69 6e 73 74 72 5f 6e 61 6d 65 5d 5b 22 73 63 6f  instr_name]["sco
0b50: 72 65 22 5d 20 0a 20 20 20 20 20 20 20 20 20 20  re"] .          
0b60: 20 20 66 69 6e 61 6c 5f 73 63 6f 72 65 20 3d 20    final_score = 
0b70: 67 65 6e 65 72 61 74 65 5f 63 73 6f 75 6e 64 5f  generate_csound_
0b80: 73 63 6f 72 65 28 63 6f 6d 70 6f 73 69 74 69 6f  score(compositio
0b90: 6e 5b 63 6f 6d 70 5f 6e 61 6d 65 5d 5b 69 6e 73  n[comp_name][ins
0ba0: 74 72 5f 6e 61 6d 65 5d 5b 22 73 63 6f 72 65 22  tr_name]["score"
0bb0: 5d 2c 20 63 6f 6d 70 6f 73 69 74 69 6f 6e 5b 63  ], composition[c
0bc0: 6f 6d 70 5f 6e 61 6d 65 5d 5b 69 6e 73 74 72 5f  omp_name][instr_
0bd0: 6e 61 6d 65 5d 5b 22 73 63 6f 72 65 5f 6c 69 6e  name]["score_lin
0be0: 65 22 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20  e"]).           
0bf0: 20 66 6f 72 20 6c 69 6e 65 20 69 6e 20 66 69 6e   for line in fin
0c00: 61 6c 5f 73 63 6f 72 65 3a 0a 20 20 20 20 20 20  al_score:.      
0c10: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 20            print 
0c20: 6c 69 6e 65 0a 20 20 20 20 20 20 20 20 20 20 20  line.           
0c30: 20 0a 0a 64 65 66 20 6d 61 6b 65 5f 73 63 61 6c   ..def make_scal
0c40: 65 28 6b 65 79 29 3a 0a 20 20 20 20 6e 6f 74 65  e(key):.    note
0c50: 73 20 3d 20 5b 22 41 22 2c 20 22 41 23 22 2c 20  s = ["A", "A#", 
0c60: 22 42 22 2c 20 22 43 22 2c 20 22 43 23 22 2c 20  "B", "C", "C#", 
0c70: 22 44 22 2c 20 22 44 23 22 2c 20 22 45 22 2c 20  "D", "D#", "E", 
0c80: 22 46 22 2c 20 22 46 23 22 2c 20 22 47 22 2c 20  "F", "F#", "G", 
0c90: 22 47 23 22 5d 0a 20 20 20 20 73 63 61 6c 65 20  "G#"].    scale 
0ca0: 3d 20 5b 6b 65 79 5d 0a 20 20 20 20 70 6f 73 20  = [key].    pos 
0cb0: 3d 20 6e 6f 74 65 73 2e 69 6e 64 65 78 28 6b 65  = notes.index(ke
0cc0: 79 29 0a 20 20 20 20 70 72 6f 67 72 65 73 73 69  y).    progressi
0cd0: 6f 6e 20 3d 20 5b 32 2c 32 2c 31 2c 32 2c 32 2c  on = [2,2,1,2,2,
0ce0: 32 2c 31 5d 0a 20 20 20 20 66 6f 72 20 70 20 69  2,1].    for p i
0cf0: 6e 20 70 72 6f 67 72 65 73 73 69 6f 6e 3a 0a 20  n progression:. 
0d00: 20 20 20 20 20 20 20 70 6f 73 20 3d 20 28 70 6f         pos = (po
0d10: 73 20 2b 20 70 29 20 25 20 31 32 0a 20 20 20 20  s + p) % 12.    
0d20: 20 20 20 20 73 63 61 6c 65 2e 61 70 70 65 6e 64      scale.append
0d30: 28 6e 6f 74 65 73 5b 70 6f 73 5d 29 0a 20 20 20  (notes[pos]).   
0d40: 20 72 65 74 75 72 6e 20 73 63 61 6c 65 0a 0a 0a   return scale...
0d50: 64 65 66 20 67 65 6e 65 72 61 74 65 5f 73 63 6f  def generate_sco
0d60: 72 65 28 73 63 6f 72 65 2c 20 67 72 61 6d 6d 61  re(score, gramma
0d70: 72 73 29 3a 0a 20 20 20 20 77 68 69 6c 65 20 31  rs):.    while 1
0d80: 3a 0a 20 20 20 20 20 20 20 20 66 6f 75 6e 64 5f  :.        found_
0d90: 73 75 62 73 74 69 74 75 74 69 6f 6e 20 3d 20 46  substitution = F
0da0: 61 6c 73 65 0a 20 20 20 20 20 20 20 20 66 6f 72  alse.        for
0db0: 20 6b 65 79 2c 76 61 6c 75 65 20 69 6e 20 67 72   key,value in gr
0dc0: 61 6d 6d 61 72 73 2e 69 74 65 72 69 74 65 6d 73  ammars.iteritems
0dd0: 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  ():.            
0de0: 69 66 20 73 63 6f 72 65 2e 66 69 6e 64 28 6b 65  if score.find(ke
0df0: 79 29 20 21 3d 20 2d 31 3a 0a 20 20 20 20 20 20  y) != -1:.      
0e00: 20 20 20 20 20 20 20 20 20 20 66 6f 75 6e 64 5f            found_
0e10: 73 75 62 73 74 69 74 75 74 69 6f 6e 20 3d 20 54  substitution = T
0e20: 72 75 65 0a 20 20 20 20 20 20 20 20 20 20 20 20  rue.            
0e30: 20 20 20 20 77 68 69 6c 65 20 73 63 6f 72 65 2e      while score.
0e40: 66 69 6e 64 28 6b 65 79 29 20 21 3d 20 2d 31 3a  find(key) != -1:
0e50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0e60: 20 20 20 20 20 73 63 6f 72 65 20 3d 20 73 63 6f       score = sco
0e70: 72 65 2e 72 65 70 6c 61 63 65 28 6b 65 79 2c 20  re.replace(key, 
0e80: 72 61 6e 64 6f 6d 2e 63 68 6f 69 63 65 28 67 72  random.choice(gr
0e90: 61 6d 6d 61 72 73 5b 6b 65 79 5d 29 2c 20 31 29  ammars[key]), 1)
0ea0: 0a 23 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .#              
0eb0: 20 20 20 20 20 20 70 72 69 6e 74 20 73 63 6f 65        print scoe
0ec0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0ed0: 20 20 20 20 20 69 66 20 6c 65 6e 28 73 63 6f 72       if len(scor
0ee0: 65 2e 73 70 6c 69 74 28 29 29 20 3e 20 32 30 30  e.split()) > 200
0ef0: 30 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  0:.             
0f00: 20 20 20 20 20 20 20 20 20 20 20 66 6f 72 20 6b             for k
0f10: 20 69 6e 20 67 72 61 6d 6d 61 72 73 2e 6b 65 79   in grammars.key
0f20: 73 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  s():.           
0f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f40: 20 73 63 6f 72 65 20 3d 20 73 63 6f 72 65 2e 72   score = score.r
0f50: 65 70 6c 61 63 65 28 6b 2c 20 22 22 29 0a 20 20  eplace(k, "").  
0f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f70: 20 20 20 20 20 20 72 65 74 75 72 6e 20 73 63 6f        return sco
0f80: 72 65 0a 20 20 20 20 20 20 20 20 69 66 20 66 6f  re.        if fo
0f90: 75 6e 64 5f 73 75 62 73 74 69 74 75 74 69 6f 6e  und_substitution
0fa0: 20 69 73 20 46 61 6c 73 65 3a 0a 20 20 20 20 20   is False:.     
0fb0: 20 20 20 20 20 20 20 62 72 65 61 6b 0a 20 20 20         break.   
0fc0: 20 72 65 74 75 72 6e 20 73 63 6f 72 65 0a 0a 64   return score..d
0fd0: 65 66 20 74 72 61 6e 73 6c 69 74 65 72 61 74 65  ef transliterate
0fe0: 5f 73 63 6f 72 65 28 73 63 6f 72 65 2c 20 6b 65  _score(score, ke
0ff0: 79 29 3a 0a 20 20 20 20 73 63 61 6c 65 20 3d 20  y):.    scale = 
1000: 6d 61 6b 65 5f 73 63 61 6c 65 28 6b 65 79 29 0a  make_scale(key).
1010: 20 20 20 20 73 63 61 6c 65 5f 63 6f 6e 76 65 72      scale_conver
1020: 73 69 6f 6e 20 3d 20 7b 0a 20 20 20 20 20 20 20  sion = {.       
1030: 20 22 49 22 3a 20 31 2c 0a 20 20 20 20 20 20 20   "I": 1,.       
1040: 20 22 49 49 22 3a 20 32 2c 0a 20 20 20 20 20 20   "II": 2,.      
1050: 20 20 22 49 49 49 22 3a 20 33 2c 0a 20 20 20 20    "III": 3,.    
1060: 20 20 20 20 22 49 56 22 3a 20 34 2c 0a 20 20 20      "IV": 4,.   
1070: 20 20 20 20 20 22 56 22 3a 20 35 2c 0a 20 20 20       "V": 5,.   
1080: 20 20 20 20 20 22 56 49 22 3a 20 36 2c 0a 20 20       "VI": 6,.  
1090: 20 20 20 20 20 20 22 56 49 49 22 3a 20 37 2c 0a        "VII": 7,.
10a0: 20 20 20 20 20 20 20 20 22 56 49 49 49 22 3a 20          "VIII": 
10b0: 38 2c 0a 20 20 20 20 7d 0a 20 20 20 20 6b 65 79  8,.    }.    key
10c0: 65 64 5f 73 63 6f 72 65 20 3d 20 5b 5d 0a 20 20  ed_score = [].  
10d0: 20 20 66 6f 72 20 69 20 69 6e 20 72 61 6e 67 65    for i in range
10e0: 28 6c 65 6e 28 73 63 6f 72 65 29 29 3a 0a 20 20  (len(score)):.  
10f0: 20 20 20 20 20 20 69 66 20 69 73 69 6e 73 74 61        if isinsta
1100: 6e 63 65 28 73 63 6f 72 65 5b 69 5d 2c 20 70 61  nce(score[i], pa
1110: 72 73 65 2e 4e 6f 74 65 29 3a 0a 20 20 20 20 20  rse.Note):.     
1120: 20 20 20 20 20 20 20 73 63 6f 72 65 5b 69 5d 2e         score[i].
1130: 76 61 6c 75 65 20 3d 20 73 63 61 6c 65 5b 73 63  value = scale[sc
1140: 61 6c 65 5f 63 6f 6e 76 65 72 73 69 6f 6e 5b 73  ale_conversion[s
1150: 63 6f 72 65 5b 69 5d 2e 76 61 6c 75 65 5d 2d 31  core[i].value]-1
1160: 5d 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 69  ].        elif i
1170: 73 69 6e 73 74 61 6e 63 65 28 73 63 6f 72 65 5b  sinstance(score[
1180: 69 5d 2c 20 70 61 72 73 65 2e 43 68 6f 72 64 29  i], parse.Chord)
1190: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 68  :.            ch
11a0: 6f 72 64 20 3d 20 5b 5d 0a 20 20 20 20 20 20 20  ord = [].       
11b0: 20 20 20 20 20 72 6f 6f 74 5f 6e 6f 74 65 5f 69       root_note_i
11c0: 6e 64 65 78 20 3d 20 73 63 61 6c 65 2e 69 6e 64  ndex = scale.ind
11d0: 65 78 28 6b 65 79 29 20 2b 20 73 63 61 6c 65 5f  ex(key) + scale_
11e0: 63 6f 6e 76 65 72 73 69 6f 6e 5b 73 63 6f 72 65  conversion[score
11f0: 5b 69 5d 2e 76 61 6c 75 65 5d 0a 20 20 20 20 20  [i].value].     
1200: 20 20 20 20 20 20 20 63 68 6f 72 64 2e 61 70 70         chord.app
1210: 65 6e 64 28 73 63 61 6c 65 5b 72 6f 6f 74 5f 6e  end(scale[root_n
1220: 6f 74 65 5f 69 6e 64 65 78 5d 29 0a 20 20 20 20  ote_index]).    
1230: 20 20 20 20 20 20 20 20 63 68 6f 72 64 2e 61 70          chord.ap
1240: 70 65 6e 64 28 73 63 61 6c 65 5b 28 72 6f 6f 74  pend(scale[(root
1250: 5f 6e 6f 74 65 5f 69 6e 64 65 78 2b 33 29 20 25  _note_index+3) %
1260: 20 38 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20   8]).           
1270: 20 69 66 20 73 63 6f 72 65 5b 69 5d 2e 63 68 6f   if score[i].cho
1280: 72 64 5f 74 79 70 65 20 3d 3d 20 22 6d 22 3a 20  rd_type == "m": 
1290: 20 23 20 4d 69 6e 6f 72 20 63 68 6f 72 64 73 2c   # Minor chords,
12a0: 20 66 6c 61 74 20 74 68 65 20 35 74 68 0a 20 20   flat the 5th.  
12b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63 68                ch
12c0: 6f 72 64 2e 61 70 70 65 6e 64 28 73 63 61 6c 65  ord.append(scale
12d0: 5b 28 72 6f 6f 74 5f 6e 6f 74 65 5f 69 6e 64 65  [(root_note_inde
12e0: 78 2b 34 29 20 25 20 38 5d 29 0a 20 20 20 20 20  x+4) % 8]).     
12f0: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
1300: 20 20 20 20 20 20 20 20 20 20 20 20 20 63 68 6f               cho
1310: 72 64 2e 61 70 70 65 6e 64 28 73 63 61 6c 65 5b  rd.append(scale[
1320: 28 72 6f 6f 74 5f 6e 6f 74 65 5f 69 6e 64 65 78  (root_note_index
1330: 2b 35 29 20 25 20 38 5d 29 0a 20 20 20 20 20 20  +5) % 8]).      
1340: 20 20 20 20 20 20 73 63 6f 72 65 5b 69 5d 2e 63        score[i].c
1350: 68 6f 72 64 20 3d 20 63 68 6f 72 64 0a 20 20 20  hord = chord.   
1360: 20 20 20 20 20 65 6c 69 66 20 69 73 69 6e 73 74       elif isinst
1370: 61 6e 63 65 28 73 63 6f 72 65 5b 69 5d 2c 20 70  ance(score[i], p
1380: 61 72 73 65 2e 52 65 73 74 29 3a 0a 20 20 20 20  arse.Rest):.    
1390: 20 20 20 20 20 20 20 20 70 61 73 73 0a 20 20 20          pass.   
13a0: 20 72 65 74 75 72 6e 20 73 63 6f 72 65 0a 0a 0a   return score...
13b0: 64 65 66 20 67 65 6e 65 72 61 74 65 5f 63 73 6f  def generate_cso
13c0: 75 6e 64 5f 73 63 6f 72 65 28 73 63 6f 72 65 2c  und_score(score,
13d0: 20 73 63 6f 72 65 5f 6c 69 6e 65 29 3a 0a 20 20   score_line):.  
13e0: 20 20 63 73 6f 75 6e 64 5f 6e 6f 74 65 5f 76 61    csound_note_va
13f0: 6c 75 65 73 20 3d 20 7b 0a 20 20 20 20 20 20 20  lues = {.       
1400: 20 22 43 22 3a 20 22 30 30 22 2c 0a 20 20 20 20   "C": "00",.    
1410: 20 20 20 20 22 43 23 22 3a 20 22 30 31 22 2c 0a      "C#": "01",.
1420: 20 20 20 20 20 20 20 20 22 44 22 3a 20 22 30 32          "D": "02
1430: 22 2c 0a 20 20 20 20 20 20 20 20 22 44 23 22 3a  ",.        "D#":
1440: 20 22 30 33 22 2c 0a 20 20 20 20 20 20 20 20 22   "03",.        "
1450: 45 22 3a 20 22 30 34 22 2c 0a 20 20 20 20 20 20  E": "04",.      
1460: 20 20 22 46 22 3a 20 22 30 35 22 2c 0a 20 20 20    "F": "05",.   
1470: 20 20 20 20 20 22 46 23 22 3a 20 22 30 36 22 2c       "F#": "06",
1480: 0a 20 20 20 20 20 20 20 20 22 47 22 3a 20 22 30  .        "G": "0
1490: 37 22 2c 0a 20 20 20 20 20 20 20 20 22 47 23 22  7",.        "G#"
14a0: 3a 20 22 30 38 22 2c 0a 20 20 20 20 20 20 20 20  : "08",.        
14b0: 22 41 22 3a 20 22 30 39 22 2c 0a 20 20 20 20 20  "A": "09",.     
14c0: 20 20 20 22 41 23 22 3a 20 22 31 30 22 2c 0a 20     "A#": "10",. 
14d0: 20 20 20 20 20 20 20 22 42 22 3a 20 22 31 31 22         "B": "11"
14e0: 2c 0a 20 20 20 20 7d 0a 20 20 20 20 63 73 6f 75  ,.    }.    csou
14f0: 6e 64 5f 73 63 6f 72 65 20 3d 20 5b 5d 0a 20 20  nd_score = [].  
1500: 20 20 66 6f 72 20 74 6f 6b 65 6e 20 69 6e 20 73    for token in s
1510: 63 6f 72 65 3a 0a 20 20 20 20 20 20 20 20 69 66  core:.        if
1520: 20 69 73 69 6e 73 74 61 6e 63 65 28 74 6f 6b 65   isinstance(toke
1530: 6e 2c 20 70 61 72 73 65 2e 43 68 6f 72 64 29 3a  n, parse.Chord):
1540: 20 20 23 20 43 68 6f 72 64 73 0a 20 20 20 20 20    # Chords.     
1550: 20 20 20 20 20 20 20 66 6f 72 20 6e 6f 74 65 20         for note 
1560: 69 6e 20 74 6f 6b 65 6e 2e 63 68 6f 72 64 3a 20  in token.chord: 
1570: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1580: 20 6e 6f 74 65 20 3d 20 63 73 6f 75 6e 64 5f 6e   note = csound_n
1590: 6f 74 65 5f 76 61 6c 75 65 73 5b 6e 6f 74 65 5d  ote_values[note]
15a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
15b0: 20 63 73 6f 75 6e 64 5f 73 63 6f 72 65 2e 61 70   csound_score.ap
15c0: 70 65 6e 64 28 73 63 6f 72 65 5f 6c 69 6e 65 20  pend(score_line 
15d0: 25 20 7b 22 74 69 6d 65 22 3a 20 74 6f 6b 65 6e  % {"time": token
15e0: 2e 74 69 6d 65 2c 20 22 6f 63 74 61 76 65 22 3a  .time, "octave":
15f0: 20 74 6f 6b 65 6e 2e 6f 63 74 61 76 65 2c 20 22   token.octave, "
1600: 6e 6f 74 65 22 3a 20 6e 6f 74 65 2c 20 22 64 75  note": note, "du
1610: 72 61 74 69 6f 6e 22 3a 20 74 6f 6b 65 6e 2e 64  ration": token.d
1620: 75 72 61 74 69 6f 6e 7d 29 0a 20 20 20 20 20 20  uration}).      
1630: 20 20 65 6c 69 66 20 69 73 69 6e 73 74 61 6e 63    elif isinstanc
1640: 65 28 74 6f 6b 65 6e 2c 20 70 61 72 73 65 2e 4e  e(token, parse.N
1650: 6f 74 65 29 3a 20 20 23 20 49 6e 64 69 76 69 64  ote):  # Individ
1660: 75 61 6c 20 6e 6f 74 65 73 0a 20 20 20 20 20 20  ual notes.      
1670: 20 20 20 20 20 20 6e 6f 74 65 20 3d 20 63 73 6f        note = cso
1680: 75 6e 64 5f 6e 6f 74 65 5f 76 61 6c 75 65 73 5b  und_note_values[
1690: 74 6f 6b 65 6e 2e 76 61 6c 75 65 5d 0a 20 20 20  token.value].   
16a0: 20 20 20 20 20 20 20 20 20 63 73 6f 75 6e 64 5f           csound_
16b0: 73 63 6f 72 65 2e 61 70 70 65 6e 64 28 73 63 6f  score.append(sco
16c0: 72 65 5f 6c 69 6e 65 20 25 20 7b 22 74 69 6d 65  re_line % {"time
16d0: 22 3a 20 74 6f 6b 65 6e 2e 74 69 6d 65 2c 20 22  ": token.time, "
16e0: 6f 63 74 61 76 65 22 3a 20 74 6f 6b 65 6e 2e 6f  octave": token.o
16f0: 63 74 61 76 65 2c 20 22 6e 6f 74 65 22 3a 20 6e  ctave, "note": n
1700: 6f 74 65 2c 20 22 64 75 72 61 74 69 6f 6e 22 3a  ote, "duration":
1710: 20 74 6f 6b 65 6e 2e 64 75 72 61 74 69 6f 6e 7d   token.duration}
1720: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 63 73 6f  ).    return cso
1730: 75 6e 64 5f 73 63 6f 72 65 0a 0a 0a 69 66 20 5f  und_score...if _
1740: 5f 6e 61 6d 65 5f 5f 20 3d 3d 20 22 5f 5f 6d 61  _name__ == "__ma
1750: 69 6e 5f 5f 22 3a 20 6d 61 69 6e 28 29 20 0a     in__": main() .