spiffyscore

Hex Artifact Content
Login

Artifact d386f64212558e4478d0b1ebdb1d9dcf1a886132:


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 69  d(time.time()).i
0080: 6d 70 6f 72 74 20 70 61 72 73 65 0a 0a 64 65 66  mport parse..def
0090: 20 6d 61 69 6e 28 29 3a 0a 20 20 20 20 6b 65 79   main():.    key
00a0: 20 3d 20 22 41 22 0a 20 20 20 20 62 70 73 20 3d   = "A".    bps =
00b0: 20 36 30 2f 36 30 0a 20 20 20 20 74 65 6d 70 6f   60/60.    tempo
00c0: 20 3d 20 31 2f 62 70 73 0a 20 20 20 20 6d 61 78   = 1/bps.    max
00d0: 5f 64 75 72 61 74 69 6f 6e 20 3d 20 31 0a 0a 20  _duration = 1.. 
00e0: 20 20 20 63 6f 6d 70 6f 73 69 74 69 6f 6e 20 3d     composition =
00f0: 20 7b 0a 20 20 20 20 20 20 20 20 22 6f 76 65 72   {.        "over
0100: 76 69 65 77 22 3a 20 7b 0a 20 20 20 20 20 20 20  view": {.       
0110: 20 20 20 20 20 22 6d 65 6c 6f 64 79 22 3a 20 7b       "melody": {
0120: 20 20 23 20 49 6e 73 74 72 75 6d 65 6e 74 20 27    # Instrument '
0130: 6d 65 6c 6f 64 79 27 0a 20 20 20 20 20 20 20 20  melody'.        
0140: 20 20 20 20 20 20 20 20 22 73 63 6f 72 65 5f 6c          "score_l
0150: 69 6e 65 22 3a 20 22 69 32 20 25 28 74 69 6d 65  ine": "i2 %(time
0160: 29 66 20 25 28 64 75 72 61 74 69 6f 6e 29 66 20  )f %(duration)f 
0170: 37 30 30 30 20 25 28 6f 63 74 61 76 65 29 64 2e  7000 %(octave)d.
0180: 25 28 6e 6f 74 65 29 73 20 32 22 2c 0a 20 20 20  %(note)s 2",.   
0190: 20 20 20 20 20 20 20 20 20 20 20 20 20 22 6f 63               "oc
01a0: 74 61 76 65 22 3a 20 38 2c 0a 20 20 20 20 20 20  tave": 8,.      
01b0: 20 20 20 20 20 20 20 20 20 20 22 64 75 72 61 74            "durat
01c0: 69 6f 6e 22 3a 20 34 30 2c 0a 20 20 20 20 20 20  ion": 40,.      
01d0: 20 20 20 20 20 20 20 20 20 20 22 67 72 61 6d 6d            "gramm
01e0: 61 72 73 22 3a 20 7b 20 20 23 20 4e 6f 74 65 73  ars": {  # Notes
01f0: 20 66 6f 72 20 74 68 69 73 20 69 6e 73 74 72 75   for this instru
0200: 6d 65 6e 74 20 74 6f 20 75 73 65 20 69 6e 20 74  ment to use in t
0210: 68 69 73 20 70 69 65 63 65 0a 20 20 20 20 20 20  his piece.      
0220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22 75                "u
0230: 22 3a 20 5b 22 43 20 47 2f 32 20 47 2f 32 20 47  ": ["C G/2 G/2 G
0240: 2f 32 20 43 20 42 2c 20 46 27 20 43 20 46 20 43  /2 C B, F' C F C
0250: 20 42 20 46 22 5d 2c 0a 23 20 20 20 20 20 20 20   B F"],.#       
0260: 20 20 20 20 20 20 20 20 20 20 20 20 20 22 77 22               "w"
0270: 3a 20 5b 27 45 2f 34 20 41 2f 34 20 44 2f 34 20  : ['E/4 A/4 D/4 
0280: 47 2f 34 20 46 2f 34 20 46 2f 34 20 42 32 27 5d  G/4 F/4 F/4 B2']
0290: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
02a0: 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 20 20 20    },.           
02b0: 20 20 20 20 20 22 73 63 6f 72 65 22 3a 20 22 75       "score": "u
02c0: 20 75 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20   u",.           
02d0: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7d 2c 0a 20   },.        },. 
02e0: 20 20 20 7d 0a 0a 20 20 20 20 6d 61 78 5f 74 20     }..    max_t 
02f0: 3d 20 30 20 20 23 20 6d 61 78 20 74 69 6d 65 20  = 0  # max time 
0300: 65 6e 63 6f 75 6e 74 65 72 65 64 20 73 6f 20 66  encountered so f
0310: 61 72 2e 20 55 73 65 64 20 66 6f 72 20 6d 6f 76  ar. Used for mov
0320: 65 6d 65 6e 74 20 74 69 6d 69 6e 67 0a 20 20 20  ement timing.   
0330: 20 70 72 6f 67 72 65 73 73 69 6f 6e 20 3d 20 22   progression = "
0340: 6f 76 65 72 76 69 65 77 22 0a 23 20 20 20 20 70  overview".#    p
0350: 72 6f 67 72 65 73 73 69 6f 6e 20 3d 20 22 7a 65  rogression = "ze
0360: 6c 64 61 31 22 0a 20 20 20 20 66 6f 72 20 63 6f  lda1".    for co
0370: 6d 70 5f 6e 61 6d 65 20 69 6e 20 70 72 6f 67 72  mp_name in progr
0380: 65 73 73 69 6f 6e 2e 73 70 6c 69 74 28 29 3a 0a  ession.split():.
0390: 20 20 20 20 20 20 20 20 63 6f 6d 70 5f 73 74 61          comp_sta
03a0: 72 74 5f 74 69 6d 65 20 3d 20 6d 61 78 5f 74 0a  rt_time = max_t.
03b0: 20 20 20 20 20 20 20 20 66 6f 72 20 69 6e 73 74          for inst
03c0: 72 5f 6e 61 6d 65 2c 20 69 6e 73 74 72 20 69 6e  r_name, instr in
03d0: 20 63 6f 6d 70 6f 73 69 74 69 6f 6e 5b 63 6f 6d   composition[com
03e0: 70 5f 6e 61 6d 65 5d 2e 69 74 65 72 69 74 65 6d  p_name].iteritem
03f0: 73 28 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20  s():.           
0400: 20 67 65 6e 65 72 61 74 65 64 5f 73 63 6f 72 65   generated_score
0410: 20 3d 20 67 65 6e 65 72 61 74 65 5f 73 63 6f 72   = generate_scor
0420: 65 28 69 6e 73 74 72 5b 22 73 63 6f 72 65 22 5d  e(instr["score"]
0430: 2c 20 69 6e 73 74 72 5b 22 67 72 61 6d 6d 61 72  , instr["grammar
0440: 73 22 5d 29 20 20 23 20 46 69 6c 6c 20 69 6e 20  s"])  # Fill in 
0450: 74 68 65 20 73 63 6f 72 65 73 20 62 79 20 67 65  the scores by ge
0460: 6e 65 72 61 74 69 6e 67 20 74 68 65 6d 20 62 61  nerating them ba
0470: 73 65 64 20 6f 6e 20 74 68 65 20 67 72 61 6d 6d  sed on the gramm
0480: 61 72 73 0a 23 20 20 20 20 20 20 20 20 20 20 20  ars.#           
0490: 20 70 72 69 6e 74 20 67 65 6e 65 72 61 74 65 64   print generated
04a0: 5f 73 63 6f 72 65 0a 20 20 20 20 20 20 20 20 20  _score.         
04b0: 20 20 20 70 72 69 6e 74 20 67 65 6e 65 72 61 74     print generat
04c0: 65 64 5f 73 63 6f 72 65 0a 20 20 20 20 20 20 20  ed_score.       
04d0: 20 20 20 20 20 73 63 6f 72 65 20 3d 20 70 61 72       score = par
04e0: 73 65 2e 70 61 72 73 65 28 67 65 6e 65 72 61 74  se.parse(generat
04f0: 65 64 5f 73 63 6f 72 65 2c 20 64 65 66 61 75 6c  ed_score, defaul
0500: 74 5f 6f 63 74 61 76 65 3d 69 6e 73 74 72 5b 22  t_octave=instr["
0510: 6f 63 74 61 76 65 22 5d 29 20 20 23 20 52 65 74  octave"])  # Ret
0520: 75 72 6e 20 4e 6f 64 65 2f 43 68 6f 72 64 20 6f  urn Node/Chord o
0530: 62 6a 65 63 74 73 0a 0a 20 20 20 20 20 20 20 20  bjects..        
0540: 20 20 20 20 23 20 47 65 6e 65 72 61 74 65 20 74      # Generate t
0550: 69 6d 65 73 74 61 6d 70 73 20 66 6f 72 20 74 68  imestamps for th
0560: 65 20 6e 6f 74 65 73 20 0a 20 20 20 20 20 20 20  e notes .       
0570: 20 20 20 20 20 74 20 3d 20 63 6f 6d 70 5f 73 74       t = comp_st
0580: 61 72 74 5f 74 69 6d 65 0a 20 20 20 20 20 20 20  art_time.       
0590: 20 20 20 20 20 66 6f 72 20 6e 6f 74 65 20 69 6e       for note in
05a0: 20 72 61 6e 67 65 28 6c 65 6e 28 73 63 6f 72 65   range(len(score
05b0: 29 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  )):.            
05c0: 20 20 20 20 73 63 6f 72 65 5b 6e 6f 74 65 5d 2e      score[note].
05d0: 74 69 6d 65 20 3d 20 74 0a 20 20 20 20 20 20 20  time = t.       
05e0: 20 20 20 20 20 20 20 20 20 73 63 6f 72 65 5b 6e           score[n
05f0: 6f 74 65 5d 2e 64 75 72 61 74 69 6f 6e 20 2a 3d  ote].duration *=
0600: 20 74 65 6d 70 6f 0a 20 20 20 20 20 20 20 20 20   tempo.         
0610: 20 20 20 20 20 20 20 74 20 2b 3d 20 73 63 6f 72         t += scor
0620: 65 5b 6e 6f 74 65 5d 2e 64 75 72 61 74 69 6f 6e  e[note].duration
0630: 0a 23 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .#              
0640: 20 20 70 72 69 6e 74 20 22 74 69 6d 65 20 64 69    print "time di
0650: 66 66 65 72 65 6e 63 65 20 3d 22 2c 20 74 2d 63  fference =", t-c
0660: 6f 6d 70 5f 73 74 61 72 74 5f 74 69 6d 65 0a 23  omp_start_time.#
0670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0680: 70 72 69 6e 74 20 22 69 6e 73 74 72 75 6d 65 6e  print "instrumen
0690: 74 20 64 75 72 61 74 69 6f 6e 20 3d 22 2c 63 6f  t duration =",co
06a0: 6d 70 6f 73 69 74 69 6f 6e 5b 63 6f 6d 70 5f 6e  mposition[comp_n
06b0: 61 6d 65 5d 5b 69 6e 73 74 72 5f 6e 61 6d 65 5d  ame][instr_name]
06c0: 5b 22 64 75 72 61 74 69 6f 6e 22 5d 0a 20 20 20  ["duration"].   
06d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20               if 
06e0: 28 74 2d 63 6f 6d 70 5f 73 74 61 72 74 5f 74 69  (t-comp_start_ti
06f0: 6d 65 29 20 3e 20 66 6c 6f 61 74 28 63 6f 6d 70  me) > float(comp
0700: 6f 73 69 74 69 6f 6e 5b 63 6f 6d 70 5f 6e 61 6d  osition[comp_nam
0710: 65 5d 5b 69 6e 73 74 72 5f 6e 61 6d 65 5d 5b 22  e][instr_name]["
0720: 64 75 72 61 74 69 6f 6e 22 5d 29 3a 0a 23 20 20  duration"]):.#  
0730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0740: 20 20 70 72 69 6e 74 20 22 68 65 72 65 22 0a 20    print "here". 
0750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0760: 20 20 20 73 63 6f 72 65 20 3d 20 73 63 6f 72 65     score = score
0770: 5b 3a 6e 6f 74 65 5d 0a 20 20 20 20 20 20 20 20  [:note].        
0780: 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61              brea
0790: 6b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k.              
07a0: 20 20 6d 61 78 5f 74 20 3d 20 74 20 69 66 20 74    max_t = t if t
07b0: 20 3e 20 6d 61 78 5f 74 20 65 6c 73 65 20 6d 61   > max_t else ma
07c0: 78 5f 74 0a 20 20 20 20 20 20 20 20 20 20 20 20  x_t.            
07d0: 63 6f 6d 70 6f 73 69 74 69 6f 6e 5b 63 6f 6d 70  composition[comp
07e0: 5f 6e 61 6d 65 5d 5b 69 6e 73 74 72 5f 6e 61 6d  _name][instr_nam
07f0: 65 5d 5b 22 73 63 6f 72 65 22 5d 20 3d 20 73 63  e]["score"] = sc
0800: 6f 72 65 0a 0a 20 20 20 20 23 20 4d 75 73 74 20  ore..    # Must 
0810: 62 65 20 64 6f 6e 65 20 61 66 74 65 72 20 61 6c  be done after al
0820: 6c 20 6e 6f 74 65 20 74 69 6d 65 73 20 6b 65 79  l note times key
0830: 65 64 20 69 6e 2c 20 65 6c 73 65 20 79 6f 75 20  ed in, else you 
0840: 63 61 6e 27 74 20 63 6f 6f 72 64 69 6e 61 74 65  can't coordinate
0850: 20 6d 65 6c 6f 64 69 65 73 20 77 69 74 68 20 74   melodies with t
0860: 68 65 20 72 68 79 74 68 6d 20 63 68 6f 72 64 73  he rhythm chords
0870: 0a 20 20 20 20 70 72 69 6e 74 20 27 27 27 66 31  .    print '''f1
0880: 20 20 30 20 20 35 31 32 20 20 31 30 20 20 31 0a    0  512  10  1.
0890: 20 20 20 20 20 20 20 20 20 20 20 20 66 32 20 30              f2 0
08a0: 20 38 31 39 32 20 31 30 20 2e 32 34 20 2e 36 34   8192 10 .24 .64
08b0: 20 2e 38 38 20 2e 37 36 20 2e 30 36 20 2e 35 20   .88 .76 .06 .5 
08c0: 2e 33 34 20 2e 30 38 0a 20 20 20 20 20 20 20 20  .34 .08.        
08d0: 20 20 20 20 66 33 20 30 20 31 30 32 35 20 31 30      f3 0 1025 10
08e0: 20 31 0a 20 20 20 20 27 27 27 0a 20 20 20 20 66   1.    '''.    f
08f0: 6f 72 20 63 6f 6d 70 5f 6e 61 6d 65 20 69 6e 20  or comp_name in 
0900: 70 72 6f 67 72 65 73 73 69 6f 6e 2e 73 70 6c 69  progression.spli
0910: 74 28 29 3a 0a 20 20 20 20 20 20 20 20 70 72 69  t():.        pri
0920: 6e 74 20 22 3b 20 4d 6f 76 65 6d 65 6e 74 3a 22  nt "; Movement:"
0930: 2c 20 63 6f 6d 70 5f 6e 61 6d 65 0a 20 20 20 20  , comp_name.    
0940: 20 20 20 20 66 6f 72 20 69 6e 73 74 72 5f 6e 61      for instr_na
0950: 6d 65 2c 20 69 6e 73 74 72 20 69 6e 20 63 6f 6d  me, instr in com
0960: 70 6f 73 69 74 69 6f 6e 5b 63 6f 6d 70 5f 6e 61  position[comp_na
0970: 6d 65 5d 2e 69 74 65 72 69 74 65 6d 73 28 29 3a  me].iteritems():
0980: 0a 23 20 20 20 20 20 20 20 20 20 20 20 20 63 6f  .#            co
0990: 6d 70 6f 73 69 74 69 6f 6e 5b 63 6f 6d 70 5f 6e  mposition[comp_n
09a0: 61 6d 65 5d 5b 69 6e 73 74 72 5f 6e 61 6d 65 5d  ame][instr_name]
09b0: 5b 22 73 63 6f 72 65 22 5d 20 3d 20 74 72 61 6e  ["score"] = tran
09c0: 73 6c 69 74 65 72 61 74 65 5f 73 63 6f 72 65 28  sliterate_score(
09d0: 63 6f 6d 70 6f 73 69 74 69 6f 6e 5b 63 6f 6d 70  composition[comp
09e0: 5f 6e 61 6d 65 5d 5b 69 6e 73 74 72 5f 6e 61 6d  _name][instr_nam
09f0: 65 5d 5b 22 73 63 6f 72 65 22 5d 2c 20 6b 65 79  e]["score"], key
0a00: 29 0a 23 20 20 20 20 20 20 20 20 20 20 20 20 70  ).#            p
0a10: 72 69 6e 74 20 22 5c 6e 4d 6f 76 65 6d 65 6e 74  rint "\nMovement
0a20: 20 25 73 20 69 6e 73 74 72 75 6d 65 6e 74 20 25   %s instrument %
0a30: 73 22 20 25 20 28 63 6f 6d 70 5f 6e 61 6d 65 2c  s" % (comp_name,
0a40: 20 69 6e 73 74 72 5f 6e 61 6d 65 29 0a 23 20 20   instr_name).#  
0a50: 20 20 20 20 20 20 20 20 20 20 70 72 69 6e 74 20            print 
0a60: 63 6f 6d 70 6f 73 69 74 69 6f 6e 5b 63 6f 6d 70  composition[comp
0a70: 5f 6e 61 6d 65 5d 5b 69 6e 73 74 72 5f 6e 61 6d  _name][instr_nam
0a80: 65 5d 5b 22 73 63 6f 72 65 22 5d 20 0a 20 20 20  e]["score"] .   
0a90: 20 20 20 20 20 20 20 20 20 66 69 6e 61 6c 5f 73           final_s
0aa0: 63 6f 72 65 20 3d 20 67 65 6e 65 72 61 74 65 5f  core = generate_
0ab0: 63 73 6f 75 6e 64 5f 73 63 6f 72 65 28 63 6f 6d  csound_score(com
0ac0: 70 6f 73 69 74 69 6f 6e 5b 63 6f 6d 70 5f 6e 61  position[comp_na
0ad0: 6d 65 5d 5b 69 6e 73 74 72 5f 6e 61 6d 65 5d 5b  me][instr_name][
0ae0: 22 73 63 6f 72 65 22 5d 2c 20 63 6f 6d 70 6f 73  "score"], compos
0af0: 69 74 69 6f 6e 5b 63 6f 6d 70 5f 6e 61 6d 65 5d  ition[comp_name]
0b00: 5b 69 6e 73 74 72 5f 6e 61 6d 65 5d 5b 22 73 63  [instr_name]["sc
0b10: 6f 72 65 5f 6c 69 6e 65 22 5d 29 0a 20 20 20 20  ore_line"]).    
0b20: 20 20 20 20 20 20 20 20 66 6f 72 20 6c 69 6e 65          for line
0b30: 20 69 6e 20 66 69 6e 61 6c 5f 73 63 6f 72 65 3a   in final_score:
0b40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0b50: 20 70 72 69 6e 74 20 6c 69 6e 65 0a 20 20 20 20   print line.    
0b60: 20 20 20 20 20 20 20 20 0a 0a 64 65 66 20 6d 61          ..def ma
0b70: 6b 65 5f 73 63 61 6c 65 28 6b 65 79 29 3a 0a 20  ke_scale(key):. 
0b80: 20 20 20 6e 6f 74 65 73 20 3d 20 5b 22 41 22 2c     notes = ["A",
0b90: 20 22 41 23 22 2c 20 22 42 22 2c 20 22 43 22 2c   "A#", "B", "C",
0ba0: 20 22 43 23 22 2c 20 22 44 22 2c 20 22 44 23 22   "C#", "D", "D#"
0bb0: 2c 20 22 45 22 2c 20 22 46 22 2c 20 22 46 23 22  , "E", "F", "F#"
0bc0: 2c 20 22 47 22 2c 20 22 47 23 22 5d 0a 20 20 20  , "G", "G#"].   
0bd0: 20 73 63 61 6c 65 20 3d 20 5b 6b 65 79 5d 0a 20   scale = [key]. 
0be0: 20 20 20 70 6f 73 20 3d 20 6e 6f 74 65 73 2e 69     pos = notes.i
0bf0: 6e 64 65 78 28 6b 65 79 29 0a 20 20 20 20 70 72  ndex(key).    pr
0c00: 6f 67 72 65 73 73 69 6f 6e 20 3d 20 5b 32 2c 32  ogression = [2,2
0c10: 2c 31 2c 32 2c 32 2c 32 2c 31 5d 0a 20 20 20 20  ,1,2,2,2,1].    
0c20: 66 6f 72 20 70 20 69 6e 20 70 72 6f 67 72 65 73  for p in progres
0c30: 73 69 6f 6e 3a 0a 20 20 20 20 20 20 20 20 70 6f  sion:.        po
0c40: 73 20 3d 20 28 70 6f 73 20 2b 20 70 29 20 25 20  s = (pos + p) % 
0c50: 31 32 0a 20 20 20 20 20 20 20 20 73 63 61 6c 65  12.        scale
0c60: 2e 61 70 70 65 6e 64 28 6e 6f 74 65 73 5b 70 6f  .append(notes[po
0c70: 73 5d 29 0a 20 20 20 20 72 65 74 75 72 6e 20 73  s]).    return s
0c80: 63 61 6c 65 0a 0a 0a 64 65 66 20 67 65 6e 65 72  cale...def gener
0c90: 61 74 65 5f 73 63 6f 72 65 28 73 63 6f 72 65 2c  ate_score(score,
0ca0: 20 67 72 61 6d 6d 61 72 73 29 3a 0a 20 20 20 20   grammars):.    
0cb0: 77 68 69 6c 65 20 31 3a 0a 20 20 20 20 20 20 20  while 1:.       
0cc0: 20 66 6f 75 6e 64 5f 73 75 62 73 74 69 74 75 74   found_substitut
0cd0: 69 6f 6e 20 3d 20 46 61 6c 73 65 0a 20 20 20 20  ion = False.    
0ce0: 20 20 20 20 66 6f 72 20 6b 65 79 2c 76 61 6c 75      for key,valu
0cf0: 65 20 69 6e 20 67 72 61 6d 6d 61 72 73 2e 69 74  e in grammars.it
0d00: 65 72 69 74 65 6d 73 28 29 3a 0a 20 20 20 20 20  eritems():.     
0d10: 20 20 20 20 20 20 20 69 66 20 73 63 6f 72 65 2e         if score.
0d20: 66 69 6e 64 28 6b 65 79 29 20 21 3d 20 2d 31 3a  find(key) != -1:
0d30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
0d40: 20 66 6f 75 6e 64 5f 73 75 62 73 74 69 74 75 74   found_substitut
0d50: 69 6f 6e 20 3d 20 54 72 75 65 0a 20 20 20 20 20  ion = True.     
0d60: 20 20 20 20 20 20 20 20 20 20 20 77 68 69 6c 65             while
0d70: 20 73 63 6f 72 65 2e 66 69 6e 64 28 6b 65 79 29   score.find(key)
0d80: 20 21 3d 20 2d 31 3a 0a 20 20 20 20 20 20 20 20   != -1:.        
0d90: 20 20 20 20 20 20 20 20 20 20 20 20 73 63 6f 72              scor
0da0: 65 20 3d 20 73 63 6f 72 65 2e 72 65 70 6c 61 63  e = score.replac
0db0: 65 28 6b 65 79 2c 20 72 61 6e 64 6f 6d 2e 63 68  e(key, random.ch
0dc0: 6f 69 63 65 28 67 72 61 6d 6d 61 72 73 5b 6b 65  oice(grammars[ke
0dd0: 79 5d 29 2c 20 31 29 0a 23 20 20 20 20 20 20 20  y]), 1).#       
0de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 72 69               pri
0df0: 6e 74 20 73 63 6f 65 0a 20 20 20 20 20 20 20 20  nt scoe.        
0e00: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 6c              if l
0e10: 65 6e 28 73 63 6f 72 65 2e 73 70 6c 69 74 28 29  en(score.split()
0e20: 29 20 3e 20 32 30 30 30 3a 0a 20 20 20 20 20 20  ) > 2000:.      
0e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e40: 20 20 66 6f 72 20 6b 20 69 6e 20 67 72 61 6d 6d    for k in gramm
0e50: 61 72 73 2e 6b 65 79 73 28 29 3a 0a 20 20 20 20  ars.keys():.    
0e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e70: 20 20 20 20 20 20 20 20 73 63 6f 72 65 20 3d 20          score = 
0e80: 73 63 6f 72 65 2e 72 65 70 6c 61 63 65 28 6b 2c  score.replace(k,
0e90: 20 22 22 29 0a 20 20 20 20 20 20 20 20 20 20 20   "").           
0ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74               ret
0eb0: 75 72 6e 20 73 63 6f 72 65 0a 20 20 20 20 20 20  urn score.      
0ec0: 20 20 69 66 20 66 6f 75 6e 64 5f 73 75 62 73 74    if found_subst
0ed0: 69 74 75 74 69 6f 6e 20 69 73 20 46 61 6c 73 65  itution is False
0ee0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 72  :.            br
0ef0: 65 61 6b 0a 20 20 20 20 72 65 74 75 72 6e 20 73  eak.    return s
0f00: 63 6f 72 65 0a 0a 64 65 66 20 74 72 61 6e 73 6c  core..def transl
0f10: 69 74 65 72 61 74 65 5f 73 63 6f 72 65 28 73 63  iterate_score(sc
0f20: 6f 72 65 2c 20 6b 65 79 29 3a 0a 20 20 20 20 73  ore, key):.    s
0f30: 63 61 6c 65 20 3d 20 6d 61 6b 65 5f 73 63 61 6c  cale = make_scal
0f40: 65 28 6b 65 79 29 0a 20 20 20 20 73 63 61 6c 65  e(key).    scale
0f50: 5f 63 6f 6e 76 65 72 73 69 6f 6e 20 3d 20 7b 0a  _conversion = {.
0f60: 20 20 20 20 20 20 20 20 22 49 22 3a 20 31 2c 0a          "I": 1,.
0f70: 20 20 20 20 20 20 20 20 22 49 49 22 3a 20 32 2c          "II": 2,
0f80: 0a 20 20 20 20 20 20 20 20 22 49 49 49 22 3a 20  .        "III": 
0f90: 33 2c 0a 20 20 20 20 20 20 20 20 22 49 56 22 3a  3,.        "IV":
0fa0: 20 34 2c 0a 20 20 20 20 20 20 20 20 22 56 22 3a   4,.        "V":
0fb0: 20 35 2c 0a 20 20 20 20 20 20 20 20 22 56 49 22   5,.        "VI"
0fc0: 3a 20 36 2c 0a 20 20 20 20 20 20 20 20 22 56 49  : 6,.        "VI
0fd0: 49 22 3a 20 37 2c 0a 20 20 20 20 20 20 20 20 22  I": 7,.        "
0fe0: 56 49 49 49 22 3a 20 38 2c 0a 20 20 20 20 7d 0a  VIII": 8,.    }.
0ff0: 20 20 20 20 6b 65 79 65 64 5f 73 63 6f 72 65 20      keyed_score 
1000: 3d 20 5b 5d 0a 20 20 20 20 66 6f 72 20 69 20 69  = [].    for i i
1010: 6e 20 72 61 6e 67 65 28 6c 65 6e 28 73 63 6f 72  n range(len(scor
1020: 65 29 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20  e)):.        if 
1030: 69 73 69 6e 73 74 61 6e 63 65 28 73 63 6f 72 65  isinstance(score
1040: 5b 69 5d 2c 20 70 61 72 73 65 2e 4e 6f 74 65 29  [i], parse.Note)
1050: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 63  :.            sc
1060: 6f 72 65 5b 69 5d 2e 76 61 6c 75 65 20 3d 20 73  ore[i].value = s
1070: 63 61 6c 65 5b 73 63 61 6c 65 5f 63 6f 6e 76 65  cale[scale_conve
1080: 72 73 69 6f 6e 5b 73 63 6f 72 65 5b 69 5d 2e 76  rsion[score[i].v
1090: 61 6c 75 65 5d 2d 31 5d 0a 20 20 20 20 20 20 20  alue]-1].       
10a0: 20 65 6c 69 66 20 69 73 69 6e 73 74 61 6e 63 65   elif isinstance
10b0: 28 73 63 6f 72 65 5b 69 5d 2c 20 70 61 72 73 65  (score[i], parse
10c0: 2e 43 68 6f 72 64 29 3a 0a 20 20 20 20 20 20 20  .Chord):.       
10d0: 20 20 20 20 20 63 68 6f 72 64 20 3d 20 5b 5d 0a       chord = [].
10e0: 20 20 20 20 20 20 20 20 20 20 20 20 72 6f 6f 74              root
10f0: 5f 6e 6f 74 65 5f 69 6e 64 65 78 20 3d 20 73 63  _note_index = sc
1100: 61 6c 65 2e 69 6e 64 65 78 28 6b 65 79 29 20 2b  ale.index(key) +
1110: 20 73 63 61 6c 65 5f 63 6f 6e 76 65 72 73 69 6f   scale_conversio
1120: 6e 5b 73 63 6f 72 65 5b 69 5d 2e 76 61 6c 75 65  n[score[i].value
1130: 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 68  ].            ch
1140: 6f 72 64 2e 61 70 70 65 6e 64 28 73 63 61 6c 65  ord.append(scale
1150: 5b 72 6f 6f 74 5f 6e 6f 74 65 5f 69 6e 64 65 78  [root_note_index
1160: 5d 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 63  ]).            c
1170: 68 6f 72 64 2e 61 70 70 65 6e 64 28 73 63 61 6c  hord.append(scal
1180: 65 5b 28 72 6f 6f 74 5f 6e 6f 74 65 5f 69 6e 64  e[(root_note_ind
1190: 65 78 2b 33 29 20 25 20 38 5d 29 0a 20 20 20 20  ex+3) % 8]).    
11a0: 20 20 20 20 20 20 20 20 69 66 20 73 63 6f 72 65          if score
11b0: 5b 69 5d 2e 63 68 6f 72 64 5f 74 79 70 65 20 3d  [i].chord_type =
11c0: 3d 20 22 6d 22 3a 20 20 23 20 4d 69 6e 6f 72 20  = "m":  # Minor 
11d0: 63 68 6f 72 64 73 2c 20 66 6c 61 74 20 74 68 65  chords, flat the
11e0: 20 35 74 68 0a 20 20 20 20 20 20 20 20 20 20 20   5th.           
11f0: 20 20 20 20 20 63 68 6f 72 64 2e 61 70 70 65 6e       chord.appen
1200: 64 28 73 63 61 6c 65 5b 28 72 6f 6f 74 5f 6e 6f  d(scale[(root_no
1210: 74 65 5f 69 6e 64 65 78 2b 34 29 20 25 20 38 5d  te_index+4) % 8]
1220: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 65 6c  ).            el
1230: 73 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  se:.            
1240: 20 20 20 20 63 68 6f 72 64 2e 61 70 70 65 6e 64      chord.append
1250: 28 73 63 61 6c 65 5b 28 72 6f 6f 74 5f 6e 6f 74  (scale[(root_not
1260: 65 5f 69 6e 64 65 78 2b 35 29 20 25 20 38 5d 29  e_index+5) % 8])
1270: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 63 6f  .            sco
1280: 72 65 5b 69 5d 2e 63 68 6f 72 64 20 3d 20 63 68  re[i].chord = ch
1290: 6f 72 64 0a 20 20 20 20 20 20 20 20 65 6c 69 66  ord.        elif
12a0: 20 69 73 69 6e 73 74 61 6e 63 65 28 73 63 6f 72   isinstance(scor
12b0: 65 5b 69 5d 2c 20 70 61 72 73 65 2e 52 65 73 74  e[i], parse.Rest
12c0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  ):.            p
12d0: 61 73 73 0a 20 20 20 20 72 65 74 75 72 6e 20 73  ass.    return s
12e0: 63 6f 72 65 0a 0a 0a 64 65 66 20 67 65 6e 65 72  core...def gener
12f0: 61 74 65 5f 63 73 6f 75 6e 64 5f 73 63 6f 72 65  ate_csound_score
1300: 28 73 63 6f 72 65 2c 20 73 63 6f 72 65 5f 6c 69  (score, score_li
1310: 6e 65 29 3a 0a 20 20 20 20 63 73 6f 75 6e 64 5f  ne):.    csound_
1320: 6e 6f 74 65 5f 76 61 6c 75 65 73 20 3d 20 7b 0a  note_values = {.
1330: 20 20 20 20 20 20 20 20 22 43 22 3a 20 22 30 30          "C": "00
1340: 22 2c 0a 20 20 20 20 20 20 20 20 22 43 23 22 3a  ",.        "C#":
1350: 20 22 30 31 22 2c 0a 20 20 20 20 20 20 20 20 22   "01",.        "
1360: 44 22 3a 20 22 30 32 22 2c 0a 20 20 20 20 20 20  D": "02",.      
1370: 20 20 22 44 23 22 3a 20 22 30 33 22 2c 0a 20 20    "D#": "03",.  
1380: 20 20 20 20 20 20 22 45 22 3a 20 22 30 34 22 2c        "E": "04",
1390: 0a 20 20 20 20 20 20 20 20 22 46 22 3a 20 22 30  .        "F": "0
13a0: 35 22 2c 0a 20 20 20 20 20 20 20 20 22 46 23 22  5",.        "F#"
13b0: 3a 20 22 30 36 22 2c 0a 20 20 20 20 20 20 20 20  : "06",.        
13c0: 22 47 22 3a 20 22 30 37 22 2c 0a 20 20 20 20 20  "G": "07",.     
13d0: 20 20 20 22 47 23 22 3a 20 22 30 38 22 2c 0a 20     "G#": "08",. 
13e0: 20 20 20 20 20 20 20 22 41 22 3a 20 22 30 39 22         "A": "09"
13f0: 2c 0a 20 20 20 20 20 20 20 20 22 41 23 22 3a 20  ,.        "A#": 
1400: 22 31 30 22 2c 0a 20 20 20 20 20 20 20 20 22 42  "10",.        "B
1410: 22 3a 20 22 31 31 22 2c 0a 20 20 20 20 7d 0a 20  ": "11",.    }. 
1420: 20 20 20 63 73 6f 75 6e 64 5f 73 63 6f 72 65 20     csound_score 
1430: 3d 20 5b 5d 0a 20 20 20 20 66 6f 72 20 74 6f 6b  = [].    for tok
1440: 65 6e 20 69 6e 20 73 63 6f 72 65 3a 0a 20 20 20  en in score:.   
1450: 20 20 20 20 20 69 66 20 69 73 69 6e 73 74 61 6e       if isinstan
1460: 63 65 28 74 6f 6b 65 6e 2c 20 70 61 72 73 65 2e  ce(token, parse.
1470: 43 68 6f 72 64 29 3a 20 20 23 20 43 68 6f 72 64  Chord):  # Chord
1480: 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f  s.            fo
1490: 72 20 6e 6f 74 65 20 69 6e 20 74 6f 6b 65 6e 2e  r note in token.
14a0: 63 68 6f 72 64 3a 20 0a 20 20 20 20 20 20 20 20  chord: .        
14b0: 20 20 20 20 20 20 20 20 6e 6f 74 65 20 3d 20 63          note = c
14c0: 73 6f 75 6e 64 5f 6e 6f 74 65 5f 76 61 6c 75 65  sound_note_value
14d0: 73 5b 6e 6f 74 65 5d 0a 20 20 20 20 20 20 20 20  s[note].        
14e0: 20 20 20 20 20 20 20 20 63 73 6f 75 6e 64 5f 73          csound_s
14f0: 63 6f 72 65 2e 61 70 70 65 6e 64 28 73 63 6f 72  core.append(scor
1500: 65 5f 6c 69 6e 65 20 25 20 7b 22 74 69 6d 65 22  e_line % {"time"
1510: 3a 20 74 6f 6b 65 6e 2e 74 69 6d 65 2c 20 22 6f  : token.time, "o
1520: 63 74 61 76 65 22 3a 20 74 6f 6b 65 6e 2e 6f 63  ctave": token.oc
1530: 74 61 76 65 2c 20 22 6e 6f 74 65 22 3a 20 6e 6f  tave, "note": no
1540: 74 65 2c 20 22 64 75 72 61 74 69 6f 6e 22 3a 20  te, "duration": 
1550: 74 6f 6b 65 6e 2e 64 75 72 61 74 69 6f 6e 7d 29  token.duration})
1560: 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20 69 73  .        elif is
1570: 69 6e 73 74 61 6e 63 65 28 74 6f 6b 65 6e 2c 20  instance(token, 
1580: 70 61 72 73 65 2e 4e 6f 74 65 29 3a 20 20 23 20  parse.Note):  # 
1590: 49 6e 64 69 76 69 64 75 61 6c 20 6e 6f 74 65 73  Individual notes
15a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 6f 74  .            not
15b0: 65 20 3d 20 63 73 6f 75 6e 64 5f 6e 6f 74 65 5f  e = csound_note_
15c0: 76 61 6c 75 65 73 5b 74 6f 6b 65 6e 2e 76 61 6c  values[token.val
15d0: 75 65 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20  ue].            
15e0: 63 73 6f 75 6e 64 5f 73 63 6f 72 65 2e 61 70 70  csound_score.app
15f0: 65 6e 64 28 73 63 6f 72 65 5f 6c 69 6e 65 20 25  end(score_line %
1600: 20 7b 22 74 69 6d 65 22 3a 20 74 6f 6b 65 6e 2e   {"time": token.
1610: 74 69 6d 65 2c 20 22 6f 63 74 61 76 65 22 3a 20  time, "octave": 
1620: 74 6f 6b 65 6e 2e 6f 63 74 61 76 65 2c 20 22 6e  token.octave, "n
1630: 6f 74 65 22 3a 20 6e 6f 74 65 2c 20 22 64 75 72  ote": note, "dur
1640: 61 74 69 6f 6e 22 3a 20 74 6f 6b 65 6e 2e 64 75  ation": token.du
1650: 72 61 74 69 6f 6e 7d 29 0a 20 20 20 20 72 65 74  ration}).    ret
1660: 75 72 6e 20 63 73 6f 75 6e 64 5f 73 63 6f 72 65  urn csound_score
1670: 0a 0a 0a 69 66 20 5f 5f 6e 61 6d 65 5f 5f 20 3d  ...if __name__ =
1680: 3d 20 22 5f 5f 6d 61 69 6e 5f 5f 22 3a 20 6d 61  = "__main__": ma
1690: 69 6e 28 29 20 0a                                in() .