finalizing 2nd string quartet and working on badass coda of 3rd - commiting as to not lose
							parent
							
								
									bed75d4bb8
								
							
						
					
					
						commit
						93c60a0a4f
					
				| @ -1,10 +1,17 @@ | |||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/5201b8af/lilypond/part_I.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4874dd07/lilypond/part_I.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/525274f2/lilypond/part_I.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/44490863/lilypond/part_I.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/41e447bc/lilypond/part_I.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4bf1af12/lilypond/part_I.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74307bb4/lilypond/part_I.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/6522664c/lilypond/part_I.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/628706ec/lilypond/part_I.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/7ede7adb/lilypond/part_I.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/4c059f33/lilypond/part_I.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/521654f8/lilypond/part_I.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/60adbbef/lilypond/part_I.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/6db2efcc/lilypond/part_I.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74b8f8d9/lilypond/part_I.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4b40ed47/lilypond/part_I.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/62300302/lilypond/part_I.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_I.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/72dc057f/lilypond/part_I.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/78a94ed1/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/531df78c/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/7276dc78/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/47bdba0e/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4f53a446/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/731cf7ae/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4da80bfb/lilypond/part_I.ly" | ||||||
|  | |||||||
| @ -1,10 +1,17 @@ | |||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/5201b8af/lilypond/part_II.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4874dd07/lilypond/part_II.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/525274f2/lilypond/part_II.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/44490863/lilypond/part_II.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/41e447bc/lilypond/part_II.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4bf1af12/lilypond/part_II.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74307bb4/lilypond/part_II.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/6522664c/lilypond/part_II.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/628706ec/lilypond/part_II.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/7ede7adb/lilypond/part_II.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/4c059f33/lilypond/part_II.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/521654f8/lilypond/part_II.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/60adbbef/lilypond/part_II.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/6db2efcc/lilypond/part_II.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74b8f8d9/lilypond/part_II.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4b40ed47/lilypond/part_II.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/62300302/lilypond/part_II.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_II.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/72dc057f/lilypond/part_II.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/78a94ed1/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/531df78c/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/7276dc78/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/47bdba0e/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4f53a446/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/731cf7ae/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4da80bfb/lilypond/part_II.ly" | ||||||
|  | |||||||
| @ -1,10 +1,17 @@ | |||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/5201b8af/lilypond/part_III.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4874dd07/lilypond/part_III.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/525274f2/lilypond/part_III.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/44490863/lilypond/part_III.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/41e447bc/lilypond/part_III.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4bf1af12/lilypond/part_III.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74307bb4/lilypond/part_III.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/6522664c/lilypond/part_III.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/628706ec/lilypond/part_III.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/7ede7adb/lilypond/part_III.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/4c059f33/lilypond/part_III.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/521654f8/lilypond/part_III.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/60adbbef/lilypond/part_III.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/6db2efcc/lilypond/part_III.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74b8f8d9/lilypond/part_III.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4b40ed47/lilypond/part_III.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/62300302/lilypond/part_III.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_III.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/72dc057f/lilypond/part_III.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/78a94ed1/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/531df78c/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/7276dc78/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/47bdba0e/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4f53a446/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/731cf7ae/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4da80bfb/lilypond/part_III.ly" | ||||||
|  | |||||||
| @ -1,10 +1,17 @@ | |||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/5201b8af/lilypond/part_IV.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4874dd07/lilypond/part_IV.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/525274f2/lilypond/part_IV.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/44490863/lilypond/part_IV.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/41e447bc/lilypond/part_IV.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4bf1af12/lilypond/part_IV.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74307bb4/lilypond/part_IV.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/6522664c/lilypond/part_IV.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/628706ec/lilypond/part_IV.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/7ede7adb/lilypond/part_IV.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/4c059f33/lilypond/part_IV.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/521654f8/lilypond/part_IV.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/60adbbef/lilypond/part_IV.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/6db2efcc/lilypond/part_IV.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74b8f8d9/lilypond/part_IV.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4b40ed47/lilypond/part_IV.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/62300302/lilypond/part_IV.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_IV.ly" | ||||||
| \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/72dc057f/lilypond/part_IV.ly" | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/78a94ed1/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/531df78c/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/7276dc78/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/47bdba0e/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4f53a446/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/731cf7ae/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_3_rise/4da80bfb/lilypond/part_IV.ly" | ||||||
|  | |||||||
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								| @ -0,0 +1,11 @@ | |||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/5201b8af/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/525274f2/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/41e447bc/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74307bb4/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/628706ec/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/4c059f33/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/60adbbef/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74b8f8d9/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/62300302/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/72dc057f/lilypond/part_I.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/76e45e56/lilypond/part_I.ly" | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/5201b8af/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/525274f2/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/41e447bc/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74307bb4/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/628706ec/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/4c059f33/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/60adbbef/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74b8f8d9/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/62300302/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/72dc057f/lilypond/part_II.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/76e45e56/lilypond/part_II.ly" | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/5201b8af/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/525274f2/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/41e447bc/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74307bb4/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/628706ec/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/4c059f33/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/60adbbef/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74b8f8d9/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/62300302/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/72dc057f/lilypond/part_III.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/76e45e56/lilypond/part_III.ly" | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/5201b8af/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/525274f2/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/41e447bc/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74307bb4/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/628706ec/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/4c059f33/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/60adbbef/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/74b8f8d9/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/62300302/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/72dc057f/lilypond/part_IV.ly" | ||||||
|  | \include "/home/mwinter/Sketches/seeds_and_ledgers/source/resources/string_quartet_2/76e45e56/lilypond/part_IV.ly" | ||||||
| @ -0,0 +1,153 @@ | |||||||
|  | \version "2.24.1" | ||||||
|  | 
 | ||||||
|  | \paper { | ||||||
|  |   #(set-paper-size "a4" 'portrait) | ||||||
|  |   top-margin = 1 \cm | ||||||
|  |   bottom-margin = 1 \cm | ||||||
|  |   left-margin = 2 \cm | ||||||
|  |   ragged-bottom = ##t | ||||||
|  |    | ||||||
|  |   top-system-spacing = | ||||||
|  |   #'((basic-distance . 15 ) | ||||||
|  |      (minimum-distance . 15 ) | ||||||
|  |      (padding . 0 ) | ||||||
|  |      (stretchability . 0)) | ||||||
|  |    | ||||||
|  |   system-system-spacing =  | ||||||
|  |   #'((basic-distance . 35 ) | ||||||
|  |      (minimum-distance . 35 ) | ||||||
|  |      (padding . 0 ) | ||||||
|  |      (stretchability . 0)) | ||||||
|  |    | ||||||
|  |   last-bottom-spacing = | ||||||
|  |   #'((basic-distance . 10 ) | ||||||
|  |      (minimum-distance . 10 ) | ||||||
|  |      (padding . 0 ) | ||||||
|  |      (stretchability . 0)) | ||||||
|  |    | ||||||
|  |   %systems-per-page = 3 | ||||||
|  |   first-page-number = 1 | ||||||
|  |   print-first-page-number = ##t | ||||||
|  |    | ||||||
|  |   print-page-number = ##t | ||||||
|  |   oddHeaderMarkup = \markup { \fill-line { \line { \unless \on-first-page {\pad-markup #2 { \concat {\italic {"test"}}}}}}} | ||||||
|  |   evenHeaderMarkup = \markup { \fill-line { \line { \unless \on-first-page {\pad-markup #2 { \concat {\italic {"test"}}}}}}} | ||||||
|  |   oddFooterMarkup = \markup { \fill-line { | ||||||
|  |     \concat { | ||||||
|  |       "-" | ||||||
|  |       \fontsize #1.5 | ||||||
|  |       \fromproperty #'page:page-number-string | ||||||
|  |       "-"}}} | ||||||
|  |   evenFooterMarkup = \markup { \fill-line { | ||||||
|  |     \concat {  | ||||||
|  |       "-"  | ||||||
|  |       \fontsize #1.5 | ||||||
|  |       \fromproperty #'page:page-number-string | ||||||
|  |       "-"}}} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | \header { | ||||||
|  |   title = \markup { \italic {"seeds and ledgers"}": string quartet #1"} | ||||||
|  |   composer = \markup \right-column {"michael winter" "(berlin & mexico city; 2023)"} | ||||||
|  |   %poet = "seed: xxx" | ||||||
|  |   tagline = "" | ||||||
|  | }  | ||||||
|  | 
 | ||||||
|  | #(set-global-staff-size 11) | ||||||
|  | 
 | ||||||
|  | \layout { | ||||||
|  |   indent = 0.0\cm | ||||||
|  |   line-width = 17.5\cm  | ||||||
|  |   ragged-last = ##f | ||||||
|  |   ragged-right = ##f | ||||||
|  |    | ||||||
|  |   \context { | ||||||
|  |     \Score | ||||||
|  |     \override BarNumber.stencil = #(make-stencil-circler 0.1 0.25 ly:text-interface::print) | ||||||
|  |     \override Stem.stemlet-length = #0.75 | ||||||
|  |     %proportionalNotationDuration = #(ly:make-moment 1/16) | ||||||
|  |     \remove "Separating_line_group_engraver" | ||||||
|  |     \override RehearsalMark.self-alignment-X = #-1  | ||||||
|  |     \override RehearsalMark.Y-offset = #10 | ||||||
|  |     \override RehearsalMark.X-offset = #-8 | ||||||
|  |     %\override RehearsalMark.outside-staff-priority = #0 | ||||||
|  |     \override SpacingSpanner.base-shortest-duration = #(ly:make-moment 1/32) | ||||||
|  |   } | ||||||
|  |   \context { | ||||||
|  |     \Staff | ||||||
|  |      | ||||||
|  |     \override VerticalAxisGroup.staff-staff-spacing = | ||||||
|  |     #'((basic-distance . 20 ) | ||||||
|  |        (minimum-distance . 20 ) | ||||||
|  |        (padding . 0 ) | ||||||
|  |        (stretchability . 0)) | ||||||
|  | 
 | ||||||
|  |     \override VerticalAxisGroup.default-staff-staff-spacing = | ||||||
|  |     #'((basic-distance . 20 ) | ||||||
|  |        (minimum-distance . 20 ) | ||||||
|  |        (padding . 0 ) | ||||||
|  |        (stretchability . 0)) | ||||||
|  |     \override TextScript.staff-padding = #2 | ||||||
|  |     %\override TextScript.self-alignment-X = #0 | ||||||
|  |   } | ||||||
|  |   \context { | ||||||
|  |     \StaffGroup | ||||||
|  |     \name "SemiStaffGroup" | ||||||
|  |     \consists "Span_bar_engraver" | ||||||
|  |     \override SpanBar.stencil = | ||||||
|  |     #(lambda (grob)  | ||||||
|  |        (if (string=? (ly:grob-property grob 'glyph-name) "|") | ||||||
|  |            (set! (ly:grob-property grob 'glyph-name) "")) | ||||||
|  |        (ly:span-bar::print grob)) | ||||||
|  |   } | ||||||
|  |   \context { | ||||||
|  |     \Score | ||||||
|  |     \accepts SemiStaffGroup | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | \score{ | ||||||
|  |   << | ||||||
|  |     \new SemiStaffGroup { | ||||||
|  |       << | ||||||
|  |         \new Staff = "I" \with {  | ||||||
|  |           instrumentName = "I"  | ||||||
|  |           shortInstrumentName = "I"  | ||||||
|  |           midiInstrument = #"clarinet"  | ||||||
|  |         } | ||||||
|  |         { | ||||||
|  |           \include "includes/part_I.ly" | ||||||
|  |         } | ||||||
|  |         \new Staff = "II" \with {  | ||||||
|  |           instrumentName = "II"  | ||||||
|  |           shortInstrumentName = "II"  | ||||||
|  |           midiInstrument = #"clarinet"  | ||||||
|  |         } | ||||||
|  |         { | ||||||
|  |           \include "includes/part_II.ly" | ||||||
|  |         } | ||||||
|  |         \new Staff = "III" \with {  | ||||||
|  |           instrumentName = "III"  | ||||||
|  |           shortInstrumentName = "III"  | ||||||
|  |           midiInstrument = #"clarinet"  | ||||||
|  |           \clef alto | ||||||
|  |         } | ||||||
|  |         { | ||||||
|  |           \include "includes/part_III.ly" | ||||||
|  |         } | ||||||
|  |         \new Staff = "IV" \with {  | ||||||
|  |           instrumentName = "IV"  | ||||||
|  |           shortInstrumentName = "IV"  | ||||||
|  |           midiInstrument = #"clarinet"  | ||||||
|  |           \clef bass | ||||||
|  |         } | ||||||
|  |         { | ||||||
|  |           \include "includes/part_IV.ly" | ||||||
|  |         } | ||||||
|  |       >> | ||||||
|  |     } | ||||||
|  |   >> | ||||||
|  |   \layout{} | ||||||
|  |   %\midi{} %this creates a warning since custom staff is not defined for midi | ||||||
|  | } | ||||||
											
												Binary file not shown.
											
										
									
								| @ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
| "ledger": |  | ||||||
| [ |  | ||||||
|   "314s49e1", |  | ||||||
|   "4a8a6e53", |  | ||||||
|   "66f6a618", |  | ||||||
|   "4c01589b", |  | ||||||
|   "7e170ef8", |  | ||||||
|   "7ac10d34", |  | ||||||
|   "628d5c8b", |  | ||||||
|   "6abf27d4" |  | ||||||
| ] |  | ||||||
| } |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
| "ledger": |  | ||||||
| [ |  | ||||||
|   "314s49e1", |  | ||||||
|   "4a8a6e53", |  | ||||||
|   "4c01589b", |  | ||||||
|   "7e170ef8", |  | ||||||
|   "7ac10d34", |  | ||||||
|   "628d5c8b", |  | ||||||
|   "6abf27d4", |  | ||||||
|   "535cc132" |  | ||||||
| ] |  | ||||||
| } |  | ||||||
| @ -1,718 +0,0 @@ | |||||||
| ( |  | ||||||
| // helper funcs |  | ||||||
| var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; |  | ||||||
| 
 |  | ||||||
| // score funcs |  | ||||||
| var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; |  | ||||||
| 
 |  | ||||||
| // subroutines |  | ||||||
| var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; |  | ||||||
| 
 |  | ||||||
| // primary routines |  | ||||||
| var genMotif, genSecondarySeq; |  | ||||||
| 
 |  | ||||||
| // audition funcs |  | ||||||
| var genPatterns, genMidiPatterns; |  | ||||||
| 
 |  | ||||||
| // resource management funcs |  | ||||||
| var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, |  | ||||||
| msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON; |  | ||||||
| 
 |  | ||||||
| // model vars |  | ||||||
| //(model and global vars mostly set by OSC funcs |  | ||||||
| var curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| ranges, orders, susWeights, passagesWeights, passagesSize, orderSize; |  | ||||||
| 
 |  | ||||||
| // model aux vars |  | ||||||
| var entrancesDurFunc, passagesDurFunc, exitsDurFunc; |  | ||||||
| 
 |  | ||||||
| // other global vars |  | ||||||
| var lastXChanges, popSize, exPath, dir, primes, dims, tuples, |  | ||||||
| seq, group, player, ledgerPath, ledger, currentlyPlayingUID; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // install JSON quark |  | ||||||
| if(Quarks.isInstalled("JSONlib").not, { |  | ||||||
| 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); |  | ||||||
| 	thisProcess.recompile; |  | ||||||
| 	//HelpBrowser.openHelpFor("Classes/JSONlib"); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------helper funcs |  | ||||||
| 
 |  | ||||||
| hsArrayToCents = { |  | ||||||
| 	arg hsArray; |  | ||||||
| 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| pDist = { |  | ||||||
| 	arg array1, array2, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); |  | ||||||
| 	if(signed, {pDistance}, {abs(pDistance)}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hdSum = { |  | ||||||
| 	arg hsArrays; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays.size; |  | ||||||
| 	distances = (size - 1).collect({arg i; |  | ||||||
| 		((i + 1)..(size - 1)).collect({arg j; |  | ||||||
| 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsChordalDistance = { |  | ||||||
| 	arg hsArrays1, hsArrays2; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays1.size; |  | ||||||
| 	distances = hsArrays1.size.collect({arg i; |  | ||||||
| 		hsArrays2.size.collect({arg j; |  | ||||||
| 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsArrayToFreq = { |  | ||||||
| 	arg array; |  | ||||||
| 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| //------score funcs |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| isInRange = { |  | ||||||
| 	arg hsArray, min, max; |  | ||||||
| 	var cents; |  | ||||||
| 	cents = hsArrayToCents.value(hsArray); |  | ||||||
| 	(cents >= min) && (cents <= max) |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| spacingScore = { |  | ||||||
| 	arg hsArrays, min; |  | ||||||
| 	var centsArray; |  | ||||||
| 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); |  | ||||||
| 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| rangeScore = { |  | ||||||
| 	arg hsArray1, hsArray2, min, max, low, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| intervalScore = { |  | ||||||
| 	arg hsArray1, hsArray2, mean, sd, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	pDistance.gaussCurve(1, mean, sd) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| inclusionScore = { |  | ||||||
| 	arg array, test, min = 0.01; |  | ||||||
| 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------subroutines |  | ||||||
| 
 |  | ||||||
| genTuples = { |  | ||||||
| 	var tuples; |  | ||||||
| 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); |  | ||||||
| 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| initVoices = { |  | ||||||
| 	var init, voicesInit; |  | ||||||
| 	voicesInit = popSize.collect({dims.collect({0})}); |  | ||||||
| 	/* |  | ||||||
| 	voicesInit = [dims.collect({0})]; |  | ||||||
| 	(popSize - 1).do({ |  | ||||||
| 		arg rep, new; |  | ||||||
| 		rep = dims.rand; |  | ||||||
| 		new = voicesInit.last.deepCopy; |  | ||||||
| 		new[rep] = new[rep] + [-1, 1].choose(); |  | ||||||
| 		voicesInit = voicesInit.add(new); |  | ||||||
| 	}); |  | ||||||
| 	*/ |  | ||||||
| 	voicesInit.deepCopy; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genDurFunc = {arg chordProb, min, max, envData; |  | ||||||
| 	var env, pTable, durFunc; |  | ||||||
| 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; |  | ||||||
| 	pTable = env.asRandomTable; |  | ||||||
| 	durFunc = {arg allowChord; |  | ||||||
| 		var res; |  | ||||||
| 		res = if(allowChord.not, { |  | ||||||
| 			pTable.tableRand * (max - min) + min |  | ||||||
| 		}, { |  | ||||||
| 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (max - min) + min}); |  | ||||||
| 		}).round(0.125); |  | ||||||
| 		if(res.asInteger == res, {res = res.asInteger}); |  | ||||||
| 		res |  | ||||||
| 	}; |  | ||||||
| 	seedFunc.value(durFunc, durSeed); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; |  | ||||||
| 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ |  | ||||||
| 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; |  | ||||||
| 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); |  | ||||||
| 		noProgIns = (popSize - noSusIns).rand + 1; |  | ||||||
| 		noSilentIns = popSize - noSusIns - noProgIns; |  | ||||||
| 
 |  | ||||||
| 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); |  | ||||||
| 
 |  | ||||||
| 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); |  | ||||||
| 		if(silent == nil, {silent = []}); |  | ||||||
| 		[sus.scramble, prog, silent.scramble] |  | ||||||
| 	}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| updateVoices = {arg ins, sus; |  | ||||||
| 	var voices, candidates, nWeights, nProbs, sel; |  | ||||||
| 
 |  | ||||||
| 	voices = lastXChanges.deepCopy.last; |  | ||||||
| 
 |  | ||||||
| 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; |  | ||||||
| 	candidates = difference(candidates.asSet, voices.asSet).asList; |  | ||||||
| 	nProbs = candidates.collect({arg candidate; |  | ||||||
| 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; |  | ||||||
| 
 |  | ||||||
| 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); |  | ||||||
| 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); |  | ||||||
| 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); |  | ||||||
| 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); |  | ||||||
| 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); |  | ||||||
| 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); |  | ||||||
| 		//maybe what you want here is a vector to another root and then favoring movement towards it. |  | ||||||
| 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); |  | ||||||
| 
 |  | ||||||
| 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	nWeights = passagesWeights; |  | ||||||
| 
 |  | ||||||
| 	//this handles nWeights of 0; mainly for testing |  | ||||||
| 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; |  | ||||||
| 	nWeights = nWeights.select({arg weight; weight != 0}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; |  | ||||||
| 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) |  | ||||||
| 	}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; |  | ||||||
| 
 |  | ||||||
| 	sel = candidates.wchoose(nProbs); |  | ||||||
| 
 |  | ||||||
| 	voices[ins] = sel; |  | ||||||
| 	lastXChanges = lastXChanges.add(voices).keep(-5); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSubMotif = {arg order, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; |  | ||||||
| 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, lastXChangesHold, voices, adder; |  | ||||||
| 	# sus, prog, silent = order; |  | ||||||
| 	flatOrder = silent ++ sus ++ prog; |  | ||||||
| 	lastXChangesHold = lastXChanges.deepCopy; |  | ||||||
| 	voices = lastState.deepCopy; |  | ||||||
| 	isInChord = popSize.collect({false}); |  | ||||||
| 	allowChord = false; |  | ||||||
| 	res = []; |  | ||||||
| 	"------generating motif".postln; |  | ||||||
| 	//need to figure out here if voices move between motifs |  | ||||||
| 	flatOrder.do({arg ins, i; |  | ||||||
| 
 |  | ||||||
| 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); |  | ||||||
| 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); |  | ||||||
| 
 |  | ||||||
| 		if(voices[ins] != adder, { |  | ||||||
| 			var dur; |  | ||||||
| 			allowChord = if((sus ++ silent).includes(ins), { |  | ||||||
| 				(sus ++ silent).includes(ins) && (ins != sus.last); |  | ||||||
| 			}, { |  | ||||||
| 				if(i < (flatOrder.size - 1), {(isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not}, {false}); |  | ||||||
| 			}); |  | ||||||
| 			dur = passagesDurFunc.value(allowChord); |  | ||||||
| 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); |  | ||||||
| 
 |  | ||||||
| 			voices[ins] = adder; |  | ||||||
| 			res = res.add([voices.deepCopy.postln, dur]); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	// pad ending |  | ||||||
| 	if(isLastOrder, { |  | ||||||
| 		(0..(popSize-1)).scramble.do({arg ins; |  | ||||||
| 			if(res.last.first[ins] != ["Rest"], { |  | ||||||
| 				var dur; |  | ||||||
| 				voices[ins] = ["Rest"]; |  | ||||||
| 				allowChord = (voices != popSize.collect({["Rest"]})); |  | ||||||
| 				dur = passagesDurFunc.value(allowChord); |  | ||||||
| 				res = res.add([voices.deepCopy.postln, dur]); |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	//format and return |  | ||||||
| 	if(startFromLast, {lastXChanges = lastXChangesHold}); |  | ||||||
| 	res; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------primary routines |  | ||||||
| 
 |  | ||||||
| genMotif = { |  | ||||||
| 	var repeats, fSeq; |  | ||||||
| 
 |  | ||||||
| 	repeats = 1; |  | ||||||
| 	fSeq = []; |  | ||||||
| 
 |  | ||||||
| 	repeats.do({arg index; |  | ||||||
| 		var motif; |  | ||||||
| 
 |  | ||||||
| 		motif = []; |  | ||||||
| 
 |  | ||||||
| 		orders.do({arg order, o; |  | ||||||
| 			var lastState, subMotif; |  | ||||||
| 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); |  | ||||||
| 			subMotif = genSubMotif.value(order, lastState, isLastOrder: o == (orders.size - 1)); |  | ||||||
| 			motif = motif.add(subMotif); |  | ||||||
| 
 |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		sanityCheck.value(motif, index); |  | ||||||
| 
 |  | ||||||
| 		fSeq = fSeq.add(motif); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSecondarySeq = {arg seq; |  | ||||||
| 	var curdles, fSeq; |  | ||||||
| 	curdles = []; |  | ||||||
| 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); |  | ||||||
| 
 |  | ||||||
| 	fSeq = seq.clumps(curdles).collect({arg clump, m; |  | ||||||
| 		var repeats, paddedSeq; |  | ||||||
| 
 |  | ||||||
| 		//add rest |  | ||||||
| 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); |  | ||||||
| 
 |  | ||||||
| 		//implement repeats |  | ||||||
| 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); |  | ||||||
| 		repeats.collect({paddedSeq}); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------audition funcs |  | ||||||
| 
 |  | ||||||
| Event.addEventType(\osc, { |  | ||||||
| 	if (~addr.postln.notNil) { |  | ||||||
| 		~addr.sendMsg(~indexPath, ~indexMsg); |  | ||||||
| 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); |  | ||||||
| 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); |  | ||||||
| 	}; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| genPatterns = {arg inSeq, addr; |  | ||||||
| 	var voices, durs, patterns, res, indices, sectionDurs, ids, seq; |  | ||||||
| 	seq = inSeq.collect({arg mSeq; mSeq[0]}); |  | ||||||
| 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	indices = inSeq.collect({arg mSeq, m; mSeq[1]}); |  | ||||||
| 	ids = inSeq.collect({arg mSeq, m; mSeq[2]}); |  | ||||||
| 	sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\instrument, \test, |  | ||||||
| 				\group, group, |  | ||||||
| 				\freq, Pseq(freqs, 1), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\sustain, Pseq(fDurs, 1) |  | ||||||
| 			) |  | ||||||
| 		}) ++ |  | ||||||
| 		[ |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \osc, |  | ||||||
| 				\addr, addr, |  | ||||||
| 				\indexPath, "/cur_play_index", |  | ||||||
| 				\indexMsg, Pseq(indices.postln, 1), |  | ||||||
| 				\seqPath, "/mus_seq", |  | ||||||
| 				\seqMsg, Pseq(seq, 1), |  | ||||||
| 				\dur, Pseq(sectionDurs, 1) |  | ||||||
| 			); |  | ||||||
| 		] |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| genMidiPatterns = {arg seq; |  | ||||||
| 	var voices, durs, patterns, res, mOut, pbRange; |  | ||||||
| 	pbRange = 1; //semitones - change this as needed for your situation |  | ||||||
| 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); |  | ||||||
| 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice, v; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 
 |  | ||||||
| 			mOut.program(v, 70); |  | ||||||
| 
 |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \midi, |  | ||||||
| 				\chan, v, |  | ||||||
| 				\noteval, Pseq(freqs.cpsmidi - 24, 1), |  | ||||||
| 				\note, Pfunc({ | event | event[\noteval].floor }), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\midiout, mOut, |  | ||||||
| 				\amp, 1, |  | ||||||
| 				\bend, Pfunc({ |  | ||||||
| 					| event | |  | ||||||
| 					if (event[\note].isRest.not) { |  | ||||||
| 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; |  | ||||||
| 						m.bend(v, pitchbendvalue); |  | ||||||
| 					}; |  | ||||||
| 					0; // return something other than nil to avoid stopping the pattern |  | ||||||
| 				}), |  | ||||||
| 			); |  | ||||||
| 		}); |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------resource management funcs |  | ||||||
| 
 |  | ||||||
| genUID = {Date.seed.asHexString.toLower}; |  | ||||||
| 
 |  | ||||||
| seedFunc = {arg func, seed; |  | ||||||
| 	var funcArgs, next; |  | ||||||
| 	next = Routine({loop{func.valueArray(funcArgs).yield }}); |  | ||||||
| 	next.randSeed_(seed); |  | ||||||
| 	{arg ...args; funcArgs = args; next.value} |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| stringifyToDepth = {arg data, maxDepth = 1; |  | ||||||
| 	var prettyString = "", rCount = 0, writeArray, indent; |  | ||||||
| 
 |  | ||||||
| 	if(maxDepth == 0, { |  | ||||||
| 		data.asCompileString |  | ||||||
| 	}, { |  | ||||||
| 		indent = {arg size; size.collect({" "}).join("")}; |  | ||||||
| 		writeArray = {arg array; |  | ||||||
| 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; |  | ||||||
| 			rCount = rCount + 1; |  | ||||||
| 			if(rCount < (maxDepth - 0), { |  | ||||||
| 				array.do({arg subArray; writeArray.value(subArray)}); |  | ||||||
| 			}, { |  | ||||||
| 				prettyString = prettyString ++ array.collect({arg subArray; |  | ||||||
| 					indent.value(rCount + 1) ++ subArray.asCompileString |  | ||||||
| 				}).join(",\n"); |  | ||||||
| 			}); |  | ||||||
| 			rCount = rCount - 1; |  | ||||||
| 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		writeArray.value(data); |  | ||||||
| 		prettyString.replace(",\n\n", "\n").drop(-2); |  | ||||||
| 	}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| sanityCheck = {arg motif, index; |  | ||||||
| 	//print functions = very helpful |  | ||||||
| 	("----------" + index + "------------").postln; |  | ||||||
| 
 |  | ||||||
| 	motif.flatten.do({arg val, v; |  | ||||||
| 		if(v > 0, { |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); |  | ||||||
| 		}); |  | ||||||
| 		val.postln |  | ||||||
| 	}); |  | ||||||
| 	"***********".postln; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; |  | ||||||
| 	var res; |  | ||||||
| 
 |  | ||||||
| 	res = in; |  | ||||||
| 	if(res.isNil.not, { |  | ||||||
| 		if((res.isArray && res.isString.not), { |  | ||||||
| 			res = res.asCompileString; |  | ||||||
| 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); |  | ||||||
| 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); |  | ||||||
| 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); |  | ||||||
| 			res = res.replace("Rest", "\"Rest\""); |  | ||||||
| 			res = res.interpret; |  | ||||||
| 		}, { |  | ||||||
| 			//res.postln; |  | ||||||
| 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| writeResources = {arg path; |  | ||||||
| 	var file, nameSpaces, modelItems, resString; |  | ||||||
| 	file = File(path,"w"); |  | ||||||
| 
 |  | ||||||
| 	nameSpaces = [ |  | ||||||
| 		"music_data", "last_changes", |  | ||||||
| 		"cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", |  | ||||||
| 		"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", |  | ||||||
| 		"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size" |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	modelItems = [ |  | ||||||
| 		seq, lastXChanges, |  | ||||||
| 		curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| 		entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	resString = [nameSpaces, modelItems].flop.collect({arg item; |  | ||||||
| 		var nameSpace, modelItem, depth = 0, insert = " "; |  | ||||||
| 		# nameSpace, modelItem = item; |  | ||||||
| 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); |  | ||||||
| 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); |  | ||||||
| 		if(nameSpace == "order", {depth = 1; insert = "\n"}); |  | ||||||
| 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(modelItem.postln, depth).postln |  | ||||||
| 	}).join(",\n"); |  | ||||||
| 
 |  | ||||||
| 	resString = "{\n" ++ resString ++ "\n}"; |  | ||||||
| 
 |  | ||||||
| 	file.write(resString); |  | ||||||
| 	file.close; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; |  | ||||||
| 
 |  | ||||||
| loadModelJSON = {arg model; |  | ||||||
| 	var nameSpaces, data; |  | ||||||
| 
 |  | ||||||
| 	//model = File(path, "r").readAllString.parseJSON; |  | ||||||
| 
 |  | ||||||
| 	nameSpaces = [ |  | ||||||
| 		"cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", |  | ||||||
| 		"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", |  | ||||||
| 		"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size" |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	data = nameSpaces.collect({arg nS; msgInterpret.value(model[nS]).postln}); |  | ||||||
| 
 |  | ||||||
| 	data.postln; |  | ||||||
| 
 |  | ||||||
| 	# curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| 	entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize = data; |  | ||||||
| 
 |  | ||||||
| 	popSize = ranges.size; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadLedgerFile = {arg path; |  | ||||||
| 	ledgerPath = path; |  | ||||||
| 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadLedgerJSON = {arg ledger; ledger = ledger["ledger"]}; |  | ||||||
| 
 |  | ||||||
| //------global vars |  | ||||||
| 
 |  | ||||||
| primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; |  | ||||||
| //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; |  | ||||||
| exPath = thisProcess.nowExecutingPath; |  | ||||||
| dir = exPath.dirname; |  | ||||||
| //popSize = 4; |  | ||||||
| dims = primes.size; |  | ||||||
| tuples = genTuples.value(); |  | ||||||
| //refUID = nil; |  | ||||||
| group = Group.new; |  | ||||||
| loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); |  | ||||||
| //passagesWeights = [1, 1, 1, 1, 1]; |  | ||||||
| //susWeights = [1, 1, 1]; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------OSC funcs |  | ||||||
| 
 |  | ||||||
| OSCdef(\load_ledger, {arg msg, time, addr, port; |  | ||||||
| 	loadLedgerFile.value(msg[1].asString); |  | ||||||
| }, \load_ledger); |  | ||||||
| 
 |  | ||||||
| OSCdef(\load_model, {arg msg, time, addr, port; |  | ||||||
| 	loadModelFile.value(msg[1].asString); |  | ||||||
| }, \load_model); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| OSCdef(\generate, {arg msg, time, addr, port; |  | ||||||
| 	var path, dFormat, condition, musPath; |  | ||||||
| 	msg.postln; |  | ||||||
| 
 |  | ||||||
| 	path = msg[1].asString; |  | ||||||
| 
 |  | ||||||
| 	loadModelFile.value(path); |  | ||||||
| 
 |  | ||||||
| 	refUID.postln; |  | ||||||
| 
 |  | ||||||
| 	loadLedgerFile.value(ledgerPath); |  | ||||||
| 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); |  | ||||||
| 
 |  | ||||||
| 	lastXChanges = if(refUID == nil, { |  | ||||||
| 		[initVoices.value().deepCopy]; |  | ||||||
| 	}, { |  | ||||||
| 		var file; |  | ||||||
| 		refUID.postln; |  | ||||||
| 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); |  | ||||||
| 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..2] ++ [entrancesProbVals[3..]]); |  | ||||||
| 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..2] ++ [passagesProbVals[3..]]); |  | ||||||
| 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..2] ++ [exitsProbVals[3..]]); |  | ||||||
| 
 |  | ||||||
| 	if(orders == nil, { |  | ||||||
| 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); |  | ||||||
| 		addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); |  | ||||||
| 	}); |  | ||||||
| 	seq = seedFunc.value(genMotif, motifSeed).value; |  | ||||||
| 
 |  | ||||||
| 	//musPath = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; |  | ||||||
| 	writeResources.value(path); |  | ||||||
| 
 |  | ||||||
| 	//orders = nil; |  | ||||||
| 	//addr.sendMsg("/current_uid", curUID); |  | ||||||
| 	//addr.sendMsg("/ledger", prettifyArray.value(ledger, 1).replace("\"", "")); |  | ||||||
| 	//addr.sendMsg("/ledger_size", ledger.size); |  | ||||||
| 	//addr.sendMsg("/mus_seq", prettifyArray.value(seq, 3)); |  | ||||||
| 	addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); |  | ||||||
| }, \generate); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| OSCdef(\commit, {arg msg, time, addr, port; |  | ||||||
| 	var newLedger, modelPath, musString, musFile, test1, test2; |  | ||||||
| 	msg.postln; |  | ||||||
| 
 |  | ||||||
| 	/* |  | ||||||
| 	test1 = msg[1].asString.parseJSON; |  | ||||||
| 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; |  | ||||||
| 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; |  | ||||||
| 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; |  | ||||||
| 	(test1["music"] == test2["music_data"]).postln; |  | ||||||
| 	*/ |  | ||||||
| 
 |  | ||||||
| 	curUID = genUID.value; |  | ||||||
| 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); |  | ||||||
| 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); |  | ||||||
| 
 |  | ||||||
| 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; |  | ||||||
| 	writeResources.value(modelPath); |  | ||||||
| 
 |  | ||||||
| 	File.delete(ledgerPath.postln ++ "_bak"); |  | ||||||
| 	File.copy(ledgerPath, ledgerPath ++ "_bak"); |  | ||||||
| 	File.delete(ledgerPath); |  | ||||||
| 	newLedger = File(ledgerPath.postln, "w"); |  | ||||||
| 	ledger = ledger.postln.drop(-1).add(curUID); |  | ||||||
| 	newLedger.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); |  | ||||||
| 	newLedger.close; |  | ||||||
| 
 |  | ||||||
| 	addr.sendMsg("/committed", curUID, ledgerPath); |  | ||||||
| 	//refUID = curUID; |  | ||||||
| }, \commit); |  | ||||||
| 
 |  | ||||||
| OSCdef(\transport, {arg msg, time, addr, port; |  | ||||||
| 	msg.postln; |  | ||||||
| 	if(msg[1] == 0, { |  | ||||||
| 		player.stop; |  | ||||||
| 		group.set(\gate, 0); |  | ||||||
| 	}, { |  | ||||||
| 		// the cued sequence can now be read from file, so this can be cleaned up |  | ||||||
| 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; |  | ||||||
| 		pSeq = []; |  | ||||||
| 		cuedSeek = (seq != nil); |  | ||||||
| 		indexStart = msg[2].asInteger; |  | ||||||
| 		indexEnd = ledger.size - if(cuedSeek, {2}, {1}); |  | ||||||
| 		if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { |  | ||||||
| 			ledger[indexStart..indexEnd].do({arg uid, index; |  | ||||||
| 				var file; |  | ||||||
| 				(indexStart + index).postln; |  | ||||||
| 				file = File((dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_music" ++ ".json").standardizePath, "r"); |  | ||||||
| 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), indexStart + index, uid]); |  | ||||||
| 				file.close; |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 		if(cuedSeek, {pSeq = pSeq.add([seq, ledger.size - 1])}); |  | ||||||
| 		patterns = genPatterns.value(pSeq, addr); |  | ||||||
| 		player = Pfset(pattern: patterns, cleanupFunc: { |  | ||||||
| 			addr.sendMsg("/transport", 0); |  | ||||||
| 		}); |  | ||||||
| 		player = player.play |  | ||||||
| 	}); |  | ||||||
| }, \transport); |  | ||||||
| 
 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	freq = WhiteNoise.ar * 3 + freq; |  | ||||||
| 	freqFinal = Duty.ar((1/freq), 0, freq); |  | ||||||
| 	trig = Changed.ar(freqFinal); |  | ||||||
| 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); |  | ||||||
| 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); |  | ||||||
| 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 
 |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| "{\"a\": 1}".parseYAML["a"].asInteger; |  | ||||||
| "{\"a\": 1}".parseJSON["a"].isNumber; |  | ||||||
| 
 |  | ||||||
| 1223423434123.asHexString.toLower |  | ||||||
| 
 |  | ||||||
| Date.getDate.rawSeconds |  | ||||||
| Date.seed.asHexString.toLower |  | ||||||
| 
 |  | ||||||
| n = NetAddr("localhost", 8080); |  | ||||||
| n.sendMsg("/GET/#", (NetAddr.localAddr.hostname ++ ":" ++ NetAddr.localAddr.port), "/passage_probs_vals"); |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,85 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.75 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 0, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ 1, 0, 0, -1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, -1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 1.625 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 1.75 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.875 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.625 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.125 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.625 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.5 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.125 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, -1 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.375 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.875 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.375 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 2 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, -1, -1, 0 ], [ "Rest" ], [ 1, 0, 0, -1, 0, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "4c01589b", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 720097, |  | ||||||
| "dur_seed": 979064, |  | ||||||
| "motifs_seed": 718021, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 2 ], [ 1, 3, 0, 1, 1, 3, 0, 0, 3, 0, 0, 3 ], [  ] ], |  | ||||||
|   [ [ 1, 0, 3 ], [ 2, 2, 2, 2, 2, 2, 2, 2 ], [  ] ], |  | ||||||
|   [ [ 3, 2, 0 ], [ 1, 1, 1, 1 ], [  ] ], |  | ||||||
|   [ [ 0 ], [ 2 ], [ 3, 1 ] ], |  | ||||||
|   [ [ 0, 2, 3 ], [ 1, 1, 1, 1, 1, 1 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ] |  | ||||||
| } |  | ||||||
| @ -1,91 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 8.375 ], |  | ||||||
|     [ [ [ 0, -1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ 1, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ 0, -1, 1, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ 1, -1, 0, -1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 10.75 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, -1, 0, -1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, -1, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ 1, -1, 0, -1, -1, 0 ], [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, -1, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ 0, -1, 0, 0, -1, 0 ], [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, -1, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, -1, -1 ], [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, -1, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, -1, -1 ], [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, -1 ] ], 1.25 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, -1, -1 ], [ 1, -1, -1, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, -1 ] ], 1.75 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, -1, -1 ], [ 1, -1, -1, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, -1, -1 ], [ 0, -1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, -1, 1, 0, -1, 0 ], [ 0, -1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1.875 ], |  | ||||||
|     [ [ [ 0, -1, 1, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 8 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, -1, -1, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ], |  | ||||||
|     [ [ [ 0, 0, -1, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ], |  | ||||||
|     [ [ [ 1, -1, 0, -1, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1.625 ], |  | ||||||
|     [ [ [ -1, -1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ 0, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 8.625 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, -1, 0, -1, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 2, 0, 0, -1, -1, 0 ] ], 1.875 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 9.25 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 1.875 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, -1, -1, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 1.625 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 1.625 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 1 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 9.75 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, -1 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, -1 ], [ "Rest" ], [ 0, 0, 0, 0, 1, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ -2, 0, 0, 0, 1, 1 ], [ "Rest" ], [ 0, 0, 0, 0, 1, 0 ] ], 1.875 ], |  | ||||||
|     [ [ [ "Rest" ], [ -2, 1, 0, 0, 1, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 1, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, -1, 0, 1, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 1, 0 ] ], 2 ], |  | ||||||
|     [ [ [ "Rest" ], [ -2, 0, 0, 1, 1, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 1, 0 ] ], 7.625 ], |  | ||||||
|     [ [ [ "Rest" ], [ -2, 0, 0, 1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 1 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 8.375 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "66f6a618", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 209164, |  | ||||||
| "dur_seed": 417909, |  | ||||||
| "motifs_seed": 885208, |  | ||||||
| "entrances_probs_vals": [ 0.34, 0, 10, 0.5, 2, 0, 0.5, 0.24509803921569, 0.89189189189189, 0.5, 1, 0.5, 0.5, 0.8562091503268, 0.69932432432432, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.34, 0, 10, 0.5, 2, 0, 0.5, 0.24509803921569, 0.89189189189189, 0.5, 1, 0.5, 0.5, 0.8562091503268, 0.69932432432432, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.34, 0, 10, 0.5, 2, 0, 0.5, 0.24509803921569, 0.89189189189189, 0.5, 1, 0.5, 0.5, 0.8562091503268, 0.69932432432432, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -1200, 2400 ], [ -1200, 2400 ], [ -1200, 2400 ], [ -1200, 2400 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 2 ], [ 0, 0, 0, 0 ], [ 1, 3 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.75, 0.75 ], |  | ||||||
| "order_size": [ 1, 10 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "true", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,24 +0,0 @@ | |||||||
| { |  | ||||||
| "ledger": |  | ||||||
| [ |  | ||||||
|   "4a8a6e53", |  | ||||||
|   "66f6a618", |  | ||||||
|   "490b1e6e", |  | ||||||
|   "46985d14", |  | ||||||
|   "761e4585", |  | ||||||
|   "6fb60ab6", |  | ||||||
|   "79e0a4a7", |  | ||||||
|   "43b009ff", |  | ||||||
|   "7d3c9a80", |  | ||||||
|   "4b7745df", |  | ||||||
|   "6ed95c4c", |  | ||||||
|   "6d635e88", |  | ||||||
|   "4e7d35e5", |  | ||||||
|   "7edbdceb", |  | ||||||
|   "784130cc", |  | ||||||
|   "443ec222", |  | ||||||
|   "52c9a980", |  | ||||||
|   "4200a90d", |  | ||||||
|   "61ce9067" |  | ||||||
| ] |  | ||||||
| } |  | ||||||
| @ -1,12 +0,0 @@ | |||||||
| {   |  | ||||||
|  { r1  } |  | ||||||
|  \bar "|"   |  | ||||||
|  { r8.[ a'16^\markup { \pad-markup #0.2 "+29"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ a'2. ~ } |  | ||||||
|  \bar "|"   |  | ||||||
|  { a'8[ g'8^\markup { \pad-markup #0.2 "-2"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ g'2. ~ } |  | ||||||
|  \bar "|"   |  | ||||||
|  { g'4 ~ g'8.[ b'16^\markup { \pad-markup #0.2 "-16"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ b'2 ~ } |  | ||||||
|  \bar "|"   |  | ||||||
|  { b'4 ~ b'8.[ g'16^\markup { \pad-markup #0.2 "-2"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ g'4 ~ g'16[ r8.]} |  | ||||||
| \bar "||" |  | ||||||
| } |  | ||||||
| @ -1,12 +0,0 @@ | |||||||
| {   |  | ||||||
|  { r2.  r16[ c''8.^\markup { \pad-markup #0.2 "-4"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } |  | ||||||
|  \bar "|"   |  | ||||||
|  { c''2. ~ c''8[ f'8^\markup { \pad-markup #0.2 "-33"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ } |  | ||||||
|  \bar "|"   |  | ||||||
|  { f'1 ~ } |  | ||||||
|  \bar "|"   |  | ||||||
|  { f'16[ c'8.^\markup { \pad-markup #0.2 "+49"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ c'2. } |  | ||||||
|  \bar "|"   |  | ||||||
|  { dis'1^\markup { \pad-markup #0.2 "+39"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}} |  | ||||||
| \bar "||" |  | ||||||
| } |  | ||||||
| @ -1,12 +0,0 @@ | |||||||
| {   |  | ||||||
|  { r4 r8.[ a16^\markup { \pad-markup #0.2 "+29"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] ~ a2 ~ } |  | ||||||
|  \bar "|"   |  | ||||||
|  { a4 ~ a8[ g8^\markup { \pad-markup #0.2 "-2"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ g2 ~ } |  | ||||||
|  \bar "|"   |  | ||||||
|  { g2 b2^\markup { \pad-markup #0.2 "-16"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } |  | ||||||
|  \bar "|"   |  | ||||||
|  { b2 ~ b16[ g8.^\markup { \pad-markup #0.2 "-2"}_\markup {  \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ g4 ~ } |  | ||||||
|  \bar "|"   |  | ||||||
|  { g1} |  | ||||||
| \bar "||" |  | ||||||
| } |  | ||||||
| @ -1,70 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ] ], 1.125 ], |  | ||||||
|     [ [ [ 0, -1, 1, -2, 1, 1 ], [ "Rest" ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 1, -2, 1, 0 ], [ "Rest" ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ 0, -1, 1, -2, 1, 1 ], [ "Rest" ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ 0, -1, 1, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ] ], 2.875 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, -1, 1, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 1, -1, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, -1, 1, -1, 1, 0 ], [ "Rest" ], [ 0, -1, 1, 0, 1, 0 ], [ 0, 0, 1, -1, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, -1, 1, -1, 1, 0 ], [ 0, -1, 2, -1, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 0, 0, 1, -1, 1, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, -1, 1, -1, 1, 0 ], [ 1, -1, 1, -1, 1, -1 ], [ 0, -1, 1, 0, 1, 0 ], [ 0, 0, 1, -1, 1, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, -1, 1, -1, 1, 0 ], [ -1, -1, 1, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 0, 0, 1, -1, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, -1, 1, -1, 1, 0 ], [ -1, -1, 1, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 2, -1, 1, -1, 1, -1 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, -1, 1, -1, 1, 0 ], [ 0, -1, 1, -1, 2, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 2, -1, 1, -1, 1, -1 ] ], 0.625 ], |  | ||||||
|     [ [ [ 0, -1, 1, -1, 1, 0 ], [ 1, -2, 1, -1, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 2, -1, 1, -1, 1, -1 ] ], 1.25 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, -1, 1, -1, 1, 0 ], [ -1, -1, 1, 0, 1, 1 ], [ 0, -1, 1, 0, 1, 0 ], [ 2, -1, 1, -1, 1, -1 ] ], 0 ], |  | ||||||
|     [ [ [ -2, 0, 1, 0, 1, 0 ], [ -1, -1, 1, 0, 1, 1 ], [ 0, -1, 1, 0, 1, 0 ], [ 2, -1, 1, -1, 1, -1 ] ], 1 ], |  | ||||||
|     [ [ [ -2, 0, 1, 0, 1, 0 ], [ -1, -1, 1, 0, 1, 1 ], [ 0, -1, 1, 0, 1, 0 ], [ 0, -1, 1, 1, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -2, 0, 1, 0, 1, 0 ], [ -1, -1, 1, 1, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 0, -1, 1, 1, 1, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ -2, 0, 1, 0, 1, 0 ], [ -1, -1, 2, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 0, -1, 1, 1, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -2, 0, 1, 0, 1, 0 ], [ -1, -1, 2, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 0, -1, 1, 0, 2, 0 ] ], 1.125 ], |  | ||||||
|     [ [ [ -2, 0, 1, 0, 1, 0 ], [ -1, -1, 2, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 1, -1, 1, 0, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, -1, 1, 0, 1, 0 ], [ -1, -1, 2, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 1, -1, 1, 0, 1, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, -1, 2, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 1, -1, 1, 0, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, -1, 1, 0, 1, 0 ], [ 1, -1, 1, 0, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, -1, 1, 0, 1, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.875 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ -2, 0, 1, 0, 1, 0 ], [ -1, -1, 1, 1, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 0, -1, 1, 1, 1, 0 ] ], |  | ||||||
|   [ [ -2, 0, 1, 0, 1, 0 ], [ -1, -1, 2, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 0, -1, 1, 1, 1, 0 ] ], |  | ||||||
|   [ [ -2, 0, 1, 0, 1, 0 ], [ -1, -1, 2, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 0, -1, 1, 0, 2, 0 ] ], |  | ||||||
|   [ [ -2, 0, 1, 0, 1, 0 ], [ -1, -1, 2, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 1, -1, 1, 0, 1, 0 ] ], |  | ||||||
|   [ [ -1, -1, 1, 0, 1, 0 ], [ -1, -1, 2, 0, 1, 0 ], [ 0, -1, 1, 0, 1, 0 ], [ 1, -1, 1, 0, 1, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "tmp", |  | ||||||
| "ref_uid": "61ce9067", |  | ||||||
| "order_seed": 473248, |  | ||||||
| "dur_seed": 979780, |  | ||||||
| "motifs_seed": 262605, |  | ||||||
| "entrances_probs_vals": [ 1, 0, 0, 0.19, 1.7582417582418, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.85, 0, 1.2301587301587, 0.54945054945055, 1.79, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 1, 0.16, 1.0714285714286, 0.16, 1.510989010989, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -2560, 59.442724458204 ], [ -1074, 393.8080495356 ], [ 59.442724458205, 1638.3900928793 ], [ -52.012383900929, 1582.6625386997 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0, 0.092592592592593, 0.78977272727273, 0.16460905349794, 0, 0.24279835390947, 0, 0.60699588477366, 0.63636363636364, 0.73662551440329, 0, 1, 0 ], |  | ||||||
| "passages_weights": [ 1, 0, 0.6, 0, 0.54 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 3 ], [ 0, 0, 0, 0 ], [ 1, 2 ] ], |  | ||||||
|   [ [ 0 ], [ 3, 2, 1, 1, 1, 3, 1, 1 ], [  ] ], |  | ||||||
|   [ [ 2 ], [ 1, 0, 3, 1, 1, 3, 3, 0 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.69, 0, 0 ], |  | ||||||
| "order_size": [ 1, 7 ], |  | ||||||
| "passages_size": [ 3, 6 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,26 +0,0 @@ | |||||||
| { |  | ||||||
| "ledger": |  | ||||||
| [ |  | ||||||
|   "314s49e1", |  | ||||||
|   "600e3005", |  | ||||||
|   "54479f3d", |  | ||||||
|   "674b56e3", |  | ||||||
|   "4c01589b", |  | ||||||
|   "7e170ef8", |  | ||||||
|   "7ac10d34", |  | ||||||
|   "640eeed3", |  | ||||||
|   "497509c8", |  | ||||||
|   "4828752f", |  | ||||||
|   "43c05737", |  | ||||||
|   "5397abab", |  | ||||||
|   "46631d0e", |  | ||||||
|   "75638b4d", |  | ||||||
|   "5cd72e22", |  | ||||||
|   "47770d57", |  | ||||||
|   "49258e97", |  | ||||||
|   "7e2c2e91", |  | ||||||
|   "688ee3e1", |  | ||||||
|   "7bfea52f", |  | ||||||
|   "57fa6a01" |  | ||||||
| ] |  | ||||||
| } |  | ||||||
| @ -1,25 +0,0 @@ | |||||||
| { |  | ||||||
| "ledger": |  | ||||||
| [ |  | ||||||
|   "314s49e1", |  | ||||||
|   "54479f3d", |  | ||||||
|   "674b56e3", |  | ||||||
|   "4c01589b", |  | ||||||
|   "7e170ef8", |  | ||||||
|   "7ac10d34", |  | ||||||
|   "640eeed3", |  | ||||||
|   "497509c8", |  | ||||||
|   "4828752f", |  | ||||||
|   "43c05737", |  | ||||||
|   "5397abab", |  | ||||||
|   "46631d0e", |  | ||||||
|   "75638b4d", |  | ||||||
|   "5cd72e22", |  | ||||||
|   "47770d57", |  | ||||||
|   "49258e97", |  | ||||||
|   "7e2c2e91", |  | ||||||
|   "688ee3e1", |  | ||||||
|   "7bfea52f", |  | ||||||
|   "57fa6a01" |  | ||||||
| ] |  | ||||||
| } |  | ||||||
| @ -1,581 +0,0 @@ | |||||||
| ( |  | ||||||
| // helper funcs |  | ||||||
| var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; |  | ||||||
| 
 |  | ||||||
| // score funcs |  | ||||||
| var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; |  | ||||||
| 
 |  | ||||||
| // subroutines |  | ||||||
| var genTuples, initVoices, genOrder, genSubMotif, updateVoices; |  | ||||||
| 
 |  | ||||||
| // primary routines |  | ||||||
| var genMotif, genSecondarySeq; |  | ||||||
| 
 |  | ||||||
| // audition funcs |  | ||||||
| var genPatterns, genMidiPatterns; |  | ||||||
| 
 |  | ||||||
| // resource management funcs |  | ||||||
| var writeResources, prettifyArray, setSeeds, sanityCheck, msgInterpret; |  | ||||||
| 
 |  | ||||||
| // global vars (many set by OSC funcs at bottom) |  | ||||||
| var refSeed, seed, lastXChanges, popSize, exPath, dir, primes, dims, tuples, ranges, durFunc, seq, group, player; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------helper funcs |  | ||||||
| 
 |  | ||||||
| hsArrayToCents = { |  | ||||||
| 	arg hsArray; |  | ||||||
| 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| pDist = { |  | ||||||
| 	arg array1, array2, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); |  | ||||||
| 	if(signed, {pDistance}, {abs(pDistance)}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hdSum = { |  | ||||||
| 	arg hsArrays; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays.size; |  | ||||||
| 	distances = (size - 1).collect({arg i; |  | ||||||
| 		((i + 1)..(size - 1)).collect({arg j; |  | ||||||
| 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsChordalDistance = { |  | ||||||
| 	arg hsArrays1, hsArrays2; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays1.size; |  | ||||||
| 	distances = hsArrays1.size.collect({arg i; |  | ||||||
| 		hsArrays2.size.collect({arg j; |  | ||||||
| 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsArrayToFreq = { |  | ||||||
| 	arg array; |  | ||||||
| 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------score funcs |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| isInRange = { |  | ||||||
| 	arg hsArray, min, max; |  | ||||||
| 	var cents; |  | ||||||
| 	cents = hsArrayToCents.value(hsArray); |  | ||||||
| 	(cents >= min) && (cents <= max) |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| spacingScore = { |  | ||||||
| 	arg hsArrays, min; |  | ||||||
| 	var centsArray; |  | ||||||
| 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); |  | ||||||
| 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| rangeScore = { |  | ||||||
| 	arg hsArray1, hsArray2, min, max, low, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| intervalScore = { |  | ||||||
| 	arg hsArray1, hsArray2, mean, sd, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	pDistance.gaussCurve(1, mean, sd) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| inclusionScore = { |  | ||||||
| 	arg array, test, min = 0.01; |  | ||||||
| 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------subroutines |  | ||||||
| 
 |  | ||||||
| genTuples = { |  | ||||||
| 	var tuples; |  | ||||||
| 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); |  | ||||||
| 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| initVoices = { |  | ||||||
| 	var init, voicesInit; |  | ||||||
| 	voicesInit = popSize.collect({dims.collect({0})}); |  | ||||||
| 	/* |  | ||||||
| 	voicesInit = [dims.collect({0})]; |  | ||||||
| 	(popSize - 1).do({ |  | ||||||
| 		arg rep, new; |  | ||||||
| 		rep = dims.rand; |  | ||||||
| 		new = voicesInit.last.deepCopy; |  | ||||||
| 		new[rep] = new[rep] + [-1, 1].choose(); |  | ||||||
| 		voicesInit = voicesInit.add(new); |  | ||||||
| 	}); |  | ||||||
| 	*/ |  | ||||||
| 	voicesInit.deepCopy; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genOrder = {arg minLength = 0, maxLength = 5; |  | ||||||
| 	var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; |  | ||||||
| 	noProgIns = (popSize - 1).rand + 1; |  | ||||||
| 	noSusIns = (popSize - noProgIns).rand + 1; |  | ||||||
| 	noSilentIns = popSize - noSusIns - noProgIns; |  | ||||||
| 
 |  | ||||||
| 	# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); |  | ||||||
| 
 |  | ||||||
| 	prog  = (prog.scramble ++ ((maxLength - minLength).rand + minLength).collect({prog.choose}).scramble); |  | ||||||
| 	if(silent == nil, {silent = []}); |  | ||||||
| 	[sus.scramble, prog, silent.scramble] |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| updateVoices = {arg ins, sus; |  | ||||||
| 	var voices, candidates, nWeights, nProbs, sel; |  | ||||||
| 
 |  | ||||||
| 	voices = lastXChanges.deepCopy.last; |  | ||||||
| 
 |  | ||||||
| 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; |  | ||||||
| 	candidates = difference(candidates.asSet, voices.asSet).asList; |  | ||||||
| 	nProbs = candidates.collect({arg candidate; |  | ||||||
| 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; |  | ||||||
| 
 |  | ||||||
| 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); |  | ||||||
| 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); |  | ||||||
| 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); |  | ||||||
| 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); |  | ||||||
| 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); |  | ||||||
| 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); |  | ||||||
| 		//maybe what you want here is a vector to another root and then favoring movement towards it. |  | ||||||
| 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); |  | ||||||
| 
 |  | ||||||
| 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	nWeights = [1, 1, 1, 1, 1]; |  | ||||||
| 
 |  | ||||||
| 	//this handles nWeights of 0; mainly for testing |  | ||||||
| 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; |  | ||||||
| 	nWeights = nWeights.select({arg weight; weight != 0}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; |  | ||||||
| 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) |  | ||||||
| 	}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; |  | ||||||
| 
 |  | ||||||
| 	sel = candidates.wchoose(nProbs); |  | ||||||
| 
 |  | ||||||
| 	voices[ins] = sel; |  | ||||||
| 	lastXChanges = lastXChanges.add(voices).keep(-5); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSubMotif = {arg order, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; |  | ||||||
| 	var sus, prog, silent, res, lastIns, lastXChangesHold, voices, adder; |  | ||||||
| 	# sus, prog, silent = order; |  | ||||||
| 	lastXChangesHold = lastXChanges.deepCopy; |  | ||||||
| 	voices = lastState.deepCopy; |  | ||||||
| 	lastIns = nil; |  | ||||||
| 	res = []; |  | ||||||
| 	"------generating motif".postln; |  | ||||||
| 	//need to figure out here if voices move between motifs |  | ||||||
| 	(silent ++ sus ++ prog).do({arg ins, i; |  | ||||||
| 
 |  | ||||||
| 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); |  | ||||||
| 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); |  | ||||||
| 
 |  | ||||||
| 		if(voices[ins] != adder, { |  | ||||||
| 			var dur; |  | ||||||
| 			//dur = [durFunc.value(), 0].wchoose([1, 0].normalizeSum); |  | ||||||
| 			dur = durFunc.value(lastIns, ins); |  | ||||||
| 			voices[ins] = adder; |  | ||||||
| 			res = res.add([voices.deepCopy.postln, dur.round(0.125)]); |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		lastIns = ins; |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	// pad ending |  | ||||||
| 	if(isLastOrder, { |  | ||||||
| 		(0..(popSize-1)).scramble.do({arg ins; |  | ||||||
| 			if(res.last.first[ins] != ["Rest"], { |  | ||||||
| 				var dur; |  | ||||||
| 				voices[ins] = ["Rest"]; |  | ||||||
| 				//dur = [durFunc.value(), 0].wchoose([1, 0].normalizeSum); |  | ||||||
| 				dur = durFunc.value(lastIns, ins); |  | ||||||
| 				res = res.add([voices.deepCopy.postln, dur.round(0.125)]); |  | ||||||
| 			}); |  | ||||||
| 			lastIns = ins; |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	//format and return |  | ||||||
| 	if(startFromLast, {lastXChanges = lastXChangesHold}); |  | ||||||
| 	res; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------primary routines |  | ||||||
| 
 |  | ||||||
| genMotif = {arg inOrders; |  | ||||||
| 	var orders, repeats, fSeq; |  | ||||||
| 
 |  | ||||||
| 	repeats = 1; |  | ||||||
| 	fSeq = []; |  | ||||||
| 
 |  | ||||||
| 	repeats.do({arg index; |  | ||||||
| 		var motif; |  | ||||||
| 
 |  | ||||||
| 		motif = []; |  | ||||||
| 		orders = inOrders; |  | ||||||
| 
 |  | ||||||
| 		orders.do({arg order, o; |  | ||||||
| 			var lastState, subMotif; |  | ||||||
| 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); |  | ||||||
| 			subMotif = genSubMotif.value(order, lastState, isLastOrder: o == (orders.size - 1)); |  | ||||||
| 			motif = motif.add(subMotif); |  | ||||||
| 
 |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		sanityCheck.value(motif, index); |  | ||||||
| 
 |  | ||||||
| 		fSeq = fSeq.add(motif); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSecondarySeq = {arg seq; |  | ||||||
| 	var curdles, fSeq; |  | ||||||
| 	curdles = []; |  | ||||||
| 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); |  | ||||||
| 
 |  | ||||||
| 	fSeq = seq.clumps(curdles).collect({arg clump, m; |  | ||||||
| 		var repeats, paddedSeq; |  | ||||||
| 
 |  | ||||||
| 		//add rest |  | ||||||
| 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); |  | ||||||
| 
 |  | ||||||
| 		//implement repeats |  | ||||||
| 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); |  | ||||||
| 		repeats.collect({paddedSeq}); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------audition funcs |  | ||||||
| 
 |  | ||||||
| genPatterns = {arg seq; |  | ||||||
| 	var voices, durs, patterns, res; |  | ||||||
| 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\instrument, \test, |  | ||||||
| 				\group, group, |  | ||||||
| 				\freq, Pseq(freqs, 1), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\sustain, Pseq(fDurs, 1) |  | ||||||
| 			); |  | ||||||
| 		}); |  | ||||||
| 		); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genMidiPatterns = {arg seq; |  | ||||||
| 	var voices, durs, patterns, res, mOut, pbRange; |  | ||||||
| 	pbRange = 1; //semitones - change this as needed for your situation |  | ||||||
| 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); |  | ||||||
| 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice, v; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 
 |  | ||||||
| 			mOut.program(v, 70); |  | ||||||
| 
 |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \midi, |  | ||||||
| 				\chan, v, |  | ||||||
| 				\noteval, Pseq(freqs.cpsmidi - 24, 1), |  | ||||||
| 				\note, Pfunc({ | event | event[\noteval].floor }), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\midiout, mOut, |  | ||||||
| 				\amp, 1, |  | ||||||
| 				\bend, Pfunc({ |  | ||||||
| 					| event | |  | ||||||
| 					if (event[\note].isRest.not) { |  | ||||||
| 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; |  | ||||||
| 						m.bend(v, pitchbendvalue); |  | ||||||
| 					}; |  | ||||||
| 					0; // return something other than nil to avoid stopping the pattern |  | ||||||
| 				}), |  | ||||||
| 			); |  | ||||||
| 		}); |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------resource management funcs |  | ||||||
| 
 |  | ||||||
| setSeeds = {arg inRefSeed, inSeed; |  | ||||||
| 	refSeed = if(inRefSeed.isNumber, {inRefSeed.asInteger}, {nil}); |  | ||||||
| 	seed = if(inSeed > 1, {inSeed.asInteger}, {rrand(100000, 999999)}); |  | ||||||
| 	thisThread.randSeed = seed; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| prettifyArray = {arg data, finDepth = 1; |  | ||||||
| 	var prettyString = "", rCount = 0, writeArray; |  | ||||||
| 
 |  | ||||||
| 	writeArray = {arg array; |  | ||||||
| 		var depth, indent; |  | ||||||
| 		depth = array.maxDepth; |  | ||||||
| 		indent = rCount.collect({"  "}).join(""); |  | ||||||
| 		prettyString = prettyString ++ indent ++ "[\n"; |  | ||||||
| 		rCount = rCount + 1; |  | ||||||
| 		if(depth > 5, { |  | ||||||
| 			array.do({arg subArray; |  | ||||||
| 				writeArray.value(subArray); |  | ||||||
| 			}); |  | ||||||
| 		}, { |  | ||||||
| 			array.do({arg data, d; |  | ||||||
| 				prettyString = prettyString ++ indent ++ "  " ++ data.asCompileString ++ if(d != (array.size - 1), {",\n"}, {""}); |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 		rCount = rCount - 1; |  | ||||||
| 		if(rCount < (finDepth - 1), {prettyString = prettyString.drop((finDepth - 1).neg)}); |  | ||||||
| 		//if(rCount == 0, {prettyString = prettyString.drop((finDepth - 1).neg)}); |  | ||||||
| 		prettyString = prettyString ++ "\n" ++ indent ++ "]" ++ if(rCount > 0, {",\n"}, {""}); |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	writeArray.value(data); |  | ||||||
| 	prettyString |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| writeResources = {arg seq, path; |  | ||||||
| 	var dir, file, resString; |  | ||||||
| 	file = File(path,"w"); |  | ||||||
| 
 |  | ||||||
| 	resString = "{\nmusic_data:\n"; |  | ||||||
| 	resString = resString ++ prettifyArray.value(seq, 3); |  | ||||||
| 
 |  | ||||||
| 	resString = resString ++ ",\nlast_changes:\n"; |  | ||||||
| 	resString = resString ++ prettifyArray.value(lastXChanges, 1); |  | ||||||
| 
 |  | ||||||
| 	resString = resString ++ ",\nseed: " ++ seed ++ ",\nref_seed: " ++ refSeed ++ "\n}"; |  | ||||||
| 
 |  | ||||||
| 	file.write(resString); |  | ||||||
| 	file.close; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| sanityCheck = {arg motif, index; |  | ||||||
| 	//print functions - very helpful |  | ||||||
| 	("----------" + index + "------------").postln; |  | ||||||
| 
 |  | ||||||
| 	motif.flatten.do({arg val, v; |  | ||||||
| 		if(v > 0, { |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); |  | ||||||
| 		}); |  | ||||||
| 		val.postln |  | ||||||
| 	}); |  | ||||||
| 	"***********".postln; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| msgInterpret = {arg in; |  | ||||||
| 	var res; |  | ||||||
| 	res = in.asCompileString; |  | ||||||
| 	res = res.replace(" ", "").replace("\n", "").replace("\t", ""); |  | ||||||
| 	res = res.replace("\'", "").replace("\"", "").replace("Rest", "\"Rest\""); |  | ||||||
| 	res.interpret |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------global vars |  | ||||||
| 
 |  | ||||||
| primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; |  | ||||||
| ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; |  | ||||||
| exPath = thisProcess.nowExecutingPath; |  | ||||||
| dir = exPath.dirname; |  | ||||||
| popSize = 4; |  | ||||||
| dims = primes.size; |  | ||||||
| tuples = genTuples.value(); |  | ||||||
| refSeed = nil; |  | ||||||
| group = Group.new; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------OSC funcs |  | ||||||
| 
 |  | ||||||
| OSCdef(\gen, {arg msg, time, addr, port; |  | ||||||
| 	var orders, condition; |  | ||||||
| 	msg.postln; |  | ||||||
| 	durFunc = nil; |  | ||||||
| 
 |  | ||||||
| 	addr.sendMsg("/STATE/SEND"); |  | ||||||
| 
 |  | ||||||
| 	{ |  | ||||||
| 		while({durFunc == nil}, {0.1.wait}); |  | ||||||
| 		setSeeds.value(msg[1].postln, msg[2]); |  | ||||||
| 
 |  | ||||||
| 		lastXChanges = if(refSeed == nil, { |  | ||||||
| 			[initVoices.value().deepCopy]; |  | ||||||
| 		}, { |  | ||||||
| 			var file; |  | ||||||
| 			file = File((dir +/+ "resources" +/+ refSeed ++ "_music" ++ ".json").standardizePath, "r"); |  | ||||||
| 			msgInterpret.value(file.readAllString.parseJSON["last_changes"]); |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		if(msg.size == 4, { |  | ||||||
| 			orders = msgInterpret.value(msg[3]); |  | ||||||
| 		}, { |  | ||||||
| 			var minLength, maxLength; |  | ||||||
| 			minLength = msg[3]; |  | ||||||
| 			maxLength = msg[4]; |  | ||||||
| 			orders = ((maxLength - minLength).rand + minLength).collect({genOrder.value(msg[5], msg[6])}); |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		orders.postln; |  | ||||||
| 		seed.postln; |  | ||||||
| 		refSeed.postln; |  | ||||||
| 
 |  | ||||||
| 		seq = genMotif.value(orders); |  | ||||||
| 		//patterns = genPatterns.value(seq); |  | ||||||
| 		addr.sendMsg("/current_seed", seed); |  | ||||||
| 		addr.sendMsg("/order", prettifyArray.value(orders, 1)); |  | ||||||
| 		addr.sendMsg("/mus_seq", prettifyArray.value(seq, 3)); |  | ||||||
| 	}.fork; |  | ||||||
| 
 |  | ||||||
| }, \gen); |  | ||||||
| 
 |  | ||||||
| OSCdef(\commit, {arg msg, time, addr, port; |  | ||||||
| 	var ledgerPath, oldLedger, newLedger, musSeq; |  | ||||||
| 	//msg.postln; |  | ||||||
| 	seed.postln; |  | ||||||
| 	//File.copy(exPath, (dir +/+ "resources" +/+ seed ++ "_code" ++ ".scd").standardizePath); |  | ||||||
| 	//addr.sendMsg("/SESSION/SAVE", (dir +/+ "resources" +/+ seed ++ "_gui_session" ++ ".json").standardizePath); |  | ||||||
| 	//addr.sendMsg("/STATE/SAVE", (dir +/+ "resources" +/+ seed ++ "_gui_state" ++ ".state").standardizePath); |  | ||||||
| 
 |  | ||||||
| 	writeResources.value(seq, (dir +/+ "resources" +/+ seed ++ "_music" ++ ".json").standardizePath); |  | ||||||
| 
 |  | ||||||
| 	ledgerPath = (dir +/+ "resources" +/+ "piece_ledger" ++ ".json").standardizePath; |  | ||||||
| 	oldLedger = File(ledgerPath, "r"); |  | ||||||
| 	musSeq = msgInterpret.value(oldLedger.readAllString.parseJSON["ledger"]); |  | ||||||
| 	oldLedger.close; |  | ||||||
| 	File.delete(ledgerPath ++ "_bak"); |  | ||||||
| 	File.copy(ledgerPath, ledgerPath ++ "_bak"); |  | ||||||
| 	File.delete(ledgerPath); |  | ||||||
| 	newLedger = File(ledgerPath, "w"); |  | ||||||
| 	musSeq = musSeq.add(seed); |  | ||||||
| 	newLedger.write("{\nledger:\n" ++ prettifyArray.value(musSeq, 1) ++ "\n}"); |  | ||||||
| 	newLedger.close; |  | ||||||
| 
 |  | ||||||
| 	//refSeed = seed; |  | ||||||
| }, \commit); |  | ||||||
| 
 |  | ||||||
| OSCdef(\transport, {arg msg, time, addr, port; |  | ||||||
| 	msg.postln; |  | ||||||
| 	if(msg[1] == 0, { |  | ||||||
| 		player.stop; |  | ||||||
| 		group.set(\gate, 0); |  | ||||||
| 	}, { |  | ||||||
| 		var cSize, ledgerPath, ledger, patterns, pSeq; |  | ||||||
| 		ledgerPath = (dir +/+ "resources" +/+ "piece_ledger" ++ ".json").standardizePath; |  | ||||||
| 		ledger = msgInterpret.value(File(ledgerPath, "r").readAllString.parseJSON["ledger"]); |  | ||||||
| 		pSeq = []; |  | ||||||
| 		if(msg[2].asString != "all", {ledger = ledger.keep(msg[2].asInteger - 1)}); |  | ||||||
| 		ledger.do({arg rSeed; |  | ||||||
| 			var file; |  | ||||||
| 			file = File((dir +/+ "resources" +/+ rSeed.postln ++ "_music" ++ ".json").standardizePath, "r"); |  | ||||||
| 			pSeq = pSeq.add(msgInterpret.value(file.readAllString.parseJSON["music_data"])); |  | ||||||
| 			file.close; |  | ||||||
| 		}); |  | ||||||
| 		pSeq = pSeq.add(seq); |  | ||||||
| 		patterns = genPatterns.value(pSeq); |  | ||||||
| 		player = Pfset(pattern: patterns, cleanupFunc: { |  | ||||||
| 			addr.sendMsg("/transport", 0); |  | ||||||
| 		}); |  | ||||||
| 		player = player.play |  | ||||||
| 	}); |  | ||||||
| }, \transport); |  | ||||||
| 
 |  | ||||||
| OSCdef(\range, {arg msg; |  | ||||||
| 	msg.postln; |  | ||||||
| 	ranges[msg[1]][msg[2]] = msg[3] |  | ||||||
| }, \range); |  | ||||||
| 
 |  | ||||||
| OSCdef(\dur_probs_env, {arg msg; |  | ||||||
| 	var env, pTable, min, max, cProb; |  | ||||||
| 	msg.postln; |  | ||||||
| 	env = Env.pairs([[0, 0]] ++ msg[4..].clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; |  | ||||||
| 	pTable = env.asRandomTable; |  | ||||||
| 	min = msg[1]; |  | ||||||
| 	max = msg[2]; |  | ||||||
| 	cProb = msg[3]; |  | ||||||
| 	durFunc = {arg lIns, cIns; |  | ||||||
| 		if(lIns.postln == cIns.postln, { |  | ||||||
| 			pTable.tableRand * (max - min) + min |  | ||||||
| 		}, { |  | ||||||
| 			if(1.0.rand < cProb.postln, {0}, {pTable.tableRand * (max - min) + min}).postln; |  | ||||||
| 		}); |  | ||||||
| 	}; |  | ||||||
| }, \dur_probs_env); |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	freq = WhiteNoise.ar * 3 + freq; |  | ||||||
| 	freqFinal = Duty.ar((1/freq), 0, freq); |  | ||||||
| 	trig = Changed.ar(freqFinal); |  | ||||||
| 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); |  | ||||||
| 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); |  | ||||||
| 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 
 |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| File((~dir +/+ "resources" +/+ 517313 ++ "_music" ++ ".json").standardizePath, "r").readAllString.parseJSON["last_changes"].asString.interpret[0][0][0].isNumber |  | ||||||
| 
 |  | ||||||
| "{\"a\": 1}".parseYAML["a"].asInteger; |  | ||||||
| "{\"a\": 1}".parseJSON["a"].isNumber; |  | ||||||
| @ -1,74 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|   [ |  | ||||||
|     [ |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.875 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.625 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.5 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.0 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.0 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.75 ] |  | ||||||
|     ], |  | ||||||
|     [ |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|       [ [ [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.5 ], |  | ||||||
|       [ [ [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|       [ [ [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.375 ], |  | ||||||
|       [ [ [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.75 ], |  | ||||||
|       [ [ [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.625 ], |  | ||||||
|       [ [ [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.75 ], |  | ||||||
|       [ [ [ 0, 0, 0, 0, 0, 1 ], [ "Rest" ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.125 ], |  | ||||||
|       [ [ [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|       [ [ [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.0 ], |  | ||||||
|       [ [ [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ] |  | ||||||
|     ], |  | ||||||
|     [ |  | ||||||
|       [ [ [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|       [ [ [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 0.75 ], |  | ||||||
|       [ [ [ 0, 0, 0, 1, -1, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 1.5 ], |  | ||||||
|       [ [ [ 0, 0, 0, 1, -1, 0 ], [ 0, 0, 0, 0, -1, 1 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 1.25 ], |  | ||||||
|       [ [ [ 0, 0, 0, 1, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 0.625 ], |  | ||||||
|       [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 0.625 ], |  | ||||||
|       [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 0.625 ], |  | ||||||
|       [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ] ], 1.375 ], |  | ||||||
|       [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ] ], 1.375 ], |  | ||||||
|       [ [ [ 2, 0, 0, -1, -1, 0 ], [ 0, 0, 1, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ] ], 1.5 ], |  | ||||||
|       [ [ [ 2, 0, 0, 0, -1, -1 ], [ 0, 0, 1, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ] ], 0.75 ], |  | ||||||
|       [ [ [ 2, 0, 0, 0, -1, -1 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ] ], 1.0 ] |  | ||||||
|     ], |  | ||||||
|     [ |  | ||||||
|       [ [ [ 2, 0, 0, 0, -1, -1 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, 0, 0, -1, -1, 0 ] ], 0.75 ], |  | ||||||
|       [ [ [ 2, 0, 0, 0, -1, -1 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 0, -1, 0, 1, -1, 0 ] ], 1.0 ], |  | ||||||
|       [ [ [ 2, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 0, -1, 0, 1, -1, 0 ] ], 0.875 ], |  | ||||||
|       [ [ [ 2, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 0, -1, 0, 0, -1, 1 ] ], 1.25 ], |  | ||||||
|       [ [ [ 1, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 0, -1, 0, 0, -1, 1 ] ], 1.125 ], |  | ||||||
|       [ [ [ 1, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, -1, -1, 0, -1, 0 ] ], 1.0 ], |  | ||||||
|       [ [ [ 1, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, -1, -1, 0, -1, 0 ] ], 0.75 ], |  | ||||||
|       [ [ [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, -1, -1, 0, -1, 0 ] ], 0.625 ], |  | ||||||
|       [ [ [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 0, -1, 0, 0, 0, 0 ] ], 0.75 ], |  | ||||||
|       [ [ [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -2, 0 ] ], 1.375 ], |  | ||||||
|       [ [ [ 2, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -2, 0 ] ], 0.875 ], |  | ||||||
|       [ [ [ 2, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 0, -1, 0, 0, -1, 1 ] ], 3.375 ], |  | ||||||
|       [ [ [ 2, -2, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ], [ 0, -1, 0, 0, -1, 1 ] ], 1.5 ], |  | ||||||
|       [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, -1, 0, 0, -1, 1 ] ], 1.375 ], |  | ||||||
|       [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.0 ] |  | ||||||
|     ] |  | ||||||
|   ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, -1, 0, -1, 0 ] ], |  | ||||||
|   [ [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ] ], |  | ||||||
|   [ [ 2, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ] ], |  | ||||||
|   [ [ 2, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, -1, 0, 0, -1, 1 ] ] |  | ||||||
| ], |  | ||||||
| "ref_uid": "nil" |  | ||||||
| } |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,55 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 6.875 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.5 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 1, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 8.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 1, 1, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 7.125 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "43c05737", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 872619, |  | ||||||
| "dur_seed": 747240, |  | ||||||
| "motifs_seed": 993768, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 2, 1 ], [ 3, 0, 0, 3, 0 ], [  ] ], |  | ||||||
|   [ [ 3 ], [ 2, 2 ], [ 1, 0 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,67 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 6 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.5 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], 2.375 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 1, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 8.5 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 10.875 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 1, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 1, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "46631d0e", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 256558, |  | ||||||
| "dur_seed": 519192, |  | ||||||
| "motifs_seed": 404168, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 3, 2, 1 ], [ 0, 0 ], [  ] ], |  | ||||||
|   [ [ 0 ], [ 1, 3, 2, 3, 1, 3 ], [  ] ], |  | ||||||
|   [ [ 2, 0 ], [ 1, 1, 1, 1, 1, 1, 1 ], [ 3 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,84 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 3.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, -1, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 2.875 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ], 7.5 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 0 ], [ 1, 1, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ], 5 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, 0, 0, -1, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 1 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, -1 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, -1, 1 ], [ 2, 0, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 3.625 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, -1, 1 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.375 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 1, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 1, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, -1, 1 ], [ 2, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 0, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "47770d57", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 168914, |  | ||||||
| "dur_seed": 252278, |  | ||||||
| "motifs_seed": 746067, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 1, 0 ], [ 3, 2, 2, 2, 2, 3, 3 ], [  ] ], |  | ||||||
|   [ [ 3, 1 ], [ 2, 0, 2, 0, 0, 2, 2, 2, 0 ], [  ] ], |  | ||||||
|   [ [ 0, 3, 2 ], [ 1, 1, 1, 1 ], [  ] ], |  | ||||||
|   [ [ 1 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 3, 2 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,85 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 4.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 9.75 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.125 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 5.125 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 8 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, -1, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 1, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.25 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, -1, 0, 0, -1, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, -1, 0, 0, 0, -2 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 4.5 ], |  | ||||||
|     [ [ [ 2, -1, 0, 0, 0, -2 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 2, -1, 0, 0, 0, -2 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 2, -1, 0, 0, 0, -2 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 8.375 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 2, -1, 0, 0, 0, -2 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "4828752f", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 530867, |  | ||||||
| "dur_seed": 693890, |  | ||||||
| "motifs_seed": 655880, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 3, 1, 0 ], [ 2, 2, 2, 2, 2 ], [  ] ], |  | ||||||
|   [ [ 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 3, 2 ] ], |  | ||||||
|   [ [ 0, 1, 3 ], [ 2, 2, 2, 2, 2, 2, 2, 2 ], [  ] ], |  | ||||||
|   [ [ 1, 3, 2 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,60 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 4.875 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.125 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, -1 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, -1 ] ], 1.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, -1 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 2, 0, 0, -1, 0, -1 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.875 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, -1, 0, -1, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, -1, 0, -1, -1 ], [ 2, 0, -1, 0, -1, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, -1, 0, -1, 0 ], [ 2, 0, -1, 0, -1, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 2, 0, -1, 0, -1, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, -1, 0, -1, 0 ], [ 1, 1, -1, 0, -1, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "49258e97", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 170731, |  | ||||||
| "dur_seed": 143948, |  | ||||||
| "motifs_seed": 177295, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 1, 2 ], [ 3, 3, 3 ], [  ] ], |  | ||||||
|   [ [ 3, 1, 0 ], [ 2, 2, 2, 2 ], [  ] ], |  | ||||||
|   [ [ 3 ], [ 2, 2, 2, 2 ], [ 0, 1 ] ], |  | ||||||
|   [ [ 2 ], [ 3, 3, 3, 3, 3, 3 ], [ 0, 1 ] ], |  | ||||||
|   [ [ 0, 2 ], [ 1, 1, 1, 1 ], [ 3 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "true", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,89 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 5.875 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 2, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 2, 0, 0, -1, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 7.375 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 10.25 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 1, 0, 0, 1 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 1, 0, 0, 1 ], [ 0, 0, 1, -1, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 4.5 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 6.25 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 1 ], [ 1, -1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 4.625 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, 1, 0, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, 1, 0, 1, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, 1, 0, 1, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, 1, 0, 1, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, 1, 0, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 2, -1, -1, 0, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 1, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 1, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, -1, 0 ] ], 6.75 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 2, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, -1, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 5.125 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 1, 0, 1, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 1, 0, 0, 0 ], [ 2, -1, -1, 0, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 1, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 1, 0 ], [ 2, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, -1, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "497509c8", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 692203, |  | ||||||
| "dur_seed": 827893, |  | ||||||
| "motifs_seed": 871275, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 3, 2 ], [ 1, 0, 1, 0, 0, 1, 0, 1, 1, 0 ], [  ] ], |  | ||||||
|   [ [ 0, 2 ], [ 1 ], [ 3 ] ], |  | ||||||
|   [ [ 3, 1 ], [ 2, 2, 2 ], [ 0 ] ], |  | ||||||
|   [ [ 3, 0 ], [ 2, 1, 2 ], [  ] ], |  | ||||||
|   [ [ 2, 0 ], [ 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 3 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,718 +0,0 @@ | |||||||
| ( |  | ||||||
| // helper funcs |  | ||||||
| var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; |  | ||||||
| 
 |  | ||||||
| // score funcs |  | ||||||
| var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; |  | ||||||
| 
 |  | ||||||
| // subroutines |  | ||||||
| var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; |  | ||||||
| 
 |  | ||||||
| // primary routines |  | ||||||
| var genMotif, genSecondarySeq; |  | ||||||
| 
 |  | ||||||
| // audition funcs |  | ||||||
| var genPatterns, genMidiPatterns; |  | ||||||
| 
 |  | ||||||
| // resource management funcs |  | ||||||
| var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, |  | ||||||
| msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON; |  | ||||||
| 
 |  | ||||||
| // model vars |  | ||||||
| //(model and global vars mostly set by OSC funcs |  | ||||||
| var curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| ranges, orders, susWeights, passagesWeights, passagesSize, orderSize; |  | ||||||
| 
 |  | ||||||
| // model aux vars |  | ||||||
| var entrancesDurFunc, passagesDurFunc, exitsDurFunc; |  | ||||||
| 
 |  | ||||||
| // other global vars |  | ||||||
| var lastXChanges, popSize, exPath, dir, primes, dims, tuples, |  | ||||||
| seq, group, player, ledgerPath, ledger, currentlyPlayingUID; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // install JSON quark |  | ||||||
| if(Quarks.isInstalled("JSONlib").not, { |  | ||||||
| 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); |  | ||||||
| 	thisProcess.recompile; |  | ||||||
| 	//HelpBrowser.openHelpFor("Classes/JSONlib"); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------helper funcs |  | ||||||
| 
 |  | ||||||
| hsArrayToCents = { |  | ||||||
| 	arg hsArray; |  | ||||||
| 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| pDist = { |  | ||||||
| 	arg array1, array2, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); |  | ||||||
| 	if(signed, {pDistance}, {abs(pDistance)}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hdSum = { |  | ||||||
| 	arg hsArrays; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays.size; |  | ||||||
| 	distances = (size - 1).collect({arg i; |  | ||||||
| 		((i + 1)..(size - 1)).collect({arg j; |  | ||||||
| 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsChordalDistance = { |  | ||||||
| 	arg hsArrays1, hsArrays2; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays1.size; |  | ||||||
| 	distances = hsArrays1.size.collect({arg i; |  | ||||||
| 		hsArrays2.size.collect({arg j; |  | ||||||
| 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsArrayToFreq = { |  | ||||||
| 	arg array; |  | ||||||
| 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| //------score funcs |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| isInRange = { |  | ||||||
| 	arg hsArray, min, max; |  | ||||||
| 	var cents; |  | ||||||
| 	cents = hsArrayToCents.value(hsArray); |  | ||||||
| 	(cents >= min) && (cents <= max) |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| spacingScore = { |  | ||||||
| 	arg hsArrays, min; |  | ||||||
| 	var centsArray; |  | ||||||
| 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); |  | ||||||
| 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| rangeScore = { |  | ||||||
| 	arg hsArray1, hsArray2, min, max, low, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| intervalScore = { |  | ||||||
| 	arg hsArray1, hsArray2, mean, sd, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	pDistance.gaussCurve(1, mean, sd) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| inclusionScore = { |  | ||||||
| 	arg array, test, min = 0.01; |  | ||||||
| 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------subroutines |  | ||||||
| 
 |  | ||||||
| genTuples = { |  | ||||||
| 	var tuples; |  | ||||||
| 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); |  | ||||||
| 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| initVoices = { |  | ||||||
| 	var init, voicesInit; |  | ||||||
| 	voicesInit = popSize.collect({dims.collect({0})}); |  | ||||||
| 	/* |  | ||||||
| 	voicesInit = [dims.collect({0})]; |  | ||||||
| 	(popSize - 1).do({ |  | ||||||
| 		arg rep, new; |  | ||||||
| 		rep = dims.rand; |  | ||||||
| 		new = voicesInit.last.deepCopy; |  | ||||||
| 		new[rep] = new[rep] + [-1, 1].choose(); |  | ||||||
| 		voicesInit = voicesInit.add(new); |  | ||||||
| 	}); |  | ||||||
| 	*/ |  | ||||||
| 	voicesInit.deepCopy; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genDurFunc = {arg chordProb, min, max, envData; |  | ||||||
| 	var env, pTable, durFunc; |  | ||||||
| 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; |  | ||||||
| 	pTable = env.asRandomTable; |  | ||||||
| 	durFunc = {arg allowChord; |  | ||||||
| 		var res; |  | ||||||
| 		res = if(allowChord.not, { |  | ||||||
| 			pTable.tableRand * (max - min) + min |  | ||||||
| 		}, { |  | ||||||
| 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (max - min) + min}); |  | ||||||
| 		}).round(0.125); |  | ||||||
| 		if(res.asInteger == res, {res = res.asInteger}); |  | ||||||
| 		res |  | ||||||
| 	}; |  | ||||||
| 	seedFunc.value(durFunc, durSeed); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; |  | ||||||
| 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ |  | ||||||
| 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; |  | ||||||
| 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); |  | ||||||
| 		noProgIns = (popSize - noSusIns).rand + 1; |  | ||||||
| 		noSilentIns = popSize - noSusIns - noProgIns; |  | ||||||
| 
 |  | ||||||
| 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); |  | ||||||
| 
 |  | ||||||
| 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); |  | ||||||
| 		if(silent == nil, {silent = []}); |  | ||||||
| 		[sus.scramble, prog, silent.scramble] |  | ||||||
| 	}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| updateVoices = {arg ins, sus; |  | ||||||
| 	var voices, candidates, nWeights, nProbs, sel; |  | ||||||
| 
 |  | ||||||
| 	voices = lastXChanges.deepCopy.last; |  | ||||||
| 
 |  | ||||||
| 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; |  | ||||||
| 	candidates = difference(candidates.asSet, voices.asSet).asList; |  | ||||||
| 	nProbs = candidates.collect({arg candidate; |  | ||||||
| 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; |  | ||||||
| 
 |  | ||||||
| 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); |  | ||||||
| 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); |  | ||||||
| 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); |  | ||||||
| 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); |  | ||||||
| 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); |  | ||||||
| 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); |  | ||||||
| 		//maybe what you want here is a vector to another root and then favoring movement towards it. |  | ||||||
| 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); |  | ||||||
| 
 |  | ||||||
| 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	nWeights = passagesWeights; |  | ||||||
| 
 |  | ||||||
| 	//this handles nWeights of 0; mainly for testing |  | ||||||
| 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; |  | ||||||
| 	nWeights = nWeights.select({arg weight; weight != 0}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; |  | ||||||
| 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) |  | ||||||
| 	}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; |  | ||||||
| 
 |  | ||||||
| 	sel = candidates.wchoose(nProbs); |  | ||||||
| 
 |  | ||||||
| 	voices[ins] = sel; |  | ||||||
| 	lastXChanges = lastXChanges.add(voices).keep(-5); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSubMotif = {arg order, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; |  | ||||||
| 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, lastXChangesHold, voices, adder; |  | ||||||
| 	# sus, prog, silent = order; |  | ||||||
| 	flatOrder = silent ++ sus ++ prog; |  | ||||||
| 	lastXChangesHold = lastXChanges.deepCopy; |  | ||||||
| 	voices = lastState.deepCopy; |  | ||||||
| 	isInChord = popSize.collect({false}); |  | ||||||
| 	allowChord = false; |  | ||||||
| 	res = []; |  | ||||||
| 	"------generating motif".postln; |  | ||||||
| 	//need to figure out here if voices move between motifs |  | ||||||
| 	flatOrder.do({arg ins, i; |  | ||||||
| 
 |  | ||||||
| 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); |  | ||||||
| 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); |  | ||||||
| 
 |  | ||||||
| 		if(voices[ins] != adder, { |  | ||||||
| 			var dur; |  | ||||||
| 			allowChord = if((sus ++ silent).includes(ins), { |  | ||||||
| 				(sus ++ silent).includes(ins) && (ins != sus.last); |  | ||||||
| 			}, { |  | ||||||
| 				if(i < (flatOrder.size - 1), {(isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not}, {false}); |  | ||||||
| 			}); |  | ||||||
| 			dur = passagesDurFunc.value(allowChord); |  | ||||||
| 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); |  | ||||||
| 
 |  | ||||||
| 			voices[ins] = adder; |  | ||||||
| 			res = res.add([voices.deepCopy.postln, dur]); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	// pad ending |  | ||||||
| 	if(isLastOrder, { |  | ||||||
| 		(0..(popSize-1)).scramble.do({arg ins; |  | ||||||
| 			if(res.last.first[ins] != ["Rest"], { |  | ||||||
| 				var dur; |  | ||||||
| 				voices[ins] = ["Rest"]; |  | ||||||
| 				allowChord = (voices != popSize.collect({["Rest"]})); |  | ||||||
| 				dur = passagesDurFunc.value(allowChord); |  | ||||||
| 				res = res.add([voices.deepCopy.postln, dur]); |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	//format and return |  | ||||||
| 	if(startFromLast, {lastXChanges = lastXChangesHold}); |  | ||||||
| 	res; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------primary routines |  | ||||||
| 
 |  | ||||||
| genMotif = { |  | ||||||
| 	var repeats, fSeq; |  | ||||||
| 
 |  | ||||||
| 	repeats = 1; |  | ||||||
| 	fSeq = []; |  | ||||||
| 
 |  | ||||||
| 	repeats.do({arg index; |  | ||||||
| 		var motif; |  | ||||||
| 
 |  | ||||||
| 		motif = []; |  | ||||||
| 
 |  | ||||||
| 		orders.do({arg order, o; |  | ||||||
| 			var lastState, subMotif; |  | ||||||
| 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); |  | ||||||
| 			subMotif = genSubMotif.value(order, lastState, isLastOrder: o == (orders.size - 1)); |  | ||||||
| 			motif = motif.add(subMotif); |  | ||||||
| 
 |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		sanityCheck.value(motif, index); |  | ||||||
| 
 |  | ||||||
| 		fSeq = fSeq.add(motif); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSecondarySeq = {arg seq; |  | ||||||
| 	var curdles, fSeq; |  | ||||||
| 	curdles = []; |  | ||||||
| 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); |  | ||||||
| 
 |  | ||||||
| 	fSeq = seq.clumps(curdles).collect({arg clump, m; |  | ||||||
| 		var repeats, paddedSeq; |  | ||||||
| 
 |  | ||||||
| 		//add rest |  | ||||||
| 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); |  | ||||||
| 
 |  | ||||||
| 		//implement repeats |  | ||||||
| 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); |  | ||||||
| 		repeats.collect({paddedSeq}); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------audition funcs |  | ||||||
| 
 |  | ||||||
| Event.addEventType(\osc, { |  | ||||||
| 	if (~addr.postln.notNil) { |  | ||||||
| 		~addr.sendMsg(~indexPath, ~indexMsg); |  | ||||||
| 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); |  | ||||||
| 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); |  | ||||||
| 	}; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| genPatterns = {arg inSeq, addr; |  | ||||||
| 	var voices, durs, patterns, res, indices, sectionDurs, ids, seq; |  | ||||||
| 	seq = inSeq.collect({arg mSeq; mSeq[0]}); |  | ||||||
| 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	indices = inSeq.collect({arg mSeq, m; mSeq[1]}); |  | ||||||
| 	ids = inSeq.collect({arg mSeq, m; mSeq[2]}); |  | ||||||
| 	sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\instrument, \test, |  | ||||||
| 				\group, group, |  | ||||||
| 				\freq, Pseq(freqs, 1), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\sustain, Pseq(fDurs, 1) |  | ||||||
| 			) |  | ||||||
| 		}) ++ |  | ||||||
| 		[ |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \osc, |  | ||||||
| 				\addr, addr, |  | ||||||
| 				\indexPath, "/cur_play_index", |  | ||||||
| 				\indexMsg, Pseq(indices.postln, 1), |  | ||||||
| 				\seqPath, "/mus_seq", |  | ||||||
| 				\seqMsg, Pseq(seq, 1), |  | ||||||
| 				\dur, Pseq(sectionDurs, 1) |  | ||||||
| 			); |  | ||||||
| 		] |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| genMidiPatterns = {arg seq; |  | ||||||
| 	var voices, durs, patterns, res, mOut, pbRange; |  | ||||||
| 	pbRange = 1; //semitones - change this as needed for your situation |  | ||||||
| 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); |  | ||||||
| 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice, v; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 
 |  | ||||||
| 			mOut.program(v, 70); |  | ||||||
| 
 |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \midi, |  | ||||||
| 				\chan, v, |  | ||||||
| 				\noteval, Pseq(freqs.cpsmidi - 24, 1), |  | ||||||
| 				\note, Pfunc({ | event | event[\noteval].floor }), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\midiout, mOut, |  | ||||||
| 				\amp, 1, |  | ||||||
| 				\bend, Pfunc({ |  | ||||||
| 					| event | |  | ||||||
| 					if (event[\note].isRest.not) { |  | ||||||
| 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; |  | ||||||
| 						m.bend(v, pitchbendvalue); |  | ||||||
| 					}; |  | ||||||
| 					0; // return something other than nil to avoid stopping the pattern |  | ||||||
| 				}), |  | ||||||
| 			); |  | ||||||
| 		}); |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------resource management funcs |  | ||||||
| 
 |  | ||||||
| genUID = {Date.seed.asHexString.toLower}; |  | ||||||
| 
 |  | ||||||
| seedFunc = {arg func, seed; |  | ||||||
| 	var funcArgs, next; |  | ||||||
| 	next = Routine({loop{func.valueArray(funcArgs).yield }}); |  | ||||||
| 	next.randSeed_(seed); |  | ||||||
| 	{arg ...args; funcArgs = args; next.value} |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| stringifyToDepth = {arg data, maxDepth = 1; |  | ||||||
| 	var prettyString = "", rCount = 0, writeArray, indent; |  | ||||||
| 
 |  | ||||||
| 	if(maxDepth == 0, { |  | ||||||
| 		data.asCompileString |  | ||||||
| 	}, { |  | ||||||
| 		indent = {arg size; size.collect({" "}).join("")}; |  | ||||||
| 		writeArray = {arg array; |  | ||||||
| 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; |  | ||||||
| 			rCount = rCount + 1; |  | ||||||
| 			if(rCount < (maxDepth - 0), { |  | ||||||
| 				array.do({arg subArray; writeArray.value(subArray)}); |  | ||||||
| 			}, { |  | ||||||
| 				prettyString = prettyString ++ array.collect({arg subArray; |  | ||||||
| 					indent.value(rCount + 1) ++ subArray.asCompileString |  | ||||||
| 				}).join(",\n"); |  | ||||||
| 			}); |  | ||||||
| 			rCount = rCount - 1; |  | ||||||
| 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		writeArray.value(data); |  | ||||||
| 		prettyString.replace(",\n\n", "\n").drop(-2); |  | ||||||
| 	}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| sanityCheck = {arg motif, index; |  | ||||||
| 	//print functions = very helpful |  | ||||||
| 	("----------" + index + "------------").postln; |  | ||||||
| 
 |  | ||||||
| 	motif.flatten.do({arg val, v; |  | ||||||
| 		if(v > 0, { |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); |  | ||||||
| 		}); |  | ||||||
| 		val.postln |  | ||||||
| 	}); |  | ||||||
| 	"***********".postln; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; |  | ||||||
| 	var res; |  | ||||||
| 
 |  | ||||||
| 	res = in; |  | ||||||
| 	if(res.isNil.not, { |  | ||||||
| 		if((res.isArray && res.isString.not), { |  | ||||||
| 			res = res.asCompileString; |  | ||||||
| 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); |  | ||||||
| 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); |  | ||||||
| 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); |  | ||||||
| 			res = res.replace("Rest", "\"Rest\""); |  | ||||||
| 			res = res.interpret; |  | ||||||
| 		}, { |  | ||||||
| 			//res.postln; |  | ||||||
| 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| writeResources = {arg path; |  | ||||||
| 	var file, nameSpaces, modelItems, resString; |  | ||||||
| 	file = File(path,"w"); |  | ||||||
| 
 |  | ||||||
| 	nameSpaces = [ |  | ||||||
| 		"music_data", "last_changes", |  | ||||||
| 		"cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", |  | ||||||
| 		"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", |  | ||||||
| 		"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size" |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	modelItems = [ |  | ||||||
| 		seq, lastXChanges, |  | ||||||
| 		curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| 		entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	resString = [nameSpaces, modelItems].flop.collect({arg item; |  | ||||||
| 		var nameSpace, modelItem, depth = 0, insert = " "; |  | ||||||
| 		# nameSpace, modelItem = item; |  | ||||||
| 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); |  | ||||||
| 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); |  | ||||||
| 		if(nameSpace == "order", {depth = 1; insert = "\n"}); |  | ||||||
| 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(modelItem.postln, depth).postln |  | ||||||
| 	}).join(",\n"); |  | ||||||
| 
 |  | ||||||
| 	resString = "{\n" ++ resString ++ "\n}"; |  | ||||||
| 
 |  | ||||||
| 	file.write(resString); |  | ||||||
| 	file.close; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; |  | ||||||
| 
 |  | ||||||
| loadModelJSON = {arg model; |  | ||||||
| 	var nameSpaces, data; |  | ||||||
| 
 |  | ||||||
| 	//model = File(path, "r").readAllString.parseJSON; |  | ||||||
| 
 |  | ||||||
| 	nameSpaces = [ |  | ||||||
| 		"cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", |  | ||||||
| 		"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", |  | ||||||
| 		"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size" |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	data = nameSpaces.collect({arg nS; msgInterpret.value(model[nS]).postln}); |  | ||||||
| 
 |  | ||||||
| 	data.postln; |  | ||||||
| 
 |  | ||||||
| 	# curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| 	entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize = data; |  | ||||||
| 
 |  | ||||||
| 	popSize = ranges.size; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadLedgerFile = {arg path; |  | ||||||
| 	ledgerPath = path; |  | ||||||
| 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadLedgerJSON = {arg ledger; ledger = ledger["ledger"]}; |  | ||||||
| 
 |  | ||||||
| //------global vars |  | ||||||
| 
 |  | ||||||
| primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; |  | ||||||
| //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; |  | ||||||
| exPath = thisProcess.nowExecutingPath; |  | ||||||
| dir = exPath.dirname; |  | ||||||
| //popSize = 4; |  | ||||||
| dims = primes.size; |  | ||||||
| tuples = genTuples.value(); |  | ||||||
| //refUID = nil; |  | ||||||
| group = Group.new; |  | ||||||
| loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); |  | ||||||
| //passagesWeights = [1, 1, 1, 1, 1]; |  | ||||||
| //susWeights = [1, 1, 1]; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------OSC funcs |  | ||||||
| 
 |  | ||||||
| OSCdef(\load_ledger, {arg msg, time, addr, port; |  | ||||||
| 	loadLedgerFile.value(msg[1].asString); |  | ||||||
| }, \load_ledger); |  | ||||||
| 
 |  | ||||||
| OSCdef(\load_model, {arg msg, time, addr, port; |  | ||||||
| 	loadModelFile.value(msg[1].asString); |  | ||||||
| }, \load_model); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| OSCdef(\generate, {arg msg, time, addr, port; |  | ||||||
| 	var path, dFormat, condition, musPath; |  | ||||||
| 	msg.postln; |  | ||||||
| 
 |  | ||||||
| 	path = msg[1].asString; |  | ||||||
| 
 |  | ||||||
| 	loadModelFile.value(path); |  | ||||||
| 
 |  | ||||||
| 	refUID.postln; |  | ||||||
| 
 |  | ||||||
| 	loadLedgerFile.value(ledgerPath); |  | ||||||
| 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); |  | ||||||
| 
 |  | ||||||
| 	lastXChanges = if(refUID == nil, { |  | ||||||
| 		[initVoices.value().deepCopy]; |  | ||||||
| 	}, { |  | ||||||
| 		var file; |  | ||||||
| 		refUID.postln; |  | ||||||
| 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); |  | ||||||
| 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..2] ++ [entrancesProbVals[3..]]); |  | ||||||
| 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..2] ++ [passagesProbVals[3..]]); |  | ||||||
| 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..2] ++ [exitsProbVals[3..]]); |  | ||||||
| 
 |  | ||||||
| 	if(orders == nil, { |  | ||||||
| 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); |  | ||||||
| 		addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); |  | ||||||
| 	}); |  | ||||||
| 	seq = seedFunc.value(genMotif, motifSeed).value; |  | ||||||
| 
 |  | ||||||
| 	//musPath = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; |  | ||||||
| 	writeResources.value(path); |  | ||||||
| 
 |  | ||||||
| 	//orders = nil; |  | ||||||
| 	//addr.sendMsg("/current_uid", curUID); |  | ||||||
| 	//addr.sendMsg("/ledger", prettifyArray.value(ledger, 1).replace("\"", "")); |  | ||||||
| 	//addr.sendMsg("/ledger_size", ledger.size); |  | ||||||
| 	//addr.sendMsg("/mus_seq", prettifyArray.value(seq, 3)); |  | ||||||
| 	addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); |  | ||||||
| }, \generate); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| OSCdef(\commit, {arg msg, time, addr, port; |  | ||||||
| 	var newLedger, modelPath, musString, musFile, test1, test2; |  | ||||||
| 	msg.postln; |  | ||||||
| 
 |  | ||||||
| 	/* |  | ||||||
| 	test1 = msg[1].asString.parseJSON; |  | ||||||
| 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; |  | ||||||
| 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; |  | ||||||
| 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; |  | ||||||
| 	(test1["music"] == test2["music_data"]).postln; |  | ||||||
| 	*/ |  | ||||||
| 
 |  | ||||||
| 	curUID = genUID.value; |  | ||||||
| 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); |  | ||||||
| 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); |  | ||||||
| 
 |  | ||||||
| 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; |  | ||||||
| 	writeResources.value(modelPath); |  | ||||||
| 
 |  | ||||||
| 	File.delete(ledgerPath.postln ++ "_bak"); |  | ||||||
| 	File.copy(ledgerPath, ledgerPath ++ "_bak"); |  | ||||||
| 	File.delete(ledgerPath); |  | ||||||
| 	newLedger = File(ledgerPath.postln, "w"); |  | ||||||
| 	ledger = ledger.postln.drop(-1).add(curUID); |  | ||||||
| 	newLedger.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); |  | ||||||
| 	newLedger.close; |  | ||||||
| 
 |  | ||||||
| 	addr.sendMsg("/committed", curUID, ledgerPath); |  | ||||||
| 	//refUID = curUID; |  | ||||||
| }, \commit); |  | ||||||
| 
 |  | ||||||
| OSCdef(\transport, {arg msg, time, addr, port; |  | ||||||
| 	msg.postln; |  | ||||||
| 	if(msg[1] == 0, { |  | ||||||
| 		player.stop; |  | ||||||
| 		group.set(\gate, 0); |  | ||||||
| 	}, { |  | ||||||
| 		// the cued sequence can now be read from file, so this can be cleaned up |  | ||||||
| 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; |  | ||||||
| 		pSeq = []; |  | ||||||
| 		cuedSeek = (seq != nil); |  | ||||||
| 		indexStart = msg[2].asInteger; |  | ||||||
| 		indexEnd = ledger.size - if(cuedSeek, {2}, {1}); |  | ||||||
| 		if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { |  | ||||||
| 			ledger[indexStart..indexEnd].do({arg uid, index; |  | ||||||
| 				var file; |  | ||||||
| 				(indexStart + index).postln; |  | ||||||
| 				file = File((dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_music" ++ ".json").standardizePath, "r"); |  | ||||||
| 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), indexStart + index, uid]); |  | ||||||
| 				file.close; |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 		if(cuedSeek, {pSeq = pSeq.add([seq, ledger.size - 1])}); |  | ||||||
| 		patterns = genPatterns.value(pSeq, addr); |  | ||||||
| 		player = Pfset(pattern: patterns, cleanupFunc: { |  | ||||||
| 			addr.sendMsg("/transport", 0); |  | ||||||
| 		}); |  | ||||||
| 		player = player.play |  | ||||||
| 	}); |  | ||||||
| }, \transport); |  | ||||||
| 
 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	freq = WhiteNoise.ar * 3 + freq; |  | ||||||
| 	freqFinal = Duty.ar((1/freq), 0, freq); |  | ||||||
| 	trig = Changed.ar(freqFinal); |  | ||||||
| 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); |  | ||||||
| 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); |  | ||||||
| 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 
 |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| "{\"a\": 1}".parseYAML["a"].asInteger; |  | ||||||
| "{\"a\": 1}".parseJSON["a"].isNumber; |  | ||||||
| 
 |  | ||||||
| 1223423434123.asHexString.toLower |  | ||||||
| 
 |  | ||||||
| Date.getDate.rawSeconds |  | ||||||
| Date.seed.asHexString.toLower |  | ||||||
| 
 |  | ||||||
| n = NetAddr("localhost", 8080); |  | ||||||
| n.sendMsg("/GET/#", (NetAddr.localAddr.hostname ++ ":" ++ NetAddr.localAddr.port), "/passage_probs_vals"); |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,85 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.75 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 0, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ 1, 0, 0, -1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, -1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 1.625 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 1.75 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.875 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.625 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.125 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.625 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.5 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.125 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, -1 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.375 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.875 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.375 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 2 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, -1, -1, 0 ], [ "Rest" ], [ 1, 0, 0, -1, 0, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "4c01589b", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 720097, |  | ||||||
| "dur_seed": 979064, |  | ||||||
| "motifs_seed": 718021, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 2 ], [ 1, 3, 0, 1, 1, 3, 0, 0, 3, 0, 0, 3 ], [  ] ], |  | ||||||
|   [ [ 1, 0, 3 ], [ 2, 2, 2, 2, 2, 2, 2, 2 ], [  ] ], |  | ||||||
|   [ [ 3, 2, 0 ], [ 1, 1, 1, 1 ], [  ] ], |  | ||||||
|   [ [ 0 ], [ 2 ], [ 3, 1 ] ], |  | ||||||
|   [ [ 0, 2, 3 ], [ 1, 1, 1, 1, 1, 1 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ] |  | ||||||
| } |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,84 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 9.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 6.5 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, -1, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, -1 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 1, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 0, 0, 0, 0, 0 ] ], 3.875 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ -1, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ -1, 0, 0, 0, 0, 1 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, -1, 0, 0, 0, 0 ] ], 10.125 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, -1, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 2 ], |  | ||||||
|     [ [ [ "Rest" ], [ 2, 0, 0, -1, 0, -1 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ 3, -1, 0, -1, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ "Rest" ], [ 2, -1, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ 3, -1, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ 3, 0, 0, 0, 0, -2 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 2, -1, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, 1, 0, -1 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], 5.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, 1, 0, -1 ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.625 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 2, -1, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 3, -1, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 3, 0, 0, 0, 0, -2 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 2, -1, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 1, 0, -1 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, -1, 0, 0, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "5397abab", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 748077, |  | ||||||
| "dur_seed": 361555, |  | ||||||
| "motifs_seed": 705478, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 3, 1 ], [ 2, 2, 2, 2, 2, 2, 2, 2, 2 ], [  ] ], |  | ||||||
|   [ [ 0 ], [ 3, 3, 3, 3 ], [ 2, 1 ] ], |  | ||||||
|   [ [ 1, 0 ], [ 3, 3 ], [ 2 ] ], |  | ||||||
|   [ [ 3, 2 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], [ 0 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,71 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 8.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 8.5 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, -1 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 3.625 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 2, -1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ] ], 5.75 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.125 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], |  | ||||||
|   [ [ 0, 1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], |  | ||||||
|   [ [ 1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], |  | ||||||
|   [ [ 2, -1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "54479f3d", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 331604, |  | ||||||
| "dur_seed": 153666, |  | ||||||
| "motifs_seed": 607664, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 3, 0 ], [ 2, 2, 2, 2, 2, 2, 2, 2, 2 ], [ 1 ] ], |  | ||||||
|   [ [ 0, 1, 2 ], [ 3, 3, 3, 3, 3, 3, 3 ], [  ] ], |  | ||||||
|   [ [ 2, 1 ], [ 0, 0, 0 ], [ 3 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,70 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ] ], 8.875 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.125 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 10.375 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, -1, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 1, 0, 0, -1 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 7.125 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.125 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 11.75 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, -1, 0 ] ], |  | ||||||
|   [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 1, 0, 0, -1 ] ], |  | ||||||
|   [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "57fa6a01", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 177943, |  | ||||||
| "dur_seed": 161612, |  | ||||||
| "motifs_seed": 484011, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 1, 2 ], [ 0, 3, 3 ], [  ] ], |  | ||||||
|   [ [ 2 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1 ], [ 3, 0 ] ], |  | ||||||
|   [ [ 0, 2, 1 ], [ 3, 3, 3, 3 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,93 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 4.125 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, -1, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.125 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ -1, 1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 9.625 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ] ], 0.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, -1, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 4.25 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, -1, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, -1, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ -1, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ -1, 1, 0, -1, 0, 1 ] ], 4.875 ], |  | ||||||
|     [ [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.75 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, -1, 0 ] ], |  | ||||||
|   [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], |  | ||||||
|   [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], |  | ||||||
|   [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, -1, 0, 1 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "5cd72e22", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 552033, |  | ||||||
| "dur_seed": 766851, |  | ||||||
| "motifs_seed": 945873, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 2, 3, 1 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [  ] ], |  | ||||||
|   [ [ 1 ], [ 3, 0, 2, 2, 3, 3 ], [  ] ], |  | ||||||
|   [ [ 3, 2, 1 ], [ 0, 0, 0, 0 ], [  ] ], |  | ||||||
|   [ [ 1 ], [ 3, 2, 3, 3, 2, 2, 2, 2, 2, 2 ], [ 0 ] ], |  | ||||||
|   [ [ 0, 1 ], [ 3, 3, 3 ], [ 2 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,99 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.875 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.625 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 1.5 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 1, 0, 0 ] ], 1 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 1 ] ], 0.875 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ] ], 0.75 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.875 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 1, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1.5 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 1.25 ], |  | ||||||
|     [ [ [ -2, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 1.375 ], |  | ||||||
|     [ [ [ -2, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 0.75 ], |  | ||||||
|     [ [ [ -2, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ] ], 0.625 ], |  | ||||||
|     [ [ [ -2, 0, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ "Rest" ] ], 0.75 ], |  | ||||||
|     [ [ [ -2, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 1, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ "Rest" ] ], 1.125 ], |  | ||||||
|     [ [ [ -1, 0, -1, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ "Rest" ] ], 1.25 ], |  | ||||||
|     [ [ [ -2, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ "Rest" ] ], 1 ], |  | ||||||
|     [ [ [ -1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ "Rest" ] ], 0.875 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ -1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, -1, 0, -1, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ -1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, -1, 0, -1, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ -2, 0, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, -1, 0, -1, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ -2, 0, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 1 ] ], 1.25 ], |  | ||||||
|     [ [ [ -2, 0, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 1.375 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 1.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, -1, -1 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, -1, -1 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 1 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, -1, -1 ], [ 1, 0, 0, -1, -1, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, -1, -1 ], [ 0, -1, 0, 1, -1, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 1 ], |  | ||||||
|     [ [ [ 0, -1, 0, 0, -1, 0 ], [ 0, -1, 0, 1, -1, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ 0, -1, 0, 0, -1, 0 ], [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ -1, -1, 0, 1, -1, 0 ], [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 1.125 ], |  | ||||||
|     [ [ [ -1, -1, 0, 1, -1, 0 ], [ 1, -1, -1, 0, -1, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 1 ], |  | ||||||
|     [ [ [ -1, 0, 0, 0, -1, 0 ], [ 1, -1, -1, 0, -1, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ -1, -1, 0, 0, 0, 0 ], [ 1, -1, -1, 0, -1, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ -1, -1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 0.75 ], |  | ||||||
|     [ [ [ -1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 1.375 ], |  | ||||||
|     [ [ [ 0, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ 0, -2, 0, 0, -1, 0 ], [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 3.375 ], |  | ||||||
|     [ [ [ 0, -2, 0, 0, -1, 0 ], [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ "Rest" ] ], 1.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ "Rest" ] ], 1.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 1 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 1 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 1, 1, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 2, 1, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 1, 1, 0, -1, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "600e3005", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 588436, |  | ||||||
| "dur_seed": 661239, |  | ||||||
| "motifs_seed": 733875, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 2, 1 ], [ 0, 0 ], [ 3 ] ], |  | ||||||
|   [ [ 0 ], [ 1, 1 ], [ 3, 2 ] ], |  | ||||||
|   [ [ 2 ], [ 3, 3, 3, 3, 3, 3, 3, 3 ], [ 0, 1 ] ], |  | ||||||
|   [ [ 3, 0, 1 ], [ 2, 2, 2, 2 ], [  ] ], |  | ||||||
|   [ [ 1 ], [ 2, 3, 0, 3, 0 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "true", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,716 +0,0 @@ | |||||||
| ( |  | ||||||
| // helper funcs |  | ||||||
| var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; |  | ||||||
| 
 |  | ||||||
| // score funcs |  | ||||||
| var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; |  | ||||||
| 
 |  | ||||||
| // subroutines |  | ||||||
| var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; |  | ||||||
| 
 |  | ||||||
| // primary routines |  | ||||||
| var genMotif, genSecondarySeq; |  | ||||||
| 
 |  | ||||||
| // audition funcs |  | ||||||
| var genPatterns, genMidiPatterns; |  | ||||||
| 
 |  | ||||||
| // resource management funcs |  | ||||||
| var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, |  | ||||||
| msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON; |  | ||||||
| 
 |  | ||||||
| // model vars |  | ||||||
| //(model and global vars mostly set by OSC funcs |  | ||||||
| var curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| ranges, orders, susWeights, passagesWeights, passagesSize, orderSize; |  | ||||||
| 
 |  | ||||||
| // model aux vars |  | ||||||
| var entrancesDurFunc, passagesDurFunc, exitsDurFunc; |  | ||||||
| 
 |  | ||||||
| // other global vars |  | ||||||
| var lastXChanges, popSize, exPath, dir, primes, dims, tuples, |  | ||||||
| seq, group, player, ledgerPath, ledger, currentlyPlayingUID; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // install JSON quark |  | ||||||
| if(Quarks.isInstalled("JSONlib").not, { |  | ||||||
| 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); |  | ||||||
| 	thisProcess.recompile; |  | ||||||
| 	//HelpBrowser.openHelpFor("Classes/JSONlib"); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------helper funcs |  | ||||||
| 
 |  | ||||||
| hsArrayToCents = { |  | ||||||
| 	arg hsArray; |  | ||||||
| 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| pDist = { |  | ||||||
| 	arg array1, array2, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); |  | ||||||
| 	if(signed, {pDistance}, {abs(pDistance)}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hdSum = { |  | ||||||
| 	arg hsArrays; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays.size; |  | ||||||
| 	distances = (size - 1).collect({arg i; |  | ||||||
| 		((i + 1)..(size - 1)).collect({arg j; |  | ||||||
| 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsChordalDistance = { |  | ||||||
| 	arg hsArrays1, hsArrays2; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays1.size; |  | ||||||
| 	distances = hsArrays1.size.collect({arg i; |  | ||||||
| 		hsArrays2.size.collect({arg j; |  | ||||||
| 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsArrayToFreq = { |  | ||||||
| 	arg array; |  | ||||||
| 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| //------score funcs |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| isInRange = { |  | ||||||
| 	arg hsArray, min, max; |  | ||||||
| 	var cents; |  | ||||||
| 	cents = hsArrayToCents.value(hsArray); |  | ||||||
| 	(cents >= min) && (cents <= max) |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| spacingScore = { |  | ||||||
| 	arg hsArrays, min; |  | ||||||
| 	var centsArray; |  | ||||||
| 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); |  | ||||||
| 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| rangeScore = { |  | ||||||
| 	arg hsArray1, hsArray2, min, max, low, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| intervalScore = { |  | ||||||
| 	arg hsArray1, hsArray2, mean, sd, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	pDistance.gaussCurve(1, mean, sd) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| inclusionScore = { |  | ||||||
| 	arg array, test, min = 0.01; |  | ||||||
| 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------subroutines |  | ||||||
| 
 |  | ||||||
| genTuples = { |  | ||||||
| 	var tuples; |  | ||||||
| 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); |  | ||||||
| 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| initVoices = { |  | ||||||
| 	var init, voicesInit; |  | ||||||
| 	voicesInit = popSize.collect({dims.collect({0})}); |  | ||||||
| 	/* |  | ||||||
| 	voicesInit = [dims.collect({0})]; |  | ||||||
| 	(popSize - 1).do({ |  | ||||||
| 		arg rep, new; |  | ||||||
| 		rep = dims.rand; |  | ||||||
| 		new = voicesInit.last.deepCopy; |  | ||||||
| 		new[rep] = new[rep] + [-1, 1].choose(); |  | ||||||
| 		voicesInit = voicesInit.add(new); |  | ||||||
| 	}); |  | ||||||
| 	*/ |  | ||||||
| 	voicesInit.deepCopy; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genDurFunc = {arg chordProb, min, max, envData; |  | ||||||
| 	var env, pTable, durFunc; |  | ||||||
| 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; |  | ||||||
| 	pTable = env.asRandomTable; |  | ||||||
| 	durFunc = {arg allowChord; |  | ||||||
| 		var res; |  | ||||||
| 		res = if(allowChord.not, { |  | ||||||
| 			pTable.tableRand * (max - min) + min |  | ||||||
| 		}, { |  | ||||||
| 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (max - min) + min}); |  | ||||||
| 		}).round(0.125); |  | ||||||
| 		if(res.asInteger == res, {res = res.asInteger}); |  | ||||||
| 		res |  | ||||||
| 	}; |  | ||||||
| 	seedFunc.value(durFunc, durSeed); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; |  | ||||||
| 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ |  | ||||||
| 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; |  | ||||||
| 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); |  | ||||||
| 		noProgIns = (popSize - noSusIns).rand + 1; |  | ||||||
| 		noSilentIns = popSize - noSusIns - noProgIns; |  | ||||||
| 
 |  | ||||||
| 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); |  | ||||||
| 
 |  | ||||||
| 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); |  | ||||||
| 		if(silent == nil, {silent = []}); |  | ||||||
| 		[sus.scramble, prog, silent.scramble] |  | ||||||
| 	}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| updateVoices = {arg ins, sus; |  | ||||||
| 	var voices, candidates, nWeights, nProbs, sel; |  | ||||||
| 
 |  | ||||||
| 	voices = lastXChanges.deepCopy.last; |  | ||||||
| 
 |  | ||||||
| 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; |  | ||||||
| 	candidates = difference(candidates.asSet, voices.asSet).asList; |  | ||||||
| 	nProbs = candidates.collect({arg candidate; |  | ||||||
| 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; |  | ||||||
| 
 |  | ||||||
| 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); |  | ||||||
| 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); |  | ||||||
| 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); |  | ||||||
| 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); |  | ||||||
| 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); |  | ||||||
| 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); |  | ||||||
| 		//maybe what you want here is a vector to another root and then favoring movement towards it. |  | ||||||
| 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); |  | ||||||
| 
 |  | ||||||
| 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	nWeights = passagesWeights; |  | ||||||
| 
 |  | ||||||
| 	//this handles nWeights of 0; mainly for testing |  | ||||||
| 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; |  | ||||||
| 	nWeights = nWeights.select({arg weight; weight != 0}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; |  | ||||||
| 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) |  | ||||||
| 	}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; |  | ||||||
| 
 |  | ||||||
| 	sel = candidates.wchoose(nProbs); |  | ||||||
| 
 |  | ||||||
| 	voices[ins] = sel; |  | ||||||
| 	lastXChanges = lastXChanges.add(voices).keep(-5); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSubMotif = {arg order, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; |  | ||||||
| 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, lastXChangesHold, voices, adder; |  | ||||||
| 	# sus, prog, silent = order; |  | ||||||
| 	flatOrder = silent ++ sus ++ prog; |  | ||||||
| 	lastXChangesHold = lastXChanges.deepCopy; |  | ||||||
| 	voices = lastState.deepCopy; |  | ||||||
| 	isInChord = popSize.collect({false}); |  | ||||||
| 	allowChord = false; |  | ||||||
| 	res = []; |  | ||||||
| 	"------generating motif".postln; |  | ||||||
| 	//need to figure out here if voices move between motifs |  | ||||||
| 	flatOrder.do({arg ins, i; |  | ||||||
| 
 |  | ||||||
| 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); |  | ||||||
| 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); |  | ||||||
| 
 |  | ||||||
| 		if(voices[ins] != adder, { |  | ||||||
| 			var dur; |  | ||||||
| 			allowChord = if((sus ++ silent).includes(ins), { |  | ||||||
| 				(sus ++ silent).includes(ins) && (ins != sus.last); |  | ||||||
| 			}, { |  | ||||||
| 				if(i < (flatOrder.size - 1), {(isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not}, {false}); |  | ||||||
| 			}); |  | ||||||
| 			dur = passagesDurFunc.value(allowChord); |  | ||||||
| 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); |  | ||||||
| 
 |  | ||||||
| 			voices[ins] = adder; |  | ||||||
| 			res = res.add([voices.deepCopy.postln, dur]); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	// pad ending |  | ||||||
| 	if(isLastOrder, { |  | ||||||
| 		(0..(popSize-1)).scramble.do({arg ins; |  | ||||||
| 			if(res.last.first[ins] != ["Rest"], { |  | ||||||
| 				var dur; |  | ||||||
| 				voices[ins] = ["Rest"]; |  | ||||||
| 				allowChord = (voices != popSize.collect({["Rest"]})); |  | ||||||
| 				dur = passagesDurFunc.value(allowChord); |  | ||||||
| 				res = res.add([voices.deepCopy.postln, dur]); |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	//format and return |  | ||||||
| 	if(startFromLast, {lastXChanges = lastXChangesHold}); |  | ||||||
| 	res; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------primary routines |  | ||||||
| 
 |  | ||||||
| genMotif = { |  | ||||||
| 	var repeats, fSeq; |  | ||||||
| 
 |  | ||||||
| 	repeats = 1; |  | ||||||
| 	fSeq = []; |  | ||||||
| 
 |  | ||||||
| 	repeats.do({arg index; |  | ||||||
| 		var motif; |  | ||||||
| 
 |  | ||||||
| 		motif = []; |  | ||||||
| 
 |  | ||||||
| 		orders.do({arg order, o; |  | ||||||
| 			var lastState, subMotif; |  | ||||||
| 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); |  | ||||||
| 			subMotif = genSubMotif.value(order, lastState, isLastOrder: o == (orders.size - 1)); |  | ||||||
| 			motif = motif.add(subMotif); |  | ||||||
| 
 |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		sanityCheck.value(motif, index); |  | ||||||
| 
 |  | ||||||
| 		fSeq = fSeq.add(motif); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSecondarySeq = {arg seq; |  | ||||||
| 	var curdles, fSeq; |  | ||||||
| 	curdles = []; |  | ||||||
| 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); |  | ||||||
| 
 |  | ||||||
| 	fSeq = seq.clumps(curdles).collect({arg clump, m; |  | ||||||
| 		var repeats, paddedSeq; |  | ||||||
| 
 |  | ||||||
| 		//add rest |  | ||||||
| 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); |  | ||||||
| 
 |  | ||||||
| 		//implement repeats |  | ||||||
| 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); |  | ||||||
| 		repeats.collect({paddedSeq}); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------audition funcs |  | ||||||
| 
 |  | ||||||
| Event.addEventType(\osc, { |  | ||||||
| 	if (~addr.postln.notNil) { |  | ||||||
| 		~addr.sendMsg(~indexPath, ~indexMsg); |  | ||||||
| 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); |  | ||||||
| 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); |  | ||||||
| 	}; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| genPatterns = {arg inSeq, addr; |  | ||||||
| 	var voices, durs, patterns, res, indices, sectionDurs, ids, seq; |  | ||||||
| 	seq = inSeq.collect({arg mSeq; mSeq[0]}); |  | ||||||
| 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	indices = inSeq.collect({arg mSeq, m; mSeq[1]}); |  | ||||||
| 	ids = inSeq.collect({arg mSeq, m; mSeq[2]}); |  | ||||||
| 	sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\instrument, \test, |  | ||||||
| 				\group, group, |  | ||||||
| 				\freq, Pseq(freqs, 1), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\sustain, Pseq(fDurs, 1) |  | ||||||
| 			) |  | ||||||
| 		}) ++ |  | ||||||
| 		[ |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \osc, |  | ||||||
| 				\addr, addr, |  | ||||||
| 				\indexPath, "/cur_play_index", |  | ||||||
| 				\indexMsg, Pseq(indices.postln, 1), |  | ||||||
| 				\seqPath, "/mus_seq", |  | ||||||
| 				\seqMsg, Pseq(seq, 1), |  | ||||||
| 				\dur, Pseq(sectionDurs, 1) |  | ||||||
| 			); |  | ||||||
| 		] |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| genMidiPatterns = {arg seq; |  | ||||||
| 	var voices, durs, patterns, res, mOut, pbRange; |  | ||||||
| 	pbRange = 1; //semitones - change this as needed for your situation |  | ||||||
| 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); |  | ||||||
| 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice, v; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 
 |  | ||||||
| 			mOut.program(v, 70); |  | ||||||
| 
 |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \midi, |  | ||||||
| 				\chan, v, |  | ||||||
| 				\noteval, Pseq(freqs.cpsmidi - 24, 1), |  | ||||||
| 				\note, Pfunc({ | event | event[\noteval].floor }), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\midiout, mOut, |  | ||||||
| 				\amp, 1, |  | ||||||
| 				\bend, Pfunc({ |  | ||||||
| 					| event | |  | ||||||
| 					if (event[\note].isRest.not) { |  | ||||||
| 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; |  | ||||||
| 						m.bend(v, pitchbendvalue); |  | ||||||
| 					}; |  | ||||||
| 					0; // return something other than nil to avoid stopping the pattern |  | ||||||
| 				}), |  | ||||||
| 			); |  | ||||||
| 		}); |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------resource management funcs |  | ||||||
| 
 |  | ||||||
| genUID = {Date.seed.asHexString.toLower}; |  | ||||||
| 
 |  | ||||||
| seedFunc = {arg func, seed; |  | ||||||
| 	var funcArgs, next; |  | ||||||
| 	next = Routine({loop{func.valueArray(funcArgs).yield }}); |  | ||||||
| 	next.randSeed_(seed); |  | ||||||
| 	{arg ...args; funcArgs = args; next.value} |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| stringifyToDepth = {arg data, maxDepth = 1; |  | ||||||
| 	var prettyString = "", rCount = 0, writeArray, indent; |  | ||||||
| 
 |  | ||||||
| 	if(maxDepth == 0, { |  | ||||||
| 		data.asCompileString |  | ||||||
| 	}, { |  | ||||||
| 		indent = {arg size; size.collect({" "}).join("")}; |  | ||||||
| 		writeArray = {arg array; |  | ||||||
| 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; |  | ||||||
| 			rCount = rCount + 1; |  | ||||||
| 			if(rCount < maxDepth, { |  | ||||||
| 				array.do({arg subArray; writeArray.value(subArray)}); |  | ||||||
| 			}, { |  | ||||||
| 				prettyString = prettyString ++ array.collect({arg subArray; |  | ||||||
| 					indent.value(rCount + 1) ++ subArray.asCompileString |  | ||||||
| 				}).join(",\n"); |  | ||||||
| 			}); |  | ||||||
| 			rCount = rCount - 1; |  | ||||||
| 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		writeArray.value(data); |  | ||||||
| 		prettyString.replace(",\n\n", "\n").drop(-2); |  | ||||||
| 	}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| sanityCheck = {arg motif, index; |  | ||||||
| 	//print functions = very helpful |  | ||||||
| 	("----------" + index + "------------").postln; |  | ||||||
| 
 |  | ||||||
| 	motif.flatten.do({arg val, v; |  | ||||||
| 		if(v > 0, { |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); |  | ||||||
| 		}); |  | ||||||
| 		val.postln |  | ||||||
| 	}); |  | ||||||
| 	"***********".postln; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; |  | ||||||
| 	var res; |  | ||||||
| 
 |  | ||||||
| 	res = in; |  | ||||||
| 	if(res.isNil.not, { |  | ||||||
| 		if((res.isArray && res.isString.not), { |  | ||||||
| 			res = res.asCompileString; |  | ||||||
| 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); |  | ||||||
| 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); |  | ||||||
| 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); |  | ||||||
| 			res = res.replace("Rest", "\"Rest\""); |  | ||||||
| 			res = res.interpret; |  | ||||||
| 		}, { |  | ||||||
| 			//res.postln; |  | ||||||
| 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| writeResources = {arg path; |  | ||||||
| 	var file, nameSpaces, modelItems, resString; |  | ||||||
| 	file = File(path,"w"); |  | ||||||
| 
 |  | ||||||
| 	nameSpaces = [ |  | ||||||
| 		"music_data", "last_changes", |  | ||||||
| 		"cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", |  | ||||||
| 		"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", |  | ||||||
| 		"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size" |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	modelItems = [ |  | ||||||
| 		seq, lastXChanges, |  | ||||||
| 		curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| 		entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	resString = [nameSpaces, modelItems].flop.collect({arg item; |  | ||||||
| 		var nameSpace, modelItem, depth = 0, insert = " "; |  | ||||||
| 		# nameSpace, modelItem = item; |  | ||||||
| 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); |  | ||||||
| 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); |  | ||||||
| 		if(nameSpace == "order", {depth = 1; insert = "\n"}); |  | ||||||
| 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(modelItem.postln, depth).postln |  | ||||||
| 	}).join(",\n"); |  | ||||||
| 
 |  | ||||||
| 	resString = "{\n" ++ resString ++ "\n}"; |  | ||||||
| 
 |  | ||||||
| 	file.write(resString); |  | ||||||
| 	file.close; |  | ||||||
| 	resString |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; |  | ||||||
| 
 |  | ||||||
| loadModelJSON = {arg jsonObject; |  | ||||||
| 	var nameSpaces, data; |  | ||||||
| 
 |  | ||||||
| 	//model = File(path, "r").readAllString.parseJSON; |  | ||||||
| 
 |  | ||||||
| 	nameSpaces = [ |  | ||||||
| 		"cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", |  | ||||||
| 		"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", |  | ||||||
| 		"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size" |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	data = nameSpaces.collect({arg nS; msgInterpret.value(jsonObject[nS]).postln}); |  | ||||||
| 
 |  | ||||||
| 	data.postln; |  | ||||||
| 
 |  | ||||||
| 	# curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| 	entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize = data; |  | ||||||
| 
 |  | ||||||
| 	popSize = ranges.size; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadLedgerFile = {arg path; |  | ||||||
| 	ledgerPath = path; |  | ||||||
| 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; |  | ||||||
| 
 |  | ||||||
| //------global vars |  | ||||||
| 
 |  | ||||||
| primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; |  | ||||||
| //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; |  | ||||||
| exPath = thisProcess.nowExecutingPath; |  | ||||||
| dir = exPath.dirname; |  | ||||||
| //popSize = 4; |  | ||||||
| dims = primes.size; |  | ||||||
| tuples = genTuples.value(); |  | ||||||
| //refUID = nil; |  | ||||||
| group = Group.new; |  | ||||||
| loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); |  | ||||||
| //passagesWeights = [1, 1, 1, 1, 1]; |  | ||||||
| //susWeights = [1, 1, 1]; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------OSC funcs |  | ||||||
| 
 |  | ||||||
| OSCdef(\load_ledger, {arg msg, time, addr, port; |  | ||||||
| 	loadLedgerFile.value(msg[1].asString); |  | ||||||
| }, \load_ledger); |  | ||||||
| 
 |  | ||||||
| OSCdef(\load_model, {arg msg, time, addr, port; |  | ||||||
| 	loadModelFile.value(msg[1].asString); |  | ||||||
| }, \load_model); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| OSCdef(\generate, {arg msg, time, addr, port; |  | ||||||
| 	var path, dFormat, condition, musPath, modelString; |  | ||||||
| 	msg.postln; |  | ||||||
| 
 |  | ||||||
| 	path = msg[1].asString; |  | ||||||
| 
 |  | ||||||
| 	loadModelFile.value(path); |  | ||||||
| 
 |  | ||||||
| 	refUID.postln; |  | ||||||
| 
 |  | ||||||
| 	loadLedgerFile.value(ledgerPath); |  | ||||||
| 	if(ledger == nil, {ledger = ["tmp"]}); |  | ||||||
| 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); |  | ||||||
| 
 |  | ||||||
| 	lastXChanges = if(refUID == nil, { |  | ||||||
| 		[initVoices.value().deepCopy]; |  | ||||||
| 	}, { |  | ||||||
| 		var file; |  | ||||||
| 		refUID.postln; |  | ||||||
| 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); |  | ||||||
| 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..2] ++ [entrancesProbVals[3..]]); |  | ||||||
| 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..2] ++ [passagesProbVals[3..]]); |  | ||||||
| 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..2] ++ [exitsProbVals[3..]]); |  | ||||||
| 
 |  | ||||||
| 	if(orders == nil, { |  | ||||||
| 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); |  | ||||||
| 		//addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); |  | ||||||
| 	}); |  | ||||||
| 	seq = seedFunc.value(genMotif, motifSeed).value; |  | ||||||
| 
 |  | ||||||
| 	modelString = writeResources.value(path); |  | ||||||
| 
 |  | ||||||
| 	//addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); |  | ||||||
| 	addr.sendMsg("/generated", path, modelString); |  | ||||||
| }, \generate); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| OSCdef(\commit, {arg msg, time, addr, port; |  | ||||||
| 	var newLedger, modelPath, musString, musFile, test1, test2; |  | ||||||
| 	msg.postln; |  | ||||||
| 
 |  | ||||||
| 	/* |  | ||||||
| 	test1 = msg[1].asString.parseJSON; |  | ||||||
| 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; |  | ||||||
| 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; |  | ||||||
| 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; |  | ||||||
| 	(test1["music"] == test2["music_data"]).postln; |  | ||||||
| 	*/ |  | ||||||
| 
 |  | ||||||
| 	curUID = genUID.value; |  | ||||||
| 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); |  | ||||||
| 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); |  | ||||||
| 
 |  | ||||||
| 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; |  | ||||||
| 	writeResources.value(modelPath); |  | ||||||
| 
 |  | ||||||
| 	File.delete(ledgerPath.postln ++ "_bak"); |  | ||||||
| 	File.copy(ledgerPath, ledgerPath ++ "_bak"); |  | ||||||
| 	File.delete(ledgerPath); |  | ||||||
| 	newLedger = File(ledgerPath.postln, "w"); |  | ||||||
| 	ledger = ledger.postln.drop(-1).add(curUID); |  | ||||||
| 	newLedger.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); |  | ||||||
| 	newLedger.close; |  | ||||||
| 
 |  | ||||||
| 	addr.sendMsg("/committed", curUID, ledgerPath); |  | ||||||
| 	//refUID = curUID; |  | ||||||
| }, \commit); |  | ||||||
| 
 |  | ||||||
| OSCdef(\transport, {arg msg, time, addr, port; |  | ||||||
| 	msg.postln; |  | ||||||
| 	if(msg[1] == 0, { |  | ||||||
| 		player.stop; |  | ||||||
| 		group.set(\gate, 0); |  | ||||||
| 	}, { |  | ||||||
| 		// the cued sequence can now be read from file, so this can be cleaned up |  | ||||||
| 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; |  | ||||||
| 		pSeq = []; |  | ||||||
| 		cuedSeek = (seq != nil); |  | ||||||
| 		indexStart = msg[2].asInteger; |  | ||||||
| 		indexEnd = ledger.size - if(cuedSeek, {2}, {1}); |  | ||||||
| 		ledger.postln; |  | ||||||
| 		if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { |  | ||||||
| 			ledger[indexStart..indexEnd].do({arg uid, index; |  | ||||||
| 				var file; |  | ||||||
| 				(indexStart + index).postln; |  | ||||||
| 				file = File((dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath, "r"); |  | ||||||
| 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), indexStart + index, uid]); |  | ||||||
| 				file.close; |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 		if(cuedSeek, {pSeq = pSeq.add([seq, ledger.size - 1])}); |  | ||||||
| 		patterns = genPatterns.value(pSeq, addr); |  | ||||||
| 		player = Pfset(pattern: patterns, cleanupFunc: { |  | ||||||
| 			addr.sendMsg("/transport", 0); |  | ||||||
| 		}); |  | ||||||
| 		player = player.play |  | ||||||
| 	}); |  | ||||||
| }, \transport); |  | ||||||
| 
 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	freq = WhiteNoise.ar * 3 + freq; |  | ||||||
| 	freqFinal = Duty.ar((1/freq), 0, freq); |  | ||||||
| 	trig = Changed.ar(freqFinal); |  | ||||||
| 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); |  | ||||||
| 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); |  | ||||||
| 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 
 |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| "{\"a\": 1}".parseYAML["a"].asInteger; |  | ||||||
| "{\"a\": 1}".parseJSON["a"].isNumber; |  | ||||||
| 
 |  | ||||||
| 1223423434123.asHexString.toLower |  | ||||||
| 
 |  | ||||||
| Date.getDate.rawSeconds |  | ||||||
| Date.seed.asHexString.toLower |  | ||||||
| 
 |  | ||||||
| n = NetAddr("localhost", 8080); |  | ||||||
| n.sendMsg("/GET/#", (NetAddr.localAddr.hostname ++ ":" ++ NetAddr.localAddr.port), "/passage_probs_vals"); |  | ||||||
| @ -1,38 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, -1, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 3.125 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, -1, -1, 0 ], [ "Rest" ], [ 2, 0, 0, -2, -1, 0 ] ], 2.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, 0, -1, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 2.625 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, -2, -1, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "640eeed3", |  | ||||||
| "ref_uid": "4c01589b", |  | ||||||
| "order_seed": 155513, |  | ||||||
| "dur_seed": 460216, |  | ||||||
| "motifs_seed": 397643, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0, 1.87, 3.7996946564886, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 1 ], [ 3 ], [ 0, 2 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 1, 0, 0 ], |  | ||||||
| "order_size": [ 1, 3 ], |  | ||||||
| "passages_size": [ 0, 2 ] |  | ||||||
| } |  | ||||||
| @ -1,57 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 4.875 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.125 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, -1 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, -1 ] ], 1.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, -1 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 2, 0, 0, -1, 0, -1 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.875 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, -1 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, -1 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "674b56e3", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 675344, |  | ||||||
| "dur_seed": 446150, |  | ||||||
| "motifs_seed": 203468, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 3 ], [ 2, 1, 1, 2 ], [  ] ], |  | ||||||
|   [ [ 2, 0 ], [ 3, 1, 3, 3, 1 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,79 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 2 ], |  | ||||||
|     [ [ [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 2 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ] ], 1 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 2, 0, 1, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 1, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ] ], 0.125 ], |  | ||||||
|     [ [ [ 2, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ] ], 0.125 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ] ], 9 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 1, 0, 0, 0 ] ], 0.375 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 1, -1, 1, 0, 0, 0 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 2, 0, 0, 0 ], [ "Rest" ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 1, 0 ], [ "Rest" ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ -1, 1, 1, 0, 0, 0 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ "Rest" ] ], 0.125 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 1, -1, 0, 0 ], [ "Rest" ] ], 6.875 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 5.125 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 2, 0, 0, 0 ], [ 0, -1, 1, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 1, 0 ], [ 0, -1, 1, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, -1, 1, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, -1, 1, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ], [ 0, -1, 1, 0, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "688ee3e1", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 630785, |  | ||||||
| "dur_seed": 942253, |  | ||||||
| "motifs_seed": 142667, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 2, 1, 3 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [  ] ], |  | ||||||
|   [ [ 2, 0, 1 ], [ 3 ], [  ] ], |  | ||||||
|   [ [ 3, 2, 1 ], [ 0, 0, 0, 0, 0 ], [  ] ], |  | ||||||
|   [ [ 0, 1, 2 ], [ 3 ], [  ] ], |  | ||||||
|   [ [ 0 ], [ 2, 2, 2, 2, 2, 2 ], [ 3, 1 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,70 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 6.625 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 2, 0, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 2, 0, 0, -1, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 5.75 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 1, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 1, 0 ], [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ -1, 0, 0, 1, 0, 0 ], [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 1, 0, 0, 0 ], [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.375 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ -1, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 7.625 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 0, 0, 0, 1, 0 ], [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ -1, 0, 0, 1, 0, 0 ], [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 1, 0, 0, 0 ], [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "75638b4d", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 533343, |  | ||||||
| "dur_seed": 497898, |  | ||||||
| "motifs_seed": 245346, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 3, 2 ], [ 1, 0, 0, 0, 1, 0, 1, 0, 0 ], [  ] ], |  | ||||||
|   [ [ 2 ], [ 0, 3, 1, 3, 1, 1, 0, 0, 0 ], [  ] ], |  | ||||||
|   [ [ 3, 0, 2 ], [ 1 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,719 +0,0 @@ | |||||||
| ( |  | ||||||
| // helper funcs |  | ||||||
| var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; |  | ||||||
| 
 |  | ||||||
| // score funcs |  | ||||||
| var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; |  | ||||||
| 
 |  | ||||||
| // subroutines |  | ||||||
| var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; |  | ||||||
| 
 |  | ||||||
| // primary routines |  | ||||||
| var genMotif, genSecondarySeq; |  | ||||||
| 
 |  | ||||||
| // audition funcs |  | ||||||
| var genPatterns, genMidiPatterns; |  | ||||||
| 
 |  | ||||||
| // resource management funcs |  | ||||||
| var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, |  | ||||||
| msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON; |  | ||||||
| 
 |  | ||||||
| // model vars |  | ||||||
| //(model and global vars mostly set by OSC funcs |  | ||||||
| var curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| ranges, orders, susWeights, passagesWeights, passagesSize, orderSize; |  | ||||||
| 
 |  | ||||||
| // model aux vars |  | ||||||
| var entrancesDurFunc, passagesDurFunc, exitsDurFunc; |  | ||||||
| 
 |  | ||||||
| // other global vars |  | ||||||
| var lastXChanges, popSize, exPath, dir, primes, dims, tuples, |  | ||||||
| seq, group, player, ledgerPath, ledger, currentlyPlayingUID; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // install JSON quark |  | ||||||
| if(Quarks.isInstalled("JSONlib").not, { |  | ||||||
| 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); |  | ||||||
| 	thisProcess.recompile; |  | ||||||
| 	//HelpBrowser.openHelpFor("Classes/JSONlib"); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------helper funcs |  | ||||||
| 
 |  | ||||||
| hsArrayToCents = { |  | ||||||
| 	arg hsArray; |  | ||||||
| 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| pDist = { |  | ||||||
| 	arg array1, array2, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); |  | ||||||
| 	if(signed, {pDistance}, {abs(pDistance)}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hdSum = { |  | ||||||
| 	arg hsArrays; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays.size; |  | ||||||
| 	distances = (size - 1).collect({arg i; |  | ||||||
| 		((i + 1)..(size - 1)).collect({arg j; |  | ||||||
| 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsChordalDistance = { |  | ||||||
| 	arg hsArrays1, hsArrays2; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays1.size; |  | ||||||
| 	distances = hsArrays1.size.collect({arg i; |  | ||||||
| 		hsArrays2.size.collect({arg j; |  | ||||||
| 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsArrayToFreq = { |  | ||||||
| 	arg array; |  | ||||||
| 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| //------score funcs |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| isInRange = { |  | ||||||
| 	arg hsArray, min, max; |  | ||||||
| 	var cents; |  | ||||||
| 	cents = hsArrayToCents.value(hsArray); |  | ||||||
| 	(cents >= min) && (cents <= max) |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| spacingScore = { |  | ||||||
| 	arg hsArrays, min; |  | ||||||
| 	var centsArray; |  | ||||||
| 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); |  | ||||||
| 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| rangeScore = { |  | ||||||
| 	arg hsArray1, hsArray2, min, max, low, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| intervalScore = { |  | ||||||
| 	arg hsArray1, hsArray2, mean, sd, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	pDistance.gaussCurve(1, mean, sd) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| inclusionScore = { |  | ||||||
| 	arg array, test, min = 0.01; |  | ||||||
| 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------subroutines |  | ||||||
| 
 |  | ||||||
| genTuples = { |  | ||||||
| 	var tuples; |  | ||||||
| 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); |  | ||||||
| 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| initVoices = { |  | ||||||
| 	var init, voicesInit; |  | ||||||
| 	voicesInit = popSize.collect({dims.collect({0})}); |  | ||||||
| 	/* |  | ||||||
| 	voicesInit = [dims.collect({0})]; |  | ||||||
| 	(popSize - 1).do({ |  | ||||||
| 		arg rep, new; |  | ||||||
| 		rep = dims.rand; |  | ||||||
| 		new = voicesInit.last.deepCopy; |  | ||||||
| 		new[rep] = new[rep] + [-1, 1].choose(); |  | ||||||
| 		voicesInit = voicesInit.add(new); |  | ||||||
| 	}); |  | ||||||
| 	*/ |  | ||||||
| 	voicesInit.deepCopy; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genDurFunc = {arg chordProb, min, max, envData; |  | ||||||
| 	var env, pTable, durFunc; |  | ||||||
| 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; |  | ||||||
| 	pTable = env.asRandomTable; |  | ||||||
| 	durFunc = {arg allowChord; |  | ||||||
| 		var res; |  | ||||||
| 		res = if(allowChord.not, { |  | ||||||
| 			pTable.tableRand * (max - min) + min |  | ||||||
| 		}, { |  | ||||||
| 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (max - min) + min}); |  | ||||||
| 		}).round(0.125); |  | ||||||
| 		if(res.asInteger == res, {res = res.asInteger}); |  | ||||||
| 		res |  | ||||||
| 	}; |  | ||||||
| 	seedFunc.value(durFunc, durSeed); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; |  | ||||||
| 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ |  | ||||||
| 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; |  | ||||||
| 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); |  | ||||||
| 		noProgIns = (popSize - noSusIns).rand + 1; |  | ||||||
| 		noSilentIns = popSize - noSusIns - noProgIns; |  | ||||||
| 
 |  | ||||||
| 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); |  | ||||||
| 
 |  | ||||||
| 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); |  | ||||||
| 		if(silent == nil, {silent = []}); |  | ||||||
| 		[sus.scramble, prog, silent.scramble] |  | ||||||
| 	}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| updateVoices = {arg ins, sus; |  | ||||||
| 	var voices, candidates, nWeights, nProbs, sel; |  | ||||||
| 
 |  | ||||||
| 	voices = lastXChanges.deepCopy.last; |  | ||||||
| 
 |  | ||||||
| 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; |  | ||||||
| 	candidates = difference(candidates.asSet, voices.asSet).asList; |  | ||||||
| 	nProbs = candidates.collect({arg candidate; |  | ||||||
| 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; |  | ||||||
| 
 |  | ||||||
| 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); |  | ||||||
| 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); |  | ||||||
| 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); |  | ||||||
| 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); |  | ||||||
| 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); |  | ||||||
| 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); |  | ||||||
| 		//maybe what you want here is a vector to another root and then favoring movement towards it. |  | ||||||
| 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); |  | ||||||
| 
 |  | ||||||
| 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	nWeights = passagesWeights; |  | ||||||
| 
 |  | ||||||
| 	//this handles nWeights of 0; mainly for testing |  | ||||||
| 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; |  | ||||||
| 	nWeights = nWeights.select({arg weight; weight != 0}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; |  | ||||||
| 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) |  | ||||||
| 	}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; |  | ||||||
| 
 |  | ||||||
| 	sel = candidates.wchoose(nProbs); |  | ||||||
| 
 |  | ||||||
| 	voices[ins] = sel; |  | ||||||
| 	lastXChanges = lastXChanges.add(voices).keep(-5); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSubMotif = {arg order, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; |  | ||||||
| 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, lastXChangesHold, voices, adder; |  | ||||||
| 	# sus, prog, silent = order; |  | ||||||
| 	flatOrder = silent ++ sus ++ prog; |  | ||||||
| 	lastXChangesHold = lastXChanges.deepCopy; |  | ||||||
| 	voices = lastState.deepCopy; |  | ||||||
| 	isInChord = popSize.collect({false}); |  | ||||||
| 	allowChord = false; |  | ||||||
| 	res = []; |  | ||||||
| 	"------generating motif".postln; |  | ||||||
| 	//need to figure out here if voices move between motifs |  | ||||||
| 	flatOrder.do({arg ins, i; |  | ||||||
| 
 |  | ||||||
| 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); |  | ||||||
| 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); |  | ||||||
| 
 |  | ||||||
| 		if(voices[ins] != adder, { |  | ||||||
| 			var dur; |  | ||||||
| 			allowChord = if((sus ++ silent).includes(ins), { |  | ||||||
| 				(sus ++ silent).includes(ins) && (ins != sus.last); |  | ||||||
| 			}, { |  | ||||||
| 				if(i < (flatOrder.size - 1), {(isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not}, {false}); |  | ||||||
| 			}); |  | ||||||
| 			dur = passagesDurFunc.value(allowChord); |  | ||||||
| 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); |  | ||||||
| 
 |  | ||||||
| 			voices[ins] = adder; |  | ||||||
| 			res = res.add([voices.deepCopy.postln, dur]); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	// pad ending |  | ||||||
| 	if(isLastOrder, { |  | ||||||
| 		(0..(popSize-1)).scramble.do({arg ins; |  | ||||||
| 			if(res.last.first[ins] != ["Rest"], { |  | ||||||
| 				var dur; |  | ||||||
| 				voices[ins] = ["Rest"]; |  | ||||||
| 				allowChord = (voices != popSize.collect({["Rest"]})); |  | ||||||
| 				dur = passagesDurFunc.value(allowChord); |  | ||||||
| 				res = res.add([voices.deepCopy.postln, dur]); |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	//format and return |  | ||||||
| 	if(startFromLast, {lastXChanges = lastXChangesHold}); |  | ||||||
| 	res; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------primary routines |  | ||||||
| 
 |  | ||||||
| genMotif = { |  | ||||||
| 	var repeats, fSeq; |  | ||||||
| 
 |  | ||||||
| 	repeats = 1; |  | ||||||
| 	fSeq = []; |  | ||||||
| 
 |  | ||||||
| 	repeats.do({arg index; |  | ||||||
| 		var motif; |  | ||||||
| 
 |  | ||||||
| 		motif = []; |  | ||||||
| 
 |  | ||||||
| 		orders.do({arg order, o; |  | ||||||
| 			var lastState, subMotif; |  | ||||||
| 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); |  | ||||||
| 			subMotif = genSubMotif.value(order, lastState, isLastOrder: o == (orders.size - 1)); |  | ||||||
| 			motif = motif.add(subMotif); |  | ||||||
| 
 |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		sanityCheck.value(motif, index); |  | ||||||
| 
 |  | ||||||
| 		fSeq = fSeq.add(motif); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSecondarySeq = {arg seq; |  | ||||||
| 	var curdles, fSeq; |  | ||||||
| 	curdles = []; |  | ||||||
| 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); |  | ||||||
| 
 |  | ||||||
| 	fSeq = seq.clumps(curdles).collect({arg clump, m; |  | ||||||
| 		var repeats, paddedSeq; |  | ||||||
| 
 |  | ||||||
| 		//add rest |  | ||||||
| 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); |  | ||||||
| 
 |  | ||||||
| 		//implement repeats |  | ||||||
| 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); |  | ||||||
| 		repeats.collect({paddedSeq}); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------audition funcs |  | ||||||
| 
 |  | ||||||
| Event.addEventType(\osc, { |  | ||||||
| 	if (~addr.postln.notNil) { |  | ||||||
| 		~addr.sendMsg(~indexPath, ~indexMsg); |  | ||||||
| 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); |  | ||||||
| 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); |  | ||||||
| 	}; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| genPatterns = {arg inSeq, addr; |  | ||||||
| 	var voices, durs, patterns, res, indices, sectionDurs, ids, seq; |  | ||||||
| 	seq = inSeq.collect({arg mSeq; mSeq[0]}); |  | ||||||
| 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	indices = inSeq.collect({arg mSeq, m; mSeq[1]}); |  | ||||||
| 	ids = inSeq.collect({arg mSeq, m; mSeq[2]}); |  | ||||||
| 	sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\instrument, \test, |  | ||||||
| 				\group, group, |  | ||||||
| 				\freq, Pseq(freqs, 1), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\sustain, Pseq(fDurs, 1) |  | ||||||
| 			) |  | ||||||
| 		}) ++ |  | ||||||
| 		[ |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \osc, |  | ||||||
| 				\addr, addr, |  | ||||||
| 				\indexPath, "/cur_play_index", |  | ||||||
| 				\indexMsg, Pseq(indices.postln, 1), |  | ||||||
| 				\seqPath, "/mus_seq", |  | ||||||
| 				\seqMsg, Pseq(seq, 1), |  | ||||||
| 				\dur, Pseq(sectionDurs, 1) |  | ||||||
| 			); |  | ||||||
| 		] |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| genMidiPatterns = {arg seq; |  | ||||||
| 	var voices, durs, patterns, res, mOut, pbRange; |  | ||||||
| 	pbRange = 1; //semitones - change this as needed for your situation |  | ||||||
| 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); |  | ||||||
| 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice, v; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 
 |  | ||||||
| 			mOut.program(v, 70); |  | ||||||
| 
 |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \midi, |  | ||||||
| 				\chan, v, |  | ||||||
| 				\noteval, Pseq(freqs.cpsmidi - 24, 1), |  | ||||||
| 				\note, Pfunc({ | event | event[\noteval].floor }), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\midiout, mOut, |  | ||||||
| 				\amp, 1, |  | ||||||
| 				\bend, Pfunc({ |  | ||||||
| 					| event | |  | ||||||
| 					if (event[\note].isRest.not) { |  | ||||||
| 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; |  | ||||||
| 						m.bend(v, pitchbendvalue); |  | ||||||
| 					}; |  | ||||||
| 					0; // return something other than nil to avoid stopping the pattern |  | ||||||
| 				}), |  | ||||||
| 			); |  | ||||||
| 		}); |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------resource management funcs |  | ||||||
| 
 |  | ||||||
| genUID = {Date.seed.asHexString.toLower}; |  | ||||||
| 
 |  | ||||||
| seedFunc = {arg func, seed; |  | ||||||
| 	var funcArgs, next; |  | ||||||
| 	next = Routine({loop{func.valueArray(funcArgs).yield }}); |  | ||||||
| 	next.randSeed_(seed); |  | ||||||
| 	{arg ...args; funcArgs = args; next.value} |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| stringifyToDepth = {arg data, maxDepth = 1; |  | ||||||
| 	var prettyString = "", rCount = 0, writeArray, indent; |  | ||||||
| 
 |  | ||||||
| 	if(maxDepth == 0, { |  | ||||||
| 		data.asCompileString |  | ||||||
| 	}, { |  | ||||||
| 		indent = {arg size; size.collect({" "}).join("")}; |  | ||||||
| 		writeArray = {arg array; |  | ||||||
| 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; |  | ||||||
| 			rCount = rCount + 1; |  | ||||||
| 			if(rCount < (maxDepth - 0), { |  | ||||||
| 				array.do({arg subArray; writeArray.value(subArray)}); |  | ||||||
| 			}, { |  | ||||||
| 				prettyString = prettyString ++ array.collect({arg subArray; |  | ||||||
| 					indent.value(rCount + 1) ++ subArray.asCompileString |  | ||||||
| 				}).join(",\n"); |  | ||||||
| 			}); |  | ||||||
| 			rCount = rCount - 1; |  | ||||||
| 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		writeArray.value(data); |  | ||||||
| 		prettyString.replace(",\n\n", "\n").drop(-2); |  | ||||||
| 	}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| sanityCheck = {arg motif, index; |  | ||||||
| 	//print functions = very helpful |  | ||||||
| 	("----------" + index + "------------").postln; |  | ||||||
| 
 |  | ||||||
| 	motif.flatten.do({arg val, v; |  | ||||||
| 		if(v > 0, { |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); |  | ||||||
| 		}); |  | ||||||
| 		val.postln |  | ||||||
| 	}); |  | ||||||
| 	"***********".postln; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; |  | ||||||
| 	var res; |  | ||||||
| 
 |  | ||||||
| 	res = in; |  | ||||||
| 	if(res.isNil.not, { |  | ||||||
| 		if((res.isArray && res.isString.not), { |  | ||||||
| 			res = res.asCompileString; |  | ||||||
| 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); |  | ||||||
| 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); |  | ||||||
| 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); |  | ||||||
| 			res = res.replace("Rest", "\"Rest\""); |  | ||||||
| 			res = res.interpret; |  | ||||||
| 		}, { |  | ||||||
| 			//res.postln; |  | ||||||
| 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| writeResources = {arg path; |  | ||||||
| 	var file, nameSpaces, modelItems, resString; |  | ||||||
| 	file = File(path,"w"); |  | ||||||
| 
 |  | ||||||
| 	nameSpaces = [ |  | ||||||
| 		"music_data", "last_changes", |  | ||||||
| 		"cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", |  | ||||||
| 		"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", |  | ||||||
| 		"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size" |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	modelItems = [ |  | ||||||
| 		seq, lastXChanges, |  | ||||||
| 		curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| 		entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	resString = [nameSpaces, modelItems].flop.collect({arg item; |  | ||||||
| 		var nameSpace, modelItem, depth = 0, insert = " "; |  | ||||||
| 		# nameSpace, modelItem = item; |  | ||||||
| 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); |  | ||||||
| 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); |  | ||||||
| 		if(nameSpace == "order", {depth = 1; insert = "\n"}); |  | ||||||
| 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(modelItem.postln, depth).postln |  | ||||||
| 	}).join(",\n"); |  | ||||||
| 
 |  | ||||||
| 	resString = "{\n" ++ resString ++ "\n}"; |  | ||||||
| 
 |  | ||||||
| 	file.write(resString); |  | ||||||
| 	file.close; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; |  | ||||||
| 
 |  | ||||||
| loadModelJSON = {arg model; |  | ||||||
| 	var nameSpaces, data; |  | ||||||
| 
 |  | ||||||
| 	//model = File(path, "r").readAllString.parseJSON; |  | ||||||
| 
 |  | ||||||
| 	nameSpaces = [ |  | ||||||
| 		"cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", |  | ||||||
| 		"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", |  | ||||||
| 		"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size" |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	data = nameSpaces.collect({arg nS; msgInterpret.value(model[nS]).postln}); |  | ||||||
| 
 |  | ||||||
| 	data.postln; |  | ||||||
| 
 |  | ||||||
| 	# curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| 	entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize = data; |  | ||||||
| 
 |  | ||||||
| 	popSize = ranges.size; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadLedgerFile = {arg path; |  | ||||||
| 	ledgerPath = path; |  | ||||||
| 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadLedgerJSON = {arg ledger; ledger = ledger["ledger"]}; |  | ||||||
| 
 |  | ||||||
| //------global vars |  | ||||||
| 
 |  | ||||||
| primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; |  | ||||||
| //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; |  | ||||||
| exPath = thisProcess.nowExecutingPath; |  | ||||||
| dir = exPath.dirname; |  | ||||||
| //popSize = 4; |  | ||||||
| dims = primes.size; |  | ||||||
| tuples = genTuples.value(); |  | ||||||
| //refUID = nil; |  | ||||||
| group = Group.new; |  | ||||||
| loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); |  | ||||||
| //passagesWeights = [1, 1, 1, 1, 1]; |  | ||||||
| //susWeights = [1, 1, 1]; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------OSC funcs |  | ||||||
| 
 |  | ||||||
| OSCdef(\load_ledger, {arg msg, time, addr, port; |  | ||||||
| 	loadLedgerFile.value(msg[1].asString); |  | ||||||
| }, \load_ledger); |  | ||||||
| 
 |  | ||||||
| OSCdef(\load_model, {arg msg, time, addr, port; |  | ||||||
| 	loadModelFile.value(msg[1].asString); |  | ||||||
| }, \load_model); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| OSCdef(\generate, {arg msg, time, addr, port; |  | ||||||
| 	var path, dFormat, condition, musPath; |  | ||||||
| 	msg.postln; |  | ||||||
| 
 |  | ||||||
| 	path = msg[1].asString; |  | ||||||
| 
 |  | ||||||
| 	loadModelFile.value(path); |  | ||||||
| 
 |  | ||||||
| 	refUID.postln; |  | ||||||
| 
 |  | ||||||
| 	loadLedgerFile.value(ledgerPath); |  | ||||||
| 	if(ledger == nil, {ledger = ["tmp"]}); |  | ||||||
| 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); |  | ||||||
| 
 |  | ||||||
| 	lastXChanges = if(refUID == nil, { |  | ||||||
| 		[initVoices.value().deepCopy]; |  | ||||||
| 	}, { |  | ||||||
| 		var file; |  | ||||||
| 		refUID.postln; |  | ||||||
| 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); |  | ||||||
| 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..2] ++ [entrancesProbVals[3..]]); |  | ||||||
| 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..2] ++ [passagesProbVals[3..]]); |  | ||||||
| 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..2] ++ [exitsProbVals[3..]]); |  | ||||||
| 
 |  | ||||||
| 	if(orders == nil, { |  | ||||||
| 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); |  | ||||||
| 		addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); |  | ||||||
| 	}); |  | ||||||
| 	seq = seedFunc.value(genMotif, motifSeed).value; |  | ||||||
| 
 |  | ||||||
| 	//musPath = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; |  | ||||||
| 	writeResources.value(path); |  | ||||||
| 
 |  | ||||||
| 	//orders = nil; |  | ||||||
| 	//addr.sendMsg("/current_uid", curUID); |  | ||||||
| 	//addr.sendMsg("/ledger", prettifyArray.value(ledger, 1).replace("\"", "")); |  | ||||||
| 	//addr.sendMsg("/ledger_size", ledger.size); |  | ||||||
| 	//addr.sendMsg("/mus_seq", prettifyArray.value(seq, 3)); |  | ||||||
| 	addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); |  | ||||||
| }, \generate); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| OSCdef(\commit, {arg msg, time, addr, port; |  | ||||||
| 	var newLedger, modelPath, musString, musFile, test1, test2; |  | ||||||
| 	msg.postln; |  | ||||||
| 
 |  | ||||||
| 	/* |  | ||||||
| 	test1 = msg[1].asString.parseJSON; |  | ||||||
| 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; |  | ||||||
| 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; |  | ||||||
| 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; |  | ||||||
| 	(test1["music"] == test2["music_data"]).postln; |  | ||||||
| 	*/ |  | ||||||
| 
 |  | ||||||
| 	curUID = genUID.value; |  | ||||||
| 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); |  | ||||||
| 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); |  | ||||||
| 
 |  | ||||||
| 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; |  | ||||||
| 	writeResources.value(modelPath); |  | ||||||
| 
 |  | ||||||
| 	File.delete(ledgerPath.postln ++ "_bak"); |  | ||||||
| 	File.copy(ledgerPath, ledgerPath ++ "_bak"); |  | ||||||
| 	File.delete(ledgerPath); |  | ||||||
| 	newLedger = File(ledgerPath.postln, "w"); |  | ||||||
| 	ledger = ledger.postln.drop(-1).add(curUID); |  | ||||||
| 	newLedger.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); |  | ||||||
| 	newLedger.close; |  | ||||||
| 
 |  | ||||||
| 	addr.sendMsg("/committed", curUID, ledgerPath); |  | ||||||
| 	//refUID = curUID; |  | ||||||
| }, \commit); |  | ||||||
| 
 |  | ||||||
| OSCdef(\transport, {arg msg, time, addr, port; |  | ||||||
| 	msg.postln; |  | ||||||
| 	if(msg[1] == 0, { |  | ||||||
| 		player.stop; |  | ||||||
| 		group.set(\gate, 0); |  | ||||||
| 	}, { |  | ||||||
| 		// the cued sequence can now be read from file, so this can be cleaned up |  | ||||||
| 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; |  | ||||||
| 		pSeq = []; |  | ||||||
| 		cuedSeek = (seq != nil); |  | ||||||
| 		indexStart = msg[2].asInteger; |  | ||||||
| 		indexEnd = ledger.size - if(cuedSeek, {2}, {1}); |  | ||||||
| 		if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { |  | ||||||
| 			ledger[indexStart..indexEnd].do({arg uid, index; |  | ||||||
| 				var file; |  | ||||||
| 				(indexStart + index).postln; |  | ||||||
| 				file = File((dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_music" ++ ".json").standardizePath, "r"); |  | ||||||
| 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), indexStart + index, uid]); |  | ||||||
| 				file.close; |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 		if(cuedSeek, {pSeq = pSeq.add([seq, ledger.size - 1])}); |  | ||||||
| 		patterns = genPatterns.value(pSeq, addr); |  | ||||||
| 		player = Pfset(pattern: patterns, cleanupFunc: { |  | ||||||
| 			addr.sendMsg("/transport", 0); |  | ||||||
| 		}); |  | ||||||
| 		player = player.play |  | ||||||
| 	}); |  | ||||||
| }, \transport); |  | ||||||
| 
 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	freq = WhiteNoise.ar * 3 + freq; |  | ||||||
| 	freqFinal = Duty.ar((1/freq), 0, freq); |  | ||||||
| 	trig = Changed.ar(freqFinal); |  | ||||||
| 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); |  | ||||||
| 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); |  | ||||||
| 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 
 |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| "{\"a\": 1}".parseYAML["a"].asInteger; |  | ||||||
| "{\"a\": 1}".parseJSON["a"].isNumber; |  | ||||||
| 
 |  | ||||||
| 1223423434123.asHexString.toLower |  | ||||||
| 
 |  | ||||||
| Date.getDate.rawSeconds |  | ||||||
| Date.seed.asHexString.toLower |  | ||||||
| 
 |  | ||||||
| n = NetAddr("localhost", 8080); |  | ||||||
| n.sendMsg("/GET/#", (NetAddr.localAddr.hostname ++ ":" ++ NetAddr.localAddr.port), "/passage_probs_vals"); |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,59 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 1 ], [ "Rest" ] ], 0.875 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ] ], 0.875 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 1, 0 ], [ "Rest" ] ], 0.75 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, -1, 0 ], [ "Rest" ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ] ], 1.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ "Rest" ] ], 1.625 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ] ], 1.625 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ 1, -1, 1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.125 ], |  | ||||||
|     [ [ [ 2, -2, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1 ], |  | ||||||
|     [ [ [ 0, 1, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 1, 0, -1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.625 ], |  | ||||||
|     [ [ [ 2, -1, 0, -1, 0, -1 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 2 ], |  | ||||||
|     [ [ [ 2, -1, 0, -2, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ 1, -1, 1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.5 ], |  | ||||||
|     [ [ [ 2, -2, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ 2, -2, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ] ], 0.875 ], |  | ||||||
|     [ [ [ 2, -2, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 2, -2, 0, -1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.375 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 1, 0, -1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 2, -1, 0, -1, 0, -1 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 2, -1, 0, -2, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 1, -1, 1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], |  | ||||||
|   [ [ 2, -2, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "7ac10d34", |  | ||||||
| "ref_uid": "46b6952a", |  | ||||||
| "order_seed": 638872, |  | ||||||
| "dur_seed": 225879, |  | ||||||
| "motifs_seed": 992393, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 0 ], [ 2, 2, 2, 2, 2, 2, 2 ], [ 3, 1 ] ], |  | ||||||
|   [ [ 1, 2, 3 ], [ 0, 0, 0, 0, 0, 0, 0, 0 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ] |  | ||||||
| } |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,86 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 8.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 9.125 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 1, 0, 1, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 1, 0, 0, 0, -1, 1 ], [ 2, -1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0.125 ], |  | ||||||
|     [ [ [ 2, 0, 1, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 3, 0, 0, -1, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 0, 0, 1, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 1, 0, 0, 0, -1, 0 ] ], 5.125 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 3, -1, 0, 0, -2, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 1, 0, 1, 0, -1, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 2, 0, -1, 0, -1, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 2, -1, -1, 0, -1, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 1, -1, 0, 0, 0, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 1, -1, 0, 1, -1, 0 ] ], 0.375 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 2, -2, 0, 0, -1, 0 ] ], 1.625 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 2, 0, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 3, -1, 0, 0, -1, 0 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ "Rest" ] ], 0.125 ], |  | ||||||
|     [ [ [ 2, 0, 0, 0, 0, -1 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 3, 0, 0, -1, -1, -1 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 3, 0, 0, 0, -2, -1 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ "Rest" ] ], 0.125 ], |  | ||||||
|     [ [ [ 3, 0, 0, 0, -1, -1 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ "Rest" ] ], 0.5 ], |  | ||||||
|     [ [ [ 2, 0, 1, 0, -1, -1 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ "Rest" ] ], 8.875 ], |  | ||||||
|     [ [ [ "Rest" ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 2, -1, 0, 0, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.75 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 2, 0, 0, 0, 0, -1 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 2, -2, 0, 0, -1, 0 ] ], |  | ||||||
|   [ [ 3, 0, 0, -1, -1, -1 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 2, -2, 0, 0, -1, 0 ] ], |  | ||||||
|   [ [ 3, 0, 0, 0, -2, -1 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 2, -2, 0, 0, -1, 0 ] ], |  | ||||||
|   [ [ 3, 0, 0, 0, -1, -1 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 2, -2, 0, 0, -1, 0 ] ], |  | ||||||
|   [ [ 2, 0, 1, 0, -1, -1 ], [ 2, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, -1 ], [ 2, -2, 0, 0, -1, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "7bfea52f", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 698323, |  | ||||||
| "dur_seed": 999832, |  | ||||||
| "motifs_seed": 474018, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 1, 2 ], [ 3, 3, 3, 3, 3, 3, 3 ], [  ] ], |  | ||||||
|   [ [ 3 ], [ 2, 0, 1, 0, 0, 0, 0, 0, 2, 2, 2 ], [  ] ], |  | ||||||
|   [ [ 0, 2, 1 ], [ 3, 3, 3, 3, 3, 3, 3 ], [  ] ], |  | ||||||
|   [ [ 2, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 3 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -1,718 +0,0 @@ | |||||||
| ( |  | ||||||
| // helper funcs |  | ||||||
| var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; |  | ||||||
| 
 |  | ||||||
| // score funcs |  | ||||||
| var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; |  | ||||||
| 
 |  | ||||||
| // subroutines |  | ||||||
| var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; |  | ||||||
| 
 |  | ||||||
| // primary routines |  | ||||||
| var genMotif, genSecondarySeq; |  | ||||||
| 
 |  | ||||||
| // audition funcs |  | ||||||
| var genPatterns, genMidiPatterns; |  | ||||||
| 
 |  | ||||||
| // resource management funcs |  | ||||||
| var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, |  | ||||||
| msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON; |  | ||||||
| 
 |  | ||||||
| // model vars |  | ||||||
| //(model and global vars mostly set by OSC funcs |  | ||||||
| var curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| ranges, orders, susWeights, passagesWeights, passagesSize, orderSize; |  | ||||||
| 
 |  | ||||||
| // model aux vars |  | ||||||
| var entrancesDurFunc, passagesDurFunc, exitsDurFunc; |  | ||||||
| 
 |  | ||||||
| // other global vars |  | ||||||
| var lastXChanges, popSize, exPath, dir, primes, dims, tuples, |  | ||||||
| seq, group, player, ledgerPath, ledger, currentlyPlayingUID; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // install JSON quark |  | ||||||
| if(Quarks.isInstalled("JSONlib").not, { |  | ||||||
| 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); |  | ||||||
| 	thisProcess.recompile; |  | ||||||
| 	//HelpBrowser.openHelpFor("Classes/JSONlib"); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------helper funcs |  | ||||||
| 
 |  | ||||||
| hsArrayToCents = { |  | ||||||
| 	arg hsArray; |  | ||||||
| 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| pDist = { |  | ||||||
| 	arg array1, array2, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); |  | ||||||
| 	if(signed, {pDistance}, {abs(pDistance)}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hdSum = { |  | ||||||
| 	arg hsArrays; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays.size; |  | ||||||
| 	distances = (size - 1).collect({arg i; |  | ||||||
| 		((i + 1)..(size - 1)).collect({arg j; |  | ||||||
| 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsChordalDistance = { |  | ||||||
| 	arg hsArrays1, hsArrays2; |  | ||||||
| 	var size, distances, mean; |  | ||||||
| 	size = hsArrays1.size; |  | ||||||
| 	distances = hsArrays1.size.collect({arg i; |  | ||||||
| 		hsArrays2.size.collect({arg j; |  | ||||||
| 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum |  | ||||||
| 		}); |  | ||||||
| 	}).flat; |  | ||||||
| 	mean = distances.sum / distances.size; |  | ||||||
| 	distances.sum |  | ||||||
| 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| hsArrayToFreq = { |  | ||||||
| 	arg array; |  | ||||||
| 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| //------score funcs |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| isInRange = { |  | ||||||
| 	arg hsArray, min, max; |  | ||||||
| 	var cents; |  | ||||||
| 	cents = hsArrayToCents.value(hsArray); |  | ||||||
| 	(cents >= min) && (cents <= max) |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| spacingScore = { |  | ||||||
| 	arg hsArrays, min; |  | ||||||
| 	var centsArray; |  | ||||||
| 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); |  | ||||||
| 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| rangeScore = { |  | ||||||
| 	arg hsArray1, hsArray2, min, max, low, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| intervalScore = { |  | ||||||
| 	arg hsArray1, hsArray2, mean, sd, signed = false; |  | ||||||
| 	var pDistance; |  | ||||||
| 	pDistance = pDist.value(hsArray1, hsArray2, signed); |  | ||||||
| 	pDistance.gaussCurve(1, mean, sd) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| inclusionScore = { |  | ||||||
| 	arg array, test, min = 0.01; |  | ||||||
| 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------subroutines |  | ||||||
| 
 |  | ||||||
| genTuples = { |  | ||||||
| 	var tuples; |  | ||||||
| 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); |  | ||||||
| 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| initVoices = { |  | ||||||
| 	var init, voicesInit; |  | ||||||
| 	voicesInit = popSize.collect({dims.collect({0})}); |  | ||||||
| 	/* |  | ||||||
| 	voicesInit = [dims.collect({0})]; |  | ||||||
| 	(popSize - 1).do({ |  | ||||||
| 		arg rep, new; |  | ||||||
| 		rep = dims.rand; |  | ||||||
| 		new = voicesInit.last.deepCopy; |  | ||||||
| 		new[rep] = new[rep] + [-1, 1].choose(); |  | ||||||
| 		voicesInit = voicesInit.add(new); |  | ||||||
| 	}); |  | ||||||
| 	*/ |  | ||||||
| 	voicesInit.deepCopy; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genDurFunc = {arg chordProb, min, max, envData; |  | ||||||
| 	var env, pTable, durFunc; |  | ||||||
| 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; |  | ||||||
| 	pTable = env.asRandomTable; |  | ||||||
| 	durFunc = {arg allowChord; |  | ||||||
| 		var res; |  | ||||||
| 		res = if(allowChord.not, { |  | ||||||
| 			pTable.tableRand * (max - min) + min |  | ||||||
| 		}, { |  | ||||||
| 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (max - min) + min}); |  | ||||||
| 		}).round(0.125); |  | ||||||
| 		if(res.asInteger == res, {res = res.asInteger}); |  | ||||||
| 		res |  | ||||||
| 	}; |  | ||||||
| 	seedFunc.value(durFunc, durSeed); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; |  | ||||||
| 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ |  | ||||||
| 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; |  | ||||||
| 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); |  | ||||||
| 		noProgIns = (popSize - noSusIns).rand + 1; |  | ||||||
| 		noSilentIns = popSize - noSusIns - noProgIns; |  | ||||||
| 
 |  | ||||||
| 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); |  | ||||||
| 
 |  | ||||||
| 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); |  | ||||||
| 		if(silent == nil, {silent = []}); |  | ||||||
| 		[sus.scramble, prog, silent.scramble] |  | ||||||
| 	}); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| updateVoices = {arg ins, sus; |  | ||||||
| 	var voices, candidates, nWeights, nProbs, sel; |  | ||||||
| 
 |  | ||||||
| 	voices = lastXChanges.deepCopy.last; |  | ||||||
| 
 |  | ||||||
| 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; |  | ||||||
| 	candidates = difference(candidates.asSet, voices.asSet).asList; |  | ||||||
| 	nProbs = candidates.collect({arg candidate; |  | ||||||
| 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; |  | ||||||
| 
 |  | ||||||
| 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); |  | ||||||
| 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); |  | ||||||
| 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); |  | ||||||
| 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); |  | ||||||
| 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); |  | ||||||
| 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); |  | ||||||
| 		//maybe what you want here is a vector to another root and then favoring movement towards it. |  | ||||||
| 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); |  | ||||||
| 
 |  | ||||||
| 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	nWeights = passagesWeights; |  | ||||||
| 
 |  | ||||||
| 	//this handles nWeights of 0; mainly for testing |  | ||||||
| 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; |  | ||||||
| 	nWeights = nWeights.select({arg weight; weight != 0}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; |  | ||||||
| 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) |  | ||||||
| 	}); |  | ||||||
| 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; |  | ||||||
| 
 |  | ||||||
| 	sel = candidates.wchoose(nProbs); |  | ||||||
| 
 |  | ||||||
| 	voices[ins] = sel; |  | ||||||
| 	lastXChanges = lastXChanges.add(voices).keep(-5); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSubMotif = {arg order, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; |  | ||||||
| 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, lastXChangesHold, voices, adder; |  | ||||||
| 	# sus, prog, silent = order; |  | ||||||
| 	flatOrder = silent ++ sus ++ prog; |  | ||||||
| 	lastXChangesHold = lastXChanges.deepCopy; |  | ||||||
| 	voices = lastState.deepCopy; |  | ||||||
| 	isInChord = popSize.collect({false}); |  | ||||||
| 	allowChord = false; |  | ||||||
| 	res = []; |  | ||||||
| 	"------generating motif".postln; |  | ||||||
| 	//need to figure out here if voices move between motifs |  | ||||||
| 	flatOrder.do({arg ins, i; |  | ||||||
| 
 |  | ||||||
| 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); |  | ||||||
| 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); |  | ||||||
| 
 |  | ||||||
| 		if(voices[ins] != adder, { |  | ||||||
| 			var dur; |  | ||||||
| 			allowChord = if((sus ++ silent).includes(ins), { |  | ||||||
| 				(sus ++ silent).includes(ins) && (ins != sus.last); |  | ||||||
| 			}, { |  | ||||||
| 				if(i < (flatOrder.size - 1), {(isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not}, {false}); |  | ||||||
| 			}); |  | ||||||
| 			dur = passagesDurFunc.value(allowChord); |  | ||||||
| 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); |  | ||||||
| 
 |  | ||||||
| 			voices[ins] = adder; |  | ||||||
| 			res = res.add([voices.deepCopy.postln, dur]); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	// pad ending |  | ||||||
| 	if(isLastOrder, { |  | ||||||
| 		(0..(popSize-1)).scramble.do({arg ins; |  | ||||||
| 			if(res.last.first[ins] != ["Rest"], { |  | ||||||
| 				var dur; |  | ||||||
| 				voices[ins] = ["Rest"]; |  | ||||||
| 				allowChord = (voices != popSize.collect({["Rest"]})); |  | ||||||
| 				dur = passagesDurFunc.value(allowChord); |  | ||||||
| 				res = res.add([voices.deepCopy.postln, dur]); |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	//format and return |  | ||||||
| 	if(startFromLast, {lastXChanges = lastXChangesHold}); |  | ||||||
| 	res; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------primary routines |  | ||||||
| 
 |  | ||||||
| genMotif = { |  | ||||||
| 	var repeats, fSeq; |  | ||||||
| 
 |  | ||||||
| 	repeats = 1; |  | ||||||
| 	fSeq = []; |  | ||||||
| 
 |  | ||||||
| 	repeats.do({arg index; |  | ||||||
| 		var motif; |  | ||||||
| 
 |  | ||||||
| 		motif = []; |  | ||||||
| 
 |  | ||||||
| 		orders.do({arg order, o; |  | ||||||
| 			var lastState, subMotif; |  | ||||||
| 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); |  | ||||||
| 			subMotif = genSubMotif.value(order, lastState, isLastOrder: o == (orders.size - 1)); |  | ||||||
| 			motif = motif.add(subMotif); |  | ||||||
| 
 |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		sanityCheck.value(motif, index); |  | ||||||
| 
 |  | ||||||
| 		fSeq = fSeq.add(motif); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| genSecondarySeq = {arg seq; |  | ||||||
| 	var curdles, fSeq; |  | ||||||
| 	curdles = []; |  | ||||||
| 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); |  | ||||||
| 
 |  | ||||||
| 	fSeq = seq.clumps(curdles).collect({arg clump, m; |  | ||||||
| 		var repeats, paddedSeq; |  | ||||||
| 
 |  | ||||||
| 		//add rest |  | ||||||
| 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); |  | ||||||
| 
 |  | ||||||
| 		//implement repeats |  | ||||||
| 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); |  | ||||||
| 		repeats.collect({paddedSeq}); |  | ||||||
| 	}); |  | ||||||
| 	fSeq |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------audition funcs |  | ||||||
| 
 |  | ||||||
| Event.addEventType(\osc, { |  | ||||||
| 	if (~addr.postln.notNil) { |  | ||||||
| 		~addr.sendMsg(~indexPath, ~indexMsg); |  | ||||||
| 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); |  | ||||||
| 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); |  | ||||||
| 	}; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| genPatterns = {arg inSeq, addr; |  | ||||||
| 	var voices, durs, patterns, res, indices, sectionDurs, ids, seq; |  | ||||||
| 	seq = inSeq.collect({arg mSeq; mSeq[0]}); |  | ||||||
| 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	indices = inSeq.collect({arg mSeq, m; mSeq[1]}); |  | ||||||
| 	ids = inSeq.collect({arg mSeq, m; mSeq[2]}); |  | ||||||
| 	sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\instrument, \test, |  | ||||||
| 				\group, group, |  | ||||||
| 				\freq, Pseq(freqs, 1), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\sustain, Pseq(fDurs, 1) |  | ||||||
| 			) |  | ||||||
| 		}) ++ |  | ||||||
| 		[ |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \osc, |  | ||||||
| 				\addr, addr, |  | ||||||
| 				\indexPath, "/cur_play_index", |  | ||||||
| 				\indexMsg, Pseq(indices.postln, 1), |  | ||||||
| 				\seqPath, "/mus_seq", |  | ||||||
| 				\seqMsg, Pseq(seq, 1), |  | ||||||
| 				\dur, Pseq(sectionDurs, 1) |  | ||||||
| 			); |  | ||||||
| 		] |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| genMidiPatterns = {arg seq; |  | ||||||
| 	var voices, durs, patterns, res, mOut, pbRange; |  | ||||||
| 	pbRange = 1; //semitones - change this as needed for your situation |  | ||||||
| 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); |  | ||||||
| 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; |  | ||||||
| 	res = Ppar( |  | ||||||
| 		voices.flop.collect({arg voice, v; |  | ||||||
| 			var clumps, hdScores, freqs, fDurs; |  | ||||||
| 
 |  | ||||||
| 			mOut.program(v, 70); |  | ||||||
| 
 |  | ||||||
| 			clumps = voice.separate({arg a, b; a != b }); |  | ||||||
| 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); |  | ||||||
| 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); |  | ||||||
| 
 |  | ||||||
| 			Pbind( |  | ||||||
| 				\type, \midi, |  | ||||||
| 				\chan, v, |  | ||||||
| 				\noteval, Pseq(freqs.cpsmidi - 24, 1), |  | ||||||
| 				\note, Pfunc({ | event | event[\noteval].floor }), |  | ||||||
| 				\dur, Pseq(fDurs, 1), |  | ||||||
| 				\midiout, mOut, |  | ||||||
| 				\amp, 1, |  | ||||||
| 				\bend, Pfunc({ |  | ||||||
| 					| event | |  | ||||||
| 					if (event[\note].isRest.not) { |  | ||||||
| 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; |  | ||||||
| 						m.bend(v, pitchbendvalue); |  | ||||||
| 					}; |  | ||||||
| 					0; // return something other than nil to avoid stopping the pattern |  | ||||||
| 				}), |  | ||||||
| 			); |  | ||||||
| 		}); |  | ||||||
| 	); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------resource management funcs |  | ||||||
| 
 |  | ||||||
| genUID = {Date.seed.asHexString.toLower}; |  | ||||||
| 
 |  | ||||||
| seedFunc = {arg func, seed; |  | ||||||
| 	var funcArgs, next; |  | ||||||
| 	next = Routine({loop{func.valueArray(funcArgs).yield }}); |  | ||||||
| 	next.randSeed_(seed); |  | ||||||
| 	{arg ...args; funcArgs = args; next.value} |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| stringifyToDepth = {arg data, maxDepth = 1; |  | ||||||
| 	var prettyString = "", rCount = 0, writeArray, indent; |  | ||||||
| 
 |  | ||||||
| 	if(maxDepth == 0, { |  | ||||||
| 		data.asCompileString |  | ||||||
| 	}, { |  | ||||||
| 		indent = {arg size; size.collect({" "}).join("")}; |  | ||||||
| 		writeArray = {arg array; |  | ||||||
| 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; |  | ||||||
| 			rCount = rCount + 1; |  | ||||||
| 			if(rCount < (maxDepth - 0), { |  | ||||||
| 				array.do({arg subArray; writeArray.value(subArray)}); |  | ||||||
| 			}, { |  | ||||||
| 				prettyString = prettyString ++ array.collect({arg subArray; |  | ||||||
| 					indent.value(rCount + 1) ++ subArray.asCompileString |  | ||||||
| 				}).join(",\n"); |  | ||||||
| 			}); |  | ||||||
| 			rCount = rCount - 1; |  | ||||||
| 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		writeArray.value(data); |  | ||||||
| 		prettyString.replace(",\n\n", "\n").drop(-2); |  | ||||||
| 	}) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| sanityCheck = {arg motif, index; |  | ||||||
| 	//print functions = very helpful |  | ||||||
| 	("----------" + index + "------------").postln; |  | ||||||
| 
 |  | ||||||
| 	motif.flatten.do({arg val, v; |  | ||||||
| 		if(v > 0, { |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); |  | ||||||
| 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); |  | ||||||
| 		}); |  | ||||||
| 		val.postln |  | ||||||
| 	}); |  | ||||||
| 	"***********".postln; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; |  | ||||||
| 	var res; |  | ||||||
| 
 |  | ||||||
| 	res = in; |  | ||||||
| 	if(res.isNil.not, { |  | ||||||
| 		if((res.isArray && res.isString.not), { |  | ||||||
| 			res = res.asCompileString; |  | ||||||
| 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); |  | ||||||
| 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); |  | ||||||
| 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); |  | ||||||
| 			res = res.replace("Rest", "\"Rest\""); |  | ||||||
| 			res = res.interpret; |  | ||||||
| 		}, { |  | ||||||
| 			//res.postln; |  | ||||||
| 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
| 	res |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| writeResources = {arg path; |  | ||||||
| 	var file, nameSpaces, modelItems, resString; |  | ||||||
| 	file = File(path,"w"); |  | ||||||
| 
 |  | ||||||
| 	nameSpaces = [ |  | ||||||
| 		"music_data", "last_changes", |  | ||||||
| 		"cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", |  | ||||||
| 		"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", |  | ||||||
| 		"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size" |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	modelItems = [ |  | ||||||
| 		seq, lastXChanges, |  | ||||||
| 		curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| 		entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	resString = [nameSpaces, modelItems].flop.collect({arg item; |  | ||||||
| 		var nameSpace, modelItem, depth = 0, insert = " "; |  | ||||||
| 		# nameSpace, modelItem = item; |  | ||||||
| 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); |  | ||||||
| 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); |  | ||||||
| 		if(nameSpace == "order", {depth = 1; insert = "\n"}); |  | ||||||
| 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(modelItem.postln, depth).postln |  | ||||||
| 	}).join(",\n"); |  | ||||||
| 
 |  | ||||||
| 	resString = "{\n" ++ resString ++ "\n}"; |  | ||||||
| 
 |  | ||||||
| 	file.write(resString); |  | ||||||
| 	file.close; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; |  | ||||||
| 
 |  | ||||||
| loadModelJSON = {arg model; |  | ||||||
| 	var nameSpaces, data; |  | ||||||
| 
 |  | ||||||
| 	//model = File(path, "r").readAllString.parseJSON; |  | ||||||
| 
 |  | ||||||
| 	nameSpaces = [ |  | ||||||
| 		"cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", |  | ||||||
| 		"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", |  | ||||||
| 		"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size" |  | ||||||
| 	]; |  | ||||||
| 
 |  | ||||||
| 	data = nameSpaces.collect({arg nS; msgInterpret.value(model[nS]).postln}); |  | ||||||
| 
 |  | ||||||
| 	data.postln; |  | ||||||
| 
 |  | ||||||
| 	# curUID, refUID, orderSeed, durSeed, motifSeed, |  | ||||||
| 	entrancesProbVals, passagesProbVals, exitsProbVals, |  | ||||||
| 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize = data; |  | ||||||
| 
 |  | ||||||
| 	popSize = ranges.size; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadLedgerFile = {arg path; |  | ||||||
| 	ledgerPath = path; |  | ||||||
| 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| loadLedgerJSON = {arg ledger; ledger = ledger["ledger"]}; |  | ||||||
| 
 |  | ||||||
| //------global vars |  | ||||||
| 
 |  | ||||||
| primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; |  | ||||||
| //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; |  | ||||||
| exPath = thisProcess.nowExecutingPath; |  | ||||||
| dir = exPath.dirname; |  | ||||||
| //popSize = 4; |  | ||||||
| dims = primes.size; |  | ||||||
| tuples = genTuples.value(); |  | ||||||
| //refUID = nil; |  | ||||||
| group = Group.new; |  | ||||||
| loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); |  | ||||||
| //passagesWeights = [1, 1, 1, 1, 1]; |  | ||||||
| //susWeights = [1, 1, 1]; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //------OSC funcs |  | ||||||
| 
 |  | ||||||
| OSCdef(\load_ledger, {arg msg, time, addr, port; |  | ||||||
| 	loadLedgerFile.value(msg[1].asString); |  | ||||||
| }, \load_ledger); |  | ||||||
| 
 |  | ||||||
| OSCdef(\load_model, {arg msg, time, addr, port; |  | ||||||
| 	loadModelFile.value(msg[1].asString); |  | ||||||
| }, \load_model); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| OSCdef(\generate, {arg msg, time, addr, port; |  | ||||||
| 	var path, dFormat, condition, musPath; |  | ||||||
| 	msg.postln; |  | ||||||
| 
 |  | ||||||
| 	path = msg[1].asString; |  | ||||||
| 
 |  | ||||||
| 	loadModelFile.value(path); |  | ||||||
| 
 |  | ||||||
| 	refUID.postln; |  | ||||||
| 
 |  | ||||||
| 	loadLedgerFile.value(ledgerPath); |  | ||||||
| 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); |  | ||||||
| 
 |  | ||||||
| 	lastXChanges = if(refUID == nil, { |  | ||||||
| 		[initVoices.value().deepCopy]; |  | ||||||
| 	}, { |  | ||||||
| 		var file; |  | ||||||
| 		refUID.postln; |  | ||||||
| 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); |  | ||||||
| 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..2] ++ [entrancesProbVals[3..]]); |  | ||||||
| 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..2] ++ [passagesProbVals[3..]]); |  | ||||||
| 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..2] ++ [exitsProbVals[3..]]); |  | ||||||
| 
 |  | ||||||
| 	if(orders == nil, { |  | ||||||
| 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); |  | ||||||
| 		addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); |  | ||||||
| 	}); |  | ||||||
| 	seq = seedFunc.value(genMotif, motifSeed).value; |  | ||||||
| 
 |  | ||||||
| 	//musPath = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; |  | ||||||
| 	writeResources.value(path); |  | ||||||
| 
 |  | ||||||
| 	//orders = nil; |  | ||||||
| 	//addr.sendMsg("/current_uid", curUID); |  | ||||||
| 	//addr.sendMsg("/ledger", prettifyArray.value(ledger, 1).replace("\"", "")); |  | ||||||
| 	//addr.sendMsg("/ledger_size", ledger.size); |  | ||||||
| 	//addr.sendMsg("/mus_seq", prettifyArray.value(seq, 3)); |  | ||||||
| 	addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); |  | ||||||
| }, \generate); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| OSCdef(\commit, {arg msg, time, addr, port; |  | ||||||
| 	var newLedger, modelPath, musString, musFile, test1, test2; |  | ||||||
| 	msg.postln; |  | ||||||
| 
 |  | ||||||
| 	/* |  | ||||||
| 	test1 = msg[1].asString.parseJSON; |  | ||||||
| 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; |  | ||||||
| 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; |  | ||||||
| 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; |  | ||||||
| 	(test1["music"] == test2["music_data"]).postln; |  | ||||||
| 	*/ |  | ||||||
| 
 |  | ||||||
| 	curUID = genUID.value; |  | ||||||
| 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); |  | ||||||
| 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); |  | ||||||
| 
 |  | ||||||
| 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; |  | ||||||
| 	writeResources.value(modelPath); |  | ||||||
| 
 |  | ||||||
| 	File.delete(ledgerPath.postln ++ "_bak"); |  | ||||||
| 	File.copy(ledgerPath, ledgerPath ++ "_bak"); |  | ||||||
| 	File.delete(ledgerPath); |  | ||||||
| 	newLedger = File(ledgerPath.postln, "w"); |  | ||||||
| 	ledger = ledger.postln.drop(-1).add(curUID); |  | ||||||
| 	newLedger.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); |  | ||||||
| 	newLedger.close; |  | ||||||
| 
 |  | ||||||
| 	addr.sendMsg("/committed", curUID, ledgerPath); |  | ||||||
| 	//refUID = curUID; |  | ||||||
| }, \commit); |  | ||||||
| 
 |  | ||||||
| OSCdef(\transport, {arg msg, time, addr, port; |  | ||||||
| 	msg.postln; |  | ||||||
| 	if(msg[1] == 0, { |  | ||||||
| 		player.stop; |  | ||||||
| 		group.set(\gate, 0); |  | ||||||
| 	}, { |  | ||||||
| 		// the cued sequence can now be read from file, so this can be cleaned up |  | ||||||
| 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; |  | ||||||
| 		pSeq = []; |  | ||||||
| 		cuedSeek = (seq != nil); |  | ||||||
| 		indexStart = msg[2].asInteger; |  | ||||||
| 		indexEnd = ledger.size - if(cuedSeek, {2}, {1}); |  | ||||||
| 		if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { |  | ||||||
| 			ledger[indexStart..indexEnd].do({arg uid, index; |  | ||||||
| 				var file; |  | ||||||
| 				(indexStart + index).postln; |  | ||||||
| 				file = File((dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_music" ++ ".json").standardizePath, "r"); |  | ||||||
| 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), indexStart + index, uid]); |  | ||||||
| 				file.close; |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 		if(cuedSeek, {pSeq = pSeq.add([seq, ledger.size - 1])}); |  | ||||||
| 		patterns = genPatterns.value(pSeq, addr); |  | ||||||
| 		player = Pfset(pattern: patterns, cleanupFunc: { |  | ||||||
| 			addr.sendMsg("/transport", 0); |  | ||||||
| 		}); |  | ||||||
| 		player = player.play |  | ||||||
| 	}); |  | ||||||
| }, \transport); |  | ||||||
| 
 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| ( |  | ||||||
| SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; |  | ||||||
| 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; |  | ||||||
| 	noHarms = 30; |  | ||||||
| 	freq = WhiteNoise.ar * 3 + freq; |  | ||||||
| 	freqFinal = Duty.ar((1/freq), 0, freq); |  | ||||||
| 	trig = Changed.ar(freqFinal); |  | ||||||
| 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); |  | ||||||
| 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); |  | ||||||
| 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); |  | ||||||
| 
 |  | ||||||
| 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), |  | ||||||
| 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), |  | ||||||
| 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; |  | ||||||
| 	sig1 = HPF.ar(sig1, 300); |  | ||||||
| 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); |  | ||||||
| }).add; |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| "{\"a\": 1}".parseYAML["a"].asInteger; |  | ||||||
| "{\"a\": 1}".parseJSON["a"].isNumber; |  | ||||||
| 
 |  | ||||||
| 1223423434123.asHexString.toLower |  | ||||||
| 
 |  | ||||||
| Date.getDate.rawSeconds |  | ||||||
| Date.seed.asHexString.toLower |  | ||||||
| 
 |  | ||||||
| n = NetAddr("localhost", 8080); |  | ||||||
| n.sendMsg("/GET/#", (NetAddr.localAddr.hostname ++ ":" ++ NetAddr.localAddr.port), "/passage_probs_vals"); |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,79 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.75 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0.625 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0.875 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 1.375 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 1.875 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 1.625 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ] ], 1.75 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ] ], 1.875 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 1.375 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ] ], 1.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ] ], 1 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ] ], 1.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ] ], 1.625 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ] ], 1.75 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ] ], 1.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ] ], 1.25 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 1 ] ], 1.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 1 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "7e170ef8", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 142640, |  | ||||||
| "dur_seed": 629022, |  | ||||||
| "motifs_seed": 973728, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 2 ], [ 3, 1, 3, 3, 3, 1, 1, 3, 3, 1 ], [ 0 ] ], |  | ||||||
|   [ [ 0 ], [ 1, 2, 3, 3, 1, 3, 1, 3 ], [  ] ], |  | ||||||
|   [ [ 0, 3 ], [ 1, 1, 1, 1, 1, 1 ], [ 2 ] ], |  | ||||||
|   [ [ 1, 2, 0 ], [ 3, 3, 3, 3 ], [  ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ] |  | ||||||
| } |  | ||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -1,72 +0,0 @@ | |||||||
| { |  | ||||||
| "music_data": |  | ||||||
| [ |  | ||||||
|  [ |  | ||||||
|   [ |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 2.625 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], |  | ||||||
|     [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ], [ 1, 0, -1, 0, 0, -1 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ], [ 1, -1, 0, 0, 0, -1 ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ], [ 1, -1, 0, 0, 0, -1 ] ], 9.625 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 1, 0, 0, 1, -1 ], [ 1, -1, 0, 0, 0, -1 ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, -1 ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, -1, 0, 1, 0, -1 ], [ 1, -1, 0, 0, 0, -1 ] ], 9.25 ] |  | ||||||
|   ], |  | ||||||
|   [ |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, -1, 0, 1, 0, -1 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 1, 0, 0, -1, -1 ], [ "Rest" ] ], 0.5 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 1, -1, 0, 0, -1 ], [ "Rest" ] ], 0.375 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 1, 0 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 2, 1, 0, 0, 0, -2 ], [ "Rest" ] ], 0.25 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ], [ "Rest" ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 2, 0, 0, 0, -1 ], [ "Rest" ] ], 0.125 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 2, 0, 0, 0, -1 ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], |  | ||||||
|     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.5 ] |  | ||||||
|   ] |  | ||||||
|  ] |  | ||||||
| ], |  | ||||||
| "last_changes": |  | ||||||
| [ |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 1, -1, 0, 0, -1 ], [ 1, -1, 0, 0, 0, -1 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, -1, 0, 0, 0, -1 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 2, 1, 0, 0, 0, -2 ], [ 1, -1, 0, 0, 0, -1 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, -1 ] ], |  | ||||||
|   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 2, 0, 0, 0, -1 ], [ 1, -1, 0, 0, 0, -1 ] ] |  | ||||||
| ], |  | ||||||
| "cur_uid": "7e2c2e91", |  | ||||||
| "ref_uid": "nil", |  | ||||||
| "order_seed": 644790, |  | ||||||
| "dur_seed": 905095, |  | ||||||
| "motifs_seed": 879826, |  | ||||||
| "entrances_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], |  | ||||||
| "passages_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "exits_probs_vals": [ 0.75, 0, 10, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], |  | ||||||
| "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], |  | ||||||
| "step_probs_vals": [ 0, 1200, 0, 0.5, 0.5, 0.5, 1, 0.5 ], |  | ||||||
| "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], |  | ||||||
| "hd_exp": 2, |  | ||||||
| "hd_invert": 0, |  | ||||||
| "order": |  | ||||||
| [ |  | ||||||
|   [ [ 3 ], [ 2, 1, 1, 1, 2 ], [ 0 ] ], |  | ||||||
|   [ [ 0, 2 ], [ 1, 3, 3, 1 ], [  ] ], |  | ||||||
|   [ [ 1, 0, 3 ], [ 2, 2, 2 ], [  ] ], |  | ||||||
|   [ [ 0, 1 ], [ 2, 2, 2, 2, 2, 2 ], [ 3 ] ] |  | ||||||
| ], |  | ||||||
| "sus_weights": [ 0.75, 0.69, 0.75 ], |  | ||||||
| "order_size": [ 2, 6 ], |  | ||||||
| "passages_size": [ 0, 10 ], |  | ||||||
| "motif_edited": "false", |  | ||||||
| "order_edited": "false" |  | ||||||
| } |  | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | { | ||||||
|  | "ledger": | ||||||
|  | [ | ||||||
|  |   "314s49e1", | ||||||
|  |   "7e170ef8", | ||||||
|  |   "7ac10d34", | ||||||
|  |   "628d5c8b", | ||||||
|  |   "6abf27d4", | ||||||
|  |   "6d743c5c", | ||||||
|  |   "5625a95a", | ||||||
|  |   "5267b235", | ||||||
|  |   "6a3f7c7c", | ||||||
|  |   "6d0c2f19", | ||||||
|  |   "7bf874ce", | ||||||
|  |   "50fec831", | ||||||
|  |   "7fd4d544", | ||||||
|  |   "6f1305ed", | ||||||
|  |   "7c7a96a2", | ||||||
|  |   "7c8bc6df", | ||||||
|  |   "46210507", | ||||||
|  |   "74faf83f", | ||||||
|  |   "703e109b", | ||||||
|  |   "4b96f62d", | ||||||
|  |   "449aeaa6", | ||||||
|  |   "6409252e" | ||||||
|  | ] | ||||||
|  | } | ||||||
| @ -0,0 +1,26 @@ | |||||||
|  | { | ||||||
|  | "ledger": | ||||||
|  | [ | ||||||
|  |   "314s49e1", | ||||||
|  |   "7e170ef8", | ||||||
|  |   "7ac10d34", | ||||||
|  |   "628d5c8b", | ||||||
|  |   "6abf27d4", | ||||||
|  |   "6d743c5c", | ||||||
|  |   "5625a95a", | ||||||
|  |   "5267b235", | ||||||
|  |   "6a3f7c7c", | ||||||
|  |   "6d0c2f19", | ||||||
|  |   "7bf874ce", | ||||||
|  |   "50fec831", | ||||||
|  |   "7fd4d544", | ||||||
|  |   "6f1305ed", | ||||||
|  |   "7c7a96a2", | ||||||
|  |   "7c8bc6df", | ||||||
|  |   "46210507", | ||||||
|  |   "74faf83f", | ||||||
|  |   "703e109b", | ||||||
|  |   "4b96f62d", | ||||||
|  |   "449aeaa6" | ||||||
|  | ] | ||||||
|  | } | ||||||
| @ -0,0 +1,83 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, 0, 0, 0, -1 ], [ "Rest" ] ], 4 ], | ||||||
|  |     [ [ [ "Rest" ], [ 0, 1, 0, 1, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ "Rest" ] ], 2 ], | ||||||
|  |     [ [ [ "Rest" ], [ 0, 1, 0, 1, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 1, 0, 0, -1, -1 ] ], 1.875 ], | ||||||
|  |     [ [ [ -1, 1, 0, 1, 0, -1 ], [ 0, 1, 0, 1, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 1, 0, 0, -1, -1 ] ], 1.625 ], | ||||||
|  |     [ [ [ -1, 1, 0, 1, 0, -1 ], [ 0, 1, 0, 1, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 2, 0, 0, 0, -1 ] ], 1.75 ], | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ 0, 1, 0, 1, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 2, 0, 0, 0, -1 ] ], 1.875 ], | ||||||
|  |     [ [ [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 1, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 2, 0, 0, 0, -1 ] ], 0 ], | ||||||
|  |     [ [ [ -1, 1, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 2, 0, 0, 0, -1 ] ], 2 ], | ||||||
|  |     [ [ [ -1, 1, 0, 0, 0, 0 ], [ 2, 1, 0, -1, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 2, 0, 0, 0, -1 ] ], 1.375 ], | ||||||
|  |     [ [ [ 0, 1, -1, 0, 0, -1 ], [ 2, 1, 0, -1, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 2, 0, 0, 0, -1 ] ], 1 ], | ||||||
|  |     [ [ [ 0, 1, -1, 0, 0, -1 ], [ 2, 1, 0, 0, 0, -2 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 2, 0, 0, 0, -1 ] ], 7.375 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ 2, 1, 0, 0, 0, -2 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 2, 0, 0, 0, -1 ] ], 0 ], | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ 2, 1, 0, 0, 0, -2 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, -1 ] ], 5.375 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ "Rest" ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ "Rest" ], [ 0, 1, 0, 0, 0, -1 ], [ "Rest" ] ], 2 ], | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ "Rest" ], [ -1, 2, 1, 0, 0, -1 ], [ "Rest" ] ], 1.25 ], | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ "Rest" ], [ -1, 2, 0, 0, 1, -1 ], [ "Rest" ] ], 1.875 ], | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ "Rest" ], [ 0, 2, 0, 0, -1, -1 ], [ "Rest" ] ], 1.25 ], | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ "Rest" ], [ -1, 3, 0, 0, 0, -1 ], [ "Rest" ] ], 1.375 ], | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ "Rest" ], [ 0, 2, -1, 0, 0, -1 ], [ "Rest" ] ], 8.375 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ 2, 2, -1, 0, 0, -2 ], [ 0, 2, -1, 0, 0, -1 ], [ "Rest" ] ], 1.75 ], | ||||||
|  |     [ [ [ -1, 2, 0, 0, 0, -1 ], [ 2, 2, -1, 0, 0, -2 ], [ 0, 2, -1, 0, 0, -1 ], [ 1, 2, -1, 0, 0, -2 ] ], 0 ], | ||||||
|  |     [ [ [ -1, 2, -1, 0, 1, -1 ], [ 2, 2, -1, 0, 0, -2 ], [ 0, 2, -1, 0, 0, -1 ], [ 1, 2, -1, 0, 0, -2 ] ], 2 ], | ||||||
|  |     [ [ [ 0, 2, -1, 0, 0, -2 ], [ 2, 2, -1, 0, 0, -2 ], [ 0, 2, -1, 0, 0, -1 ], [ 1, 2, -1, 0, 0, -2 ] ], 1.5 ], | ||||||
|  |     [ [ [ 0, 2, -1, 0, 0, -2 ], [ 2, 2, -1, -1, 0, -1 ], [ 0, 2, -1, 0, 0, -1 ], [ 1, 2, -1, 0, 0, -2 ] ], 7 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ 0, 2, -1, 0, 0, -2 ], [ "Rest" ], [ 0, 2, -1, 0, 0, -1 ], [ 1, 2, -1, 0, 0, -2 ] ], 1.5 ], | ||||||
|  |     [ [ [ 0, 2, -1, 0, 0, -2 ], [ "Rest" ], [ 0, 2, -1, 0, 0, -1 ], [ "Rest" ] ], 1.25 ], | ||||||
|  |     [ [ [ 0, 2, -1, -1, 0, -1 ], [ "Rest" ], [ 0, 2, -1, 0, 0, -1 ], [ "Rest" ] ], 1.875 ], | ||||||
|  |     [ [ [ -1, 2, -1, 0, 0, -1 ], [ "Rest" ], [ 0, 2, -1, 0, 0, -1 ], [ "Rest" ] ], 1.5 ], | ||||||
|  |     [ [ [ -2, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 2, -1, 0, 0, -1 ], [ "Rest" ] ], 1 ], | ||||||
|  |     [ [ [ -1, 2, -2, 0, 0, -1 ], [ "Rest" ], [ 0, 2, -1, 0, 0, -1 ], [ "Rest" ] ], 1.375 ], | ||||||
|  |     [ [ [ -2, 2, -1, 1, 0, -1 ], [ "Rest" ], [ 0, 2, -1, 0, 0, -1 ], [ "Rest" ] ], 6.75 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 2, -1, 0, 0, -1 ], [ "Rest" ] ], 1.125 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 7.5 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 2, -1, -1, 0, -1 ], [ 2, 2, -1, -1, 0, -1 ], [ 0, 2, -1, 0, 0, -1 ], [ 1, 2, -1, 0, 0, -2 ] ], | ||||||
|  |   [ [ -1, 2, -1, 0, 0, -1 ], [ 2, 2, -1, -1, 0, -1 ], [ 0, 2, -1, 0, 0, -1 ], [ 1, 2, -1, 0, 0, -2 ] ], | ||||||
|  |   [ [ -2, 2, -1, 0, 0, 0 ], [ 2, 2, -1, -1, 0, -1 ], [ 0, 2, -1, 0, 0, -1 ], [ 1, 2, -1, 0, 0, -2 ] ], | ||||||
|  |   [ [ -1, 2, -2, 0, 0, -1 ], [ 2, 2, -1, -1, 0, -1 ], [ 0, 2, -1, 0, 0, -1 ], [ 1, 2, -1, 0, 0, -2 ] ], | ||||||
|  |   [ [ -2, 2, -1, 1, 0, -1 ], [ 2, 2, -1, -1, 0, -1 ], [ 0, 2, -1, 0, 0, -1 ], [ 1, 2, -1, 0, 0, -2 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "449aeaa6", | ||||||
|  | "ref_uid": "628d5c8b", | ||||||
|  | "order_seed": 338959, | ||||||
|  | "dur_seed": 810921, | ||||||
|  | "motifs_seed": 154723, | ||||||
|  | "entrances_probs_vals": [ 0.29, 0, 7.0238095238095, 0.77, 2.1703296703297, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0.29, 0, 7.0238095238095, 0.77, 2.1703296703297, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0.29, 0, 7.0238095238095, 0.77, 2.1703296703297, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ -3600, -349 ], [ 799, 1758 ], [ -282, 1013 ], [ -282, 799 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 2 ], [ 1, 3, 0, 3, 0, 0, 1, 1, 0, 1 ], [  ] ], | ||||||
|  |   [ [ 2 ], [ 0, 3, 1 ], [  ] ], | ||||||
|  |   [ [ 0 ], [ 2, 2, 2, 2, 2 ], [ 1, 3 ] ], | ||||||
|  |   [ [ 2 ], [ 1, 3, 0, 0, 1 ], [  ] ], | ||||||
|  |   [ [ 2 ], [ 0, 0, 0, 0, 0 ], [ 1, 3 ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.75, 0.34, 0 ], | ||||||
|  | "order_size": [ 2, 6 ], | ||||||
|  | "passages_size": [ 0, 10 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,907 @@ | |||||||
|  | ( | ||||||
|  | // helper funcs | ||||||
|  | var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; | ||||||
|  | 
 | ||||||
|  | // score funcs | ||||||
|  | var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; | ||||||
|  | 
 | ||||||
|  | // subroutines | ||||||
|  | var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; | ||||||
|  | 
 | ||||||
|  | // primary routines | ||||||
|  | var genMotif, genSecondarySeq; | ||||||
|  | 
 | ||||||
|  | // audition funcs | ||||||
|  | var genPatterns, genMidiPatterns; | ||||||
|  | 
 | ||||||
|  | // resource management funcs | ||||||
|  | var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, | ||||||
|  | msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON, | ||||||
|  | setGlobalVars, globalVarsToDict, saveLedger; | ||||||
|  | 
 | ||||||
|  | // model vars | ||||||
|  | //(model and global vars mostly set by OSC funcs | ||||||
|  | var seq, lastXChanges, | ||||||
|  | curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | motifEdited, orderEdited; | ||||||
|  | 
 | ||||||
|  | // model aux vars | ||||||
|  | var entrancesDurFunc, passagesDurFunc, exitsDurFunc; | ||||||
|  | 
 | ||||||
|  | // other global vars | ||||||
|  | var popSize, exPath, dir, primes, dims, tuples, | ||||||
|  | group, player, ledgerPath, ledger, currentlyPlayingUID, | ||||||
|  | nameSpaces; | ||||||
|  | 
 | ||||||
|  | // install JSON quark | ||||||
|  | if(Quarks.isInstalled("JSONlib").not, { | ||||||
|  | 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); | ||||||
|  | 	thisProcess.recompile; | ||||||
|  | 	//HelpBrowser.openHelpFor("Classes/JSONlib"); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------helper funcs | ||||||
|  | 
 | ||||||
|  | hsArrayToCents = { | ||||||
|  | 	arg hsArray; | ||||||
|  | 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pDist = { | ||||||
|  | 	arg array1, array2, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); | ||||||
|  | 	if(signed, {pDistance}, {abs(pDistance)}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hdSum = { | ||||||
|  | 	arg hsArrays; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays.size; | ||||||
|  | 	distances = (size - 1).collect({arg i; | ||||||
|  | 		((i + 1)..(size - 1)).collect({arg j; | ||||||
|  | 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsChordalDistance = { | ||||||
|  | 	arg hsArrays1, hsArrays2; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays1.size; | ||||||
|  | 	distances = hsArrays1.size.collect({arg i; | ||||||
|  | 		hsArrays2.size.collect({arg j; | ||||||
|  | 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsArrayToFreq = { | ||||||
|  | 	arg array; | ||||||
|  | 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------score funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | isInRange = { | ||||||
|  | 	arg hsArray, min, max; | ||||||
|  | 	var cents; | ||||||
|  | 	cents = hsArrayToCents.value(hsArray); | ||||||
|  | 	(cents >= min) && (cents <= max) | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | spacingScore = { | ||||||
|  | 	arg hsArrays, min; | ||||||
|  | 	var centsArray; | ||||||
|  | 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); | ||||||
|  | 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | rangeScore = { | ||||||
|  | 	arg hsArray1, hsArray2, min, max, low, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | intervalScore = { | ||||||
|  | 	arg hsArray1, hsArray2, mean, sd, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	pDistance.gaussCurve(1, mean, sd) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | inclusionScore = { | ||||||
|  | 	arg array, test, min = 0.01; | ||||||
|  | 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------subroutines | ||||||
|  | 
 | ||||||
|  | genTuples = { | ||||||
|  | 	var tuples; | ||||||
|  | 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); | ||||||
|  | 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | initVoices = { | ||||||
|  | 	var init, voicesInit; | ||||||
|  | 	voicesInit = popSize.collect({dims.collect({0})}); | ||||||
|  | 	/* | ||||||
|  | 	voicesInit = [dims.collect({0})]; | ||||||
|  | 	(popSize - 1).do({ | ||||||
|  | 		arg rep, new; | ||||||
|  | 		rep = dims.rand; | ||||||
|  | 		new = voicesInit.last.deepCopy; | ||||||
|  | 		new[rep] = new[rep] + [-1, 1].choose(); | ||||||
|  | 		voicesInit = voicesInit.add(new); | ||||||
|  | 	}); | ||||||
|  | 	*/ | ||||||
|  | 	voicesInit.deepCopy; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; | ||||||
|  | 	var env, pTable, durFunc; | ||||||
|  | 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; | ||||||
|  | 	pTable = env.asRandomTable; | ||||||
|  | 	[chordProb, minPad, maxPad, minDur, maxDur, envData].postln; | ||||||
|  | 	durFunc = {arg allowChord, pad = false; | ||||||
|  | 		var res; | ||||||
|  | 		res = if(allowChord.not, { | ||||||
|  | 			pTable.tableRand * (maxDur - minDur) + minDur | ||||||
|  | 		}, { | ||||||
|  | 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (maxDur - minDur) + minDur}); | ||||||
|  | 		}).round(0.125); | ||||||
|  | 		if(pad, {res = res + rrand(minPad.asFloat, maxPad.asFloat).round(0.125)}); | ||||||
|  | 		if(res.asInteger == res, {res = res.asInteger}); | ||||||
|  | 		res | ||||||
|  | 	}; | ||||||
|  | 	seedFunc.value(durFunc, seed); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; | ||||||
|  | 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ | ||||||
|  | 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; | ||||||
|  | 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); | ||||||
|  | 		noProgIns = (popSize - noSusIns).rand + 1; | ||||||
|  | 		noSilentIns = popSize - noSusIns - noProgIns; | ||||||
|  | 
 | ||||||
|  | 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); | ||||||
|  | 
 | ||||||
|  | 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); | ||||||
|  | 		if(silent == nil, {silent = []}); | ||||||
|  | 		[sus.scramble, prog, silent.scramble] | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | updateVoices = {arg ins, sus; | ||||||
|  | 	var voices, candidates, nWeights, nProbs, sel; | ||||||
|  | 
 | ||||||
|  | 	voices = lastXChanges.deepCopy.last; | ||||||
|  | 
 | ||||||
|  | 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; | ||||||
|  | 	candidates = difference(candidates.asSet, voices.asSet).asList; | ||||||
|  | 	nProbs = candidates.collect({arg candidate; | ||||||
|  | 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; | ||||||
|  | 
 | ||||||
|  | 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); | ||||||
|  | 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); | ||||||
|  | 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); | ||||||
|  | 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); | ||||||
|  | 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); | ||||||
|  | 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); | ||||||
|  | 		//maybe what you want here is a vector to another root and then favoring movement towards it. | ||||||
|  | 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); | ||||||
|  | 
 | ||||||
|  | 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	nWeights = passagesWeights; | ||||||
|  | 
 | ||||||
|  | 	//this handles nWeights of 0; mainly for testing | ||||||
|  | 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; | ||||||
|  | 	nWeights = nWeights.select({arg weight; weight != 0}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; | ||||||
|  | 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) | ||||||
|  | 	}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; | ||||||
|  | 
 | ||||||
|  | 	sel = candidates.wchoose(nProbs); | ||||||
|  | 
 | ||||||
|  | 	voices[ins] = sel; | ||||||
|  | 	lastXChanges = lastXChanges.add(voices).keep(-5); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; | ||||||
|  | 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, pad, lastXChangesHold, voices, adder; | ||||||
|  | 	# sus, prog, silent = order; | ||||||
|  | 	flatOrder = silent ++ sus ++ prog; | ||||||
|  | 	lastXChangesHold = lastXChanges.deepCopy; | ||||||
|  | 	voices = lastState.deepCopy; | ||||||
|  | 	isInChord = popSize.collect({false}); | ||||||
|  | 	allowChord = false; | ||||||
|  | 	pad = false; | ||||||
|  | 	res = []; | ||||||
|  | 	"------generating motif".postln; | ||||||
|  | 	//need to figure out here if voices move between motifs | ||||||
|  | 	flatOrder.do({arg ins, i; | ||||||
|  | 
 | ||||||
|  | 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); | ||||||
|  | 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); | ||||||
|  | 
 | ||||||
|  | 		if(voices[ins] != adder, { | ||||||
|  | 			var dur; | ||||||
|  | 
 | ||||||
|  | 			if((sus ++ silent).includes(ins), { | ||||||
|  | 				allowChord = (ins != sus.last); | ||||||
|  | 				pad = (ins == sus.last); | ||||||
|  | 			}, { | ||||||
|  | 				if(i < (flatOrder.size - 1), { | ||||||
|  | 					allowChord = (isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not; | ||||||
|  | 					pad = false; | ||||||
|  | 				}, { | ||||||
|  | 					allowChord = false; | ||||||
|  | 					pad = true | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if((orderIndex == 0) && sus.includes(ins), { | ||||||
|  | 				dur = entrancesDurFunc.value(allowChord, pad); | ||||||
|  | 			}, { | ||||||
|  | 				dur = passagesDurFunc.value(allowChord, pad); | ||||||
|  | 			}); | ||||||
|  | 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); | ||||||
|  | 
 | ||||||
|  | 			voices[ins] = adder; | ||||||
|  | 			res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// pad ending | ||||||
|  | 	if(orderIndex == (orders.size - 1), { | ||||||
|  | 		(0..(popSize-1)).scramble.do({arg ins; | ||||||
|  | 			if(res.last.first[ins] != ["Rest"], { | ||||||
|  | 				var dur; | ||||||
|  | 				voices[ins] = ["Rest"]; | ||||||
|  | 				allowChord = (voices != popSize.collect({["Rest"]})); | ||||||
|  | 				pad = allowChord.not; | ||||||
|  | 				dur = exitsDurFunc.value(allowChord, pad); | ||||||
|  | 				res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	//format and return | ||||||
|  | 	if(startFromLast, {lastXChanges = lastXChangesHold.deepCopy}); | ||||||
|  | 	res; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------primary routines | ||||||
|  | 
 | ||||||
|  | genMotif = { | ||||||
|  | 	var repeats, fSeq; | ||||||
|  | 
 | ||||||
|  | 	repeats = 1; | ||||||
|  | 	fSeq = []; | ||||||
|  | 
 | ||||||
|  | 	repeats.do({arg index; | ||||||
|  | 		var motif; | ||||||
|  | 
 | ||||||
|  | 		motif = []; | ||||||
|  | 
 | ||||||
|  | 		orders.do({arg order, o; | ||||||
|  | 			var lastState, subMotif; | ||||||
|  | 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); | ||||||
|  | 			subMotif = genSubMotif.value(order, o, lastState, isLastOrder: o == (orders.size - 1)); | ||||||
|  | 			motif = motif.add(subMotif); | ||||||
|  | 
 | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		sanityCheck.value(motif, index); | ||||||
|  | 
 | ||||||
|  | 		fSeq = fSeq.add(motif); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSecondarySeq = {arg seq; | ||||||
|  | 	var curdles, fSeq; | ||||||
|  | 	curdles = []; | ||||||
|  | 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); | ||||||
|  | 
 | ||||||
|  | 	fSeq = seq.clumps(curdles).collect({arg clump, m; | ||||||
|  | 		var repeats, paddedSeq; | ||||||
|  | 
 | ||||||
|  | 		//add rest | ||||||
|  | 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); | ||||||
|  | 
 | ||||||
|  | 		//implement repeats | ||||||
|  | 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); | ||||||
|  | 		repeats.collect({paddedSeq}); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------audition funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~addr.sendMsg(~indexPath, ~indexMsg); | ||||||
|  | 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); | ||||||
|  | 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~msg.postln; | ||||||
|  | 		~addr.sendMsg(~path, *~msg); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | genPatterns = {arg inSeq, addr, oneShot = false; | ||||||
|  | 	var voices, durs, pbinds, res, indices, sectionDurs, msg, ids, seq; | ||||||
|  | 	seq = inSeq.collect({arg mSeq; mSeq[0]}); | ||||||
|  | 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	pbinds = voices.flop.collect({arg voice, v; | ||||||
|  | 		var clumps, hdScores, freqs, fDurs, attacks, rels, amps; | ||||||
|  | 		clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 		freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 		fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 		//attacks = 2.collect({rrand(1, 3)}) ++ freqs.drop(2).collect({rrand(0.3, 0.5)}); | ||||||
|  | 		attacks = fDurs.collect({arg dur; dur * rrand(0.2, 0.4)}); | ||||||
|  | 		//rels = freqs.drop(2).collect({rrand(0.3, 0.5)}) ++ 2.collect({rrand(1, 3)}); | ||||||
|  | 		rels = (clumps.size - 1).collect({arg c; | ||||||
|  | 			if(clumps[c + 1][0] == ["Rest"], {rrand(1, 3)}, {rrand(0.3, 0.5)}); | ||||||
|  | 		}); | ||||||
|  | 		amps = freqs.collect({rrand(0.6, 0.99)}); | ||||||
|  | 
 | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \string_model, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\attack, Pseq(attacks, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\release, Pseq(rels, 1), | ||||||
|  | 				//\amp, Pseq(amps, 1), | ||||||
|  | 				\amp, Pbrown(0.5, 1, 0.5), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			), | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \sine, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	}).flatten; | ||||||
|  | 	if(oneShot.not, { | ||||||
|  | 		msg = inSeq.collect({arg mSeq, m; mSeq[1..]}); | ||||||
|  | 		//ids = inSeq.collect({arg mSeq, m; mSeq[2]}); | ||||||
|  | 		sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); | ||||||
|  | 		pbinds = pbinds ++ | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \osc, | ||||||
|  | 				\addr, addr, | ||||||
|  | 				\path, "/playing", | ||||||
|  | 				\msg, Pseq(msg, 1), | ||||||
|  | 				\dur, Pseq(sectionDurs, 1) | ||||||
|  | 			); | ||||||
|  | 		] | ||||||
|  | 	}); | ||||||
|  | 	res = Ppar(pbinds); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | genMidiPatterns = {arg seq; | ||||||
|  | 	var voices, durs, patterns, res, mOut, pbRange; | ||||||
|  | 	pbRange = 1; //semitones - change this as needed for your situation | ||||||
|  | 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); | ||||||
|  | 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	res = Ppar( | ||||||
|  | 		voices.flop.collect({arg voice, v; | ||||||
|  | 			var clumps, hdScores, freqs, fDurs; | ||||||
|  | 
 | ||||||
|  | 			mOut.program(v, 70); | ||||||
|  | 
 | ||||||
|  | 			clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \midi, | ||||||
|  | 				\chan, v, | ||||||
|  | 				\noteval, Pseq(freqs.cpsmidi - 24, 1), | ||||||
|  | 				\note, Pfunc({ | event | event[\noteval].floor }), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\midiout, mOut, | ||||||
|  | 				\amp, 1, | ||||||
|  | 				\bend, Pfunc({ | ||||||
|  | 					| event | | ||||||
|  | 					if (event[\note].isRest.not) { | ||||||
|  | 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; | ||||||
|  | 						m.bend(v, pitchbendvalue); | ||||||
|  | 					}; | ||||||
|  | 					0; // return something other than nil to avoid stopping the pattern | ||||||
|  | 				}), | ||||||
|  | 			); | ||||||
|  | 		}); | ||||||
|  | 	); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------resource management funcs | ||||||
|  | 
 | ||||||
|  | genUID = {Date.seed.asHexString.toLower}; | ||||||
|  | 
 | ||||||
|  | seedFunc = {arg func, seed; | ||||||
|  | 	var funcArgs, next; | ||||||
|  | 	next = Routine({loop{func.valueArray(funcArgs).yield }}); | ||||||
|  | 	next.randSeed_(seed); | ||||||
|  | 	{arg ...args; funcArgs = args; next.value} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | stringifyToDepth = {arg data, maxDepth = 1; | ||||||
|  | 	var prettyString = "", rCount = 0, writeArray, indent; | ||||||
|  | 
 | ||||||
|  | 	if(maxDepth == 0, { | ||||||
|  | 		data.asCompileString | ||||||
|  | 	}, { | ||||||
|  | 		indent = {arg size; size.collect({" "}).join("")}; | ||||||
|  | 		writeArray = {arg array; | ||||||
|  | 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; | ||||||
|  | 			rCount = rCount + 1; | ||||||
|  | 			if(rCount < maxDepth, { | ||||||
|  | 				array.do({arg subArray; writeArray.value(subArray)}); | ||||||
|  | 			}, { | ||||||
|  | 				prettyString = prettyString ++ array.collect({arg subArray; | ||||||
|  | 					indent.value(rCount + 1) ++ subArray.asCompileString | ||||||
|  | 				}).join(",\n"); | ||||||
|  | 			}); | ||||||
|  | 			rCount = rCount - 1; | ||||||
|  | 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		writeArray.value(data); | ||||||
|  | 		prettyString.replace(",\n\n", "\n").drop(-2); | ||||||
|  | 	}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | sanityCheck = {arg motif, index; | ||||||
|  | 	//print functions = very helpful | ||||||
|  | 	("----------" + index + "------------").postln; | ||||||
|  | 
 | ||||||
|  | 	motif.flatten.do({arg val, v; | ||||||
|  | 		if(v > 0, { | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); | ||||||
|  | 		}); | ||||||
|  | 		val.postln | ||||||
|  | 	}); | ||||||
|  | 	"***********".postln; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; | ||||||
|  | 	var res; | ||||||
|  | 
 | ||||||
|  | 	res = in; | ||||||
|  | 	if(res.isNil.not, { | ||||||
|  | 		if((res.isArray && res.isString.not), { | ||||||
|  | 			res = res.asCompileString; | ||||||
|  | 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); | ||||||
|  | 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); | ||||||
|  | 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); | ||||||
|  | 			res = res.replace("Rest", "\"Rest\""); | ||||||
|  | 			res = res.interpret; | ||||||
|  | 		}, { | ||||||
|  | 			//res.postln; | ||||||
|  | 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | writeResources = {arg path, dict; | ||||||
|  | 	var file, modelItems, resString; | ||||||
|  | 	file = File(path,"w"); | ||||||
|  | 
 | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	resString = nameSpaces.collect({arg nameSpace; | ||||||
|  | 		var depth = 0, insert = " "; | ||||||
|  | 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "order", {depth = 1; insert = "\n"}); | ||||||
|  | 		if((nameSpace == "ref_uid") && (dict[nameSpace] == nil), {dict[nameSpace] = "nil"}); | ||||||
|  | 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(dict[nameSpace], depth) | ||||||
|  | 	}).join(",\n"); | ||||||
|  | 
 | ||||||
|  | 	resString = "{\n" ++ resString ++ "\n}"; | ||||||
|  | 
 | ||||||
|  | 	file.write(resString); | ||||||
|  | 	file.close; | ||||||
|  | 	resString | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; | ||||||
|  | 
 | ||||||
|  | loadModelJSON = {arg jsonObject; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS; nS->msgInterpret.value(jsonObject[nS])})); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | setGlobalVars = {arg dict, skipLastXChanges = false; | ||||||
|  | 	var tmpLastXChanges; | ||||||
|  | 	tmpLastXChanges = lastXChanges.deepCopy; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	# seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 	entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 	motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); | ||||||
|  | 	if(skipLastXChanges, {lastXChanges = tmpLastXChanges}); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | globalVarsToDict = { | ||||||
|  | 	var modelItems, dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerFile = {arg path; | ||||||
|  | 	ledgerPath = path; | ||||||
|  | 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; | ||||||
|  | 
 | ||||||
|  | saveLedger = {arg ledger, path; | ||||||
|  | 	var file; | ||||||
|  | 	file = File(path, "w"); | ||||||
|  | 	file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); | ||||||
|  | 	file.close; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------global vars | ||||||
|  | 
 | ||||||
|  | primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; | ||||||
|  | //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; | ||||||
|  | exPath = thisProcess.nowExecutingPath; | ||||||
|  | dir = exPath.dirname; | ||||||
|  | //popSize = 4; | ||||||
|  | dims = primes.size; | ||||||
|  | tuples = genTuples.value(); | ||||||
|  | //refUID = nil; | ||||||
|  | group = Group.new; | ||||||
|  | ~group = group; | ||||||
|  | loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); | ||||||
|  | //passagesWeights = [1, 1, 1, 1, 1]; | ||||||
|  | //susWeights = [1, 1, 1]; | ||||||
|  | // order really matters!!!! | ||||||
|  | nameSpaces = [ | ||||||
|  | 	"music_data", "last_changes", "cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", | ||||||
|  | 	"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", | ||||||
|  | 	"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", | ||||||
|  | 	"motif_edited", "order_edited" | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------OSC funcs | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_ledger, {arg msg, time, addr, port; | ||||||
|  | 	loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \load_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_model, {arg msg, time, addr, port; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = loadModelFile.value(msg[1].asString); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | }, \load_model); | ||||||
|  | 
 | ||||||
|  | OSCdef(\save_ledger, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	ledger = msgInterpret.value(msg[1].asString.parseJSON["ledger"], false).postln; | ||||||
|  | 	//loadLedgerJSON.value(msg[0]) | ||||||
|  | 	saveLedger.value(ledger, msg[2].asString); | ||||||
|  | 	//loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \save_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\generate, {arg msg, time, addr, port; | ||||||
|  | 	var path, dict, durSeeds, musPath, modelString; | ||||||
|  | 	msg.postln; | ||||||
|  | 
 | ||||||
|  | 	path = msg[1].asString; | ||||||
|  | 
 | ||||||
|  | 	dict = loadModelFile.value(path); | ||||||
|  | 	setGlobalVars.value(dict, true); | ||||||
|  | 
 | ||||||
|  | 	popSize = ranges.size; | ||||||
|  | 
 | ||||||
|  | 	//refUID.postln; | ||||||
|  | 
 | ||||||
|  | 	loadLedgerFile.value(ledgerPath); | ||||||
|  | 	if(ledger == nil, {ledger = ["tmp"]}); | ||||||
|  | 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); | ||||||
|  | 
 | ||||||
|  | 	if(refUID == nil, {lastXChanges = [initVoices.value().deepCopy]}); | ||||||
|  | 	if((refUID != nil) && (refUID != "tmp"), { | ||||||
|  | 		var file; | ||||||
|  | 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); | ||||||
|  | 		lastXChanges = msgInterpret.value(file.readAllString.parseJSON["last_changes"]); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	refUID.postln; | ||||||
|  | 	lastXChanges.collect({arg item; item.postln}); | ||||||
|  | 
 | ||||||
|  | 	durSeeds = seedFunc.value({3.collect({rrand(100000, 999999)})}, durSeed).value.postln; | ||||||
|  | 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..4] ++ [entrancesProbVals[5..]] ++ [durSeeds[0]]); | ||||||
|  | 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..4] ++ [passagesProbVals[5..]] ++ [durSeeds[1]]); | ||||||
|  | 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..4] ++ [exitsProbVals[5..]] ++ [durSeeds[2]]); | ||||||
|  | 
 | ||||||
|  | 	if(orders == nil, { | ||||||
|  | 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); | ||||||
|  | 		//addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); | ||||||
|  | 	}); | ||||||
|  | 	seq = seedFunc.value(genMotif, motifSeed).value; | ||||||
|  | 
 | ||||||
|  | 	lastXChanges.collect({arg item; item.postln}); | ||||||
|  | 
 | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	modelString = writeResources.value(path, dict); | ||||||
|  | 
 | ||||||
|  | 	//addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); | ||||||
|  | 	addr.sendMsg("/generated", path, modelString, ledgerPath); | ||||||
|  | }, \generate); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | OSCdef(\commit, {arg msg, time, addr, port; | ||||||
|  | 	var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; | ||||||
|  | 	//msg.postln; | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	test1 = msg[1].asString.parseJSON; | ||||||
|  | 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; | ||||||
|  | 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; | ||||||
|  | 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; | ||||||
|  | 	(test1["music"] == test2["music_data"]).postln; | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; | ||||||
|  | 	musicChanged = (musicData != seq).postln; | ||||||
|  | 
 | ||||||
|  | 	curUID = genUID.value; | ||||||
|  | 
 | ||||||
|  | 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); | ||||||
|  | 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); | ||||||
|  | 
 | ||||||
|  | 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	if(musicChanged, { | ||||||
|  | 		seq = musicData; | ||||||
|  | 		dict["music_data"] = seq; | ||||||
|  | 		dict["motif_edited"] = "true" | ||||||
|  | 	}); | ||||||
|  | 	dict["cur_uid"] = curUID; | ||||||
|  | 
 | ||||||
|  | 	writeResources.value(modelPath, dict); | ||||||
|  | 
 | ||||||
|  | 	File.delete(ledgerPath ++ "_bak"); | ||||||
|  | 	File.copy(ledgerPath, ledgerPath ++ "_bak"); | ||||||
|  | 	File.delete(ledgerPath); | ||||||
|  | 	ledger = ledger.drop(-1).add(curUID); | ||||||
|  | 
 | ||||||
|  | 	saveLedger.value(ledger, ledgerPath); | ||||||
|  | 
 | ||||||
|  | 	addr.sendMsg("/committed", curUID, ledgerPath); | ||||||
|  | 	//refUID = curUID; | ||||||
|  | 
 | ||||||
|  | }, \commit); | ||||||
|  | 
 | ||||||
|  | OSCdef(\transport, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	if(msg[1] == 0, { | ||||||
|  | 		group.set(\release, 2); | ||||||
|  | 		group.set(\gate, 0); | ||||||
|  | 		player.stop; | ||||||
|  | 	}, { | ||||||
|  | 		// the cued sequence can now be read from file, so this can be cleaned up | ||||||
|  | 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; | ||||||
|  | 		if(msg[1] == 1, { | ||||||
|  | 			pSeq = []; | ||||||
|  | 			cuedSeek = (seq != nil); | ||||||
|  | 			indexStart = msg[2].asInteger; | ||||||
|  | 			indexEnd = ledger.size - if(cuedSeek, {2}, {1}); | ||||||
|  | 			//ledger.postln; | ||||||
|  | 			if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { | ||||||
|  | 				ledger[indexStart..indexEnd].do({arg uid, index; | ||||||
|  | 					var path, file; | ||||||
|  | 					path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 					file = File(path, "r"); | ||||||
|  | 					pSeq = pSeq.add([msgInterpret.value(file.readAllString.postln.parseJSON["music_data"]), path, indexStart + index, uid]); | ||||||
|  | 					file.close; | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if(cuedSeek, { | ||||||
|  | 				var path, file; | ||||||
|  | 				path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; | ||||||
|  | 				file = File(path, "r"); | ||||||
|  | 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, ledger.size - 1, "tmp"]); | ||||||
|  | 				file.close; | ||||||
|  | 			}); | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr); | ||||||
|  | 		}, { | ||||||
|  | 			pSeq = [loadModelJSON.value(msg[2].asString.parseJSON)["music_data"].postln]; | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr, true); | ||||||
|  | 		}); | ||||||
|  | 		player = Pfset(pattern: patterns, cleanupFunc: { | ||||||
|  | 			addr.sendMsg("/transport", 0); | ||||||
|  | 			addr.sendMsg("/one_shot", 0); | ||||||
|  | 		}); | ||||||
|  | 		player = player.play | ||||||
|  | 	}); | ||||||
|  | }, \transport); | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | //synthdefs | ||||||
|  | ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sineBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~bassBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~hdustBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~samplerBusArray = 2.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sBuf = Buffer.alloc(s, 10, 2); | ||||||
|  | SynthDef(\string_model, {arg freq, gate = 1, sustain, amp, dur, attack, release = 1, busIndex = 0; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~stringModelBusArray), sig1 * amp * EnvGen.kr(Env.adsr(attack, 0.3, 0.9, release, 0.9, -3), gate, doneAction: 2)); | ||||||
|  | 	//Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var sig; | ||||||
|  | 	sig = SinOsc.ar(freq); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.asr(0.3, 0.4, 0.3), gate, timeScale: dur, doneAction: 2)); | ||||||
|  | 	//Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.sine(dur), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; | ||||||
|  | 	var nameSpaces, sigs, hierarchicalDust; | ||||||
|  | 
 | ||||||
|  | 	hierarchicalDust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	sigs = [~stringModelBusArray, ~sineBusArray, ~bassBusArray, ~hdustBusArray, ~samplerBusArray].collect({arg busArray, i; | ||||||
|  | 		var nameSpace, sig; | ||||||
|  | 		nameSpace = ['string', 'sine', 'bass', 'hdust', 'sampler'][i]; | ||||||
|  | 		sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = Mix.ar(sig) * pow(NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.1), 2); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	sigs = Mix.ar(sigs / 4); | ||||||
|  | 	Out.ar(0, sigs) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\bass, { | ||||||
|  | 	var switches, drone; | ||||||
|  | 	switches = {|i| Dust.kr(0.1)} ! 9; | ||||||
|  | 	drone = {|i| var harm = pow(2, 2 - (i / 3).trunc), amp = (1 / pow(harm, 2)); | ||||||
|  | 		SinOsc.ar(60 * harm + TRand.kr(-3, 3, switches[i]), 0, amp)} ! 9; | ||||||
|  | 	Out.ar(~bassBusArray[0], Mix.new(drone) * 0.2); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sampler, { | ||||||
|  | 	Out.ar(~samplerBusArray, PlayBuf.ar(2, ~sBuf, BufRateScale.kr(~sBuf), doneAction: 2)) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | // main routine | ||||||
|  | SynthDef(\hdust, { | ||||||
|  | 	arg gate = 0; | ||||||
|  | 	var hierarchical_dust, low_sine, high_sine, brown_noise, white_noise; | ||||||
|  | 	// this triggers the combinations of sources | ||||||
|  | 	// it is similar to the Supercollider UGen called dust but with a hierarchical structure | ||||||
|  | 	hierarchical_dust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(0.1)) | ||||||
|  | 	); | ||||||
|  | 	// adjust the multiplier at the end of each line for adjusting levels | ||||||
|  | 	// note with each trigger, each source has a 1 in 3 chance of sounding | ||||||
|  | 	low_sine = SinOsc.ar(76.midicps / 16) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.1; | ||||||
|  | 	high_sine = SinOsc.ar(76.midicps * 8) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.01; | ||||||
|  | 	brown_noise = BrownNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.025; | ||||||
|  | 	white_noise = WhiteNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.02; | ||||||
|  | 	Out.ar(~hdustBusArray[0], | ||||||
|  | 		((low_sine + high_sine + brown_noise + white_noise) ) | ||||||
|  | 	); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | var bass, hdust, sampler, mixer; | ||||||
|  | bass = Synth.tail(~group, \bass); | ||||||
|  | hdust = Synth.tail(~group, \hdust); | ||||||
|  | sampler = Synth.head(~group, \sampler); | ||||||
|  | mixer = Synth.tail(~group, \mixer); | ||||||
|  | OSCdef(\mixer, {arg msg, time, addr, port; | ||||||
|  | 	mixer.set((msg[1] ++ '_' ++ msg[2] ++ '_' ++ msg[3]), msg[4]) | ||||||
|  | }, \mixer); | ||||||
|  | 
 | ||||||
|  | OSCdef(\sampler, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	sampler.free; | ||||||
|  | 	~sBuf.free; | ||||||
|  | 	~sBuf = Buffer.read(s, msg[1].asString.postln, action: {sampler = Synth.head(~group, \sampler)}); | ||||||
|  | }, \sampler); | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /* old something | ||||||
|  | ( | ||||||
|  | SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	freq = WhiteNoise.ar * 3 + freq; | ||||||
|  | 	freqFinal = Duty.ar((1/freq), 0, freq); | ||||||
|  | 	trig = Changed.ar(freqFinal); | ||||||
|  | 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); | ||||||
|  | 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); | ||||||
|  | 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 
 | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | ) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| @ -0,0 +1,59 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 2.375 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 1.625 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 1.125 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 3 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 3.125 ], | ||||||
|  |     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1.125 ], | ||||||
|  |     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ] ], 1.25 ], | ||||||
|  |     [ [ [ -1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ] ], 1.375 ], | ||||||
|  |     [ [ [ -1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 1.5 ], | ||||||
|  |     [ [ [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0.875 ], | ||||||
|  |     [ [ [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 2 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ] ], 1 ], | ||||||
|  |     [ [ [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ "Rest" ] ], 1.375 ], | ||||||
|  |     [ [ [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ] ], 1.75 ], | ||||||
|  |     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ] ], 1.375 ], | ||||||
|  |     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1.625 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.375 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ -1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], | ||||||
|  |   [ [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], | ||||||
|  |   [ [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], | ||||||
|  |   [ [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], | ||||||
|  |   [ [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, -1, 0, 0, 0 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "46210507", | ||||||
|  | "ref_uid": "nil", | ||||||
|  | "order_seed": 944186, | ||||||
|  | "dur_seed": 424778, | ||||||
|  | "motifs_seed": 515266, | ||||||
|  | "entrances_probs_vals": [ 0, 0.48, 1.7460317460317, 0.58, 1.68, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0, 0.48, 1.7460317460317, 0.58, 1.68, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0, 0.48, 1.7460317460317, 0.58, 1.68, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ -3600, -627.86377708978 ], [ -3600, 260 ], [ -980.80495356037, 2066 ], [ -627.86377708978, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 2 ], [ 3, 3, 3 ], [ 0, 1 ] ], | ||||||
|  |   [ [ 1 ], [ 2, 3, 0, 3, 0, 0 ], [  ] ], | ||||||
|  |   [ [ 0, 1 ], [ 2, 2 ], [ 3 ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.73, 0.49, 0 ], | ||||||
|  | "order_size": [ 1, 7 ], | ||||||
|  | "passages_size": [ 0, 5 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,48 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 7, -7, -4, 0, -1, -2 ], [ "Rest" ] ], 2.25 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 7, -7, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 3.875 ], | ||||||
|  |     [ [ [ 8, -7, -4, 1, -1, -2 ], [ "Rest" ], [ 7, -7, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 1.125 ], | ||||||
|  |     [ [ [ 8, -7, -4, 1, -1, -2 ], [ 7, -8, -4, 0, -1, -2 ], [ 7, -7, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 6.5 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ 8, -7, -4, 1, -1, -2 ], [ "Rest" ], [ 7, -7, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 2 ], | ||||||
|  |     [ [ [ 8, -7, -4, 1, -1, -2 ], [ "Rest" ], [ 6, -7, -3, 1, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 7.125 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 6, -7, -3, 1, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 0 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 6, -7, -3, 1, -1, -2 ], [ "Rest" ] ], 1.625 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 5.5 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ 8, -6, -4, 0, -1, -2 ], [ 6, -5, -4, 0, -1, -3 ], [ 6, -5, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], | ||||||
|  |   [ [ 8, -6, -4, 0, -1, -2 ], [ 6, -5, -4, 0, -1, -3 ], [ 7, -7, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], | ||||||
|  |   [ [ 8, -7, -4, 1, -1, -2 ], [ 6, -5, -4, 0, -1, -3 ], [ 7, -7, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], | ||||||
|  |   [ [ 8, -7, -4, 1, -1, -2 ], [ 7, -8, -4, 0, -1, -2 ], [ 7, -7, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], | ||||||
|  |   [ [ 8, -7, -4, 1, -1, -2 ], [ 7, -8, -4, 0, -1, -2 ], [ 6, -7, -3, 1, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "4b96f62d", | ||||||
|  | "ref_uid": "703e109b", | ||||||
|  | "order_seed": 550421, | ||||||
|  | "dur_seed": 808010, | ||||||
|  | "motifs_seed": 180604, | ||||||
|  | "entrances_probs_vals": [ 0.52, 0.56, 5.1984126984127, 0.76923076923077, 2.31, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0.52, 0.56, 5.1984126984127, 0.76923076923077, 2.31, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0.52, 0.56, 5.1984126984127, 0.76923076923077, 2.31, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ 1211.1455108359, 2400 ], [ -1650, 450 ], [ -405, 1137 ], [ 951.08359133127, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 2, 3 ], [ 0, 1 ], [  ] ], | ||||||
|  |   [ [ 3, 0 ], [ 2 ], [ 1 ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.73, 0.49, 0 ], | ||||||
|  | "order_size": [ 1, 3 ], | ||||||
|  | "passages_size": [ 0, 0 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,887 @@ | |||||||
|  | ( | ||||||
|  | // helper funcs | ||||||
|  | var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; | ||||||
|  | 
 | ||||||
|  | // score funcs | ||||||
|  | var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; | ||||||
|  | 
 | ||||||
|  | // subroutines | ||||||
|  | var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; | ||||||
|  | 
 | ||||||
|  | // primary routines | ||||||
|  | var genMotif, genSecondarySeq; | ||||||
|  | 
 | ||||||
|  | // audition funcs | ||||||
|  | var genPatterns, genMidiPatterns; | ||||||
|  | 
 | ||||||
|  | // resource management funcs | ||||||
|  | var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, | ||||||
|  | msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON, | ||||||
|  | setGlobalVars, globalVarsToDict, saveLedger; | ||||||
|  | 
 | ||||||
|  | // model vars | ||||||
|  | //(model and global vars mostly set by OSC funcs | ||||||
|  | var seq, lastXChanges, | ||||||
|  | curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | motifEdited, orderEdited; | ||||||
|  | 
 | ||||||
|  | // model aux vars | ||||||
|  | var entrancesDurFunc, passagesDurFunc, exitsDurFunc; | ||||||
|  | 
 | ||||||
|  | // other global vars | ||||||
|  | var popSize, exPath, dir, primes, dims, tuples, | ||||||
|  | group, player, ledgerPath, ledger, currentlyPlayingUID, | ||||||
|  | nameSpaces; | ||||||
|  | 
 | ||||||
|  | // install JSON quark | ||||||
|  | if(Quarks.isInstalled("JSONlib").not, { | ||||||
|  | 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); | ||||||
|  | 	thisProcess.recompile; | ||||||
|  | 	//HelpBrowser.openHelpFor("Classes/JSONlib"); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------helper funcs | ||||||
|  | 
 | ||||||
|  | hsArrayToCents = { | ||||||
|  | 	arg hsArray; | ||||||
|  | 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pDist = { | ||||||
|  | 	arg array1, array2, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); | ||||||
|  | 	if(signed, {pDistance}, {abs(pDistance)}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hdSum = { | ||||||
|  | 	arg hsArrays; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays.size; | ||||||
|  | 	distances = (size - 1).collect({arg i; | ||||||
|  | 		((i + 1)..(size - 1)).collect({arg j; | ||||||
|  | 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsChordalDistance = { | ||||||
|  | 	arg hsArrays1, hsArrays2; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays1.size; | ||||||
|  | 	distances = hsArrays1.size.collect({arg i; | ||||||
|  | 		hsArrays2.size.collect({arg j; | ||||||
|  | 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsArrayToFreq = { | ||||||
|  | 	arg array; | ||||||
|  | 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------score funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | isInRange = { | ||||||
|  | 	arg hsArray, min, max; | ||||||
|  | 	var cents; | ||||||
|  | 	cents = hsArrayToCents.value(hsArray); | ||||||
|  | 	(cents >= min) && (cents <= max) | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | spacingScore = { | ||||||
|  | 	arg hsArrays, min; | ||||||
|  | 	var centsArray; | ||||||
|  | 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); | ||||||
|  | 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | rangeScore = { | ||||||
|  | 	arg hsArray1, hsArray2, min, max, low, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | intervalScore = { | ||||||
|  | 	arg hsArray1, hsArray2, mean, sd, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	pDistance.gaussCurve(1, mean, sd) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | inclusionScore = { | ||||||
|  | 	arg array, test, min = 0.01; | ||||||
|  | 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------subroutines | ||||||
|  | 
 | ||||||
|  | genTuples = { | ||||||
|  | 	var tuples; | ||||||
|  | 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); | ||||||
|  | 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | initVoices = { | ||||||
|  | 	var init, voicesInit; | ||||||
|  | 	voicesInit = popSize.collect({dims.collect({0})}); | ||||||
|  | 	/* | ||||||
|  | 	voicesInit = [dims.collect({0})]; | ||||||
|  | 	(popSize - 1).do({ | ||||||
|  | 		arg rep, new; | ||||||
|  | 		rep = dims.rand; | ||||||
|  | 		new = voicesInit.last.deepCopy; | ||||||
|  | 		new[rep] = new[rep] + [-1, 1].choose(); | ||||||
|  | 		voicesInit = voicesInit.add(new); | ||||||
|  | 	}); | ||||||
|  | 	*/ | ||||||
|  | 	voicesInit.deepCopy; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; | ||||||
|  | 	var env, pTable, durFunc; | ||||||
|  | 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; | ||||||
|  | 	pTable = env.asRandomTable; | ||||||
|  | 	[chordProb, minPad, maxPad, minDur, maxDur, envData].postln; | ||||||
|  | 	durFunc = {arg allowChord, pad = false; | ||||||
|  | 		var res; | ||||||
|  | 		res = if(allowChord.not, { | ||||||
|  | 			pTable.tableRand * (maxDur - minDur) + minDur | ||||||
|  | 		}, { | ||||||
|  | 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (maxDur - minDur) + minDur}); | ||||||
|  | 		}).round(0.125); | ||||||
|  | 		if(pad, {res = res + rrand(minPad.asFloat, maxPad.asFloat).round(0.125)}); | ||||||
|  | 		if(res.asInteger == res, {res = res.asInteger}); | ||||||
|  | 		res | ||||||
|  | 	}; | ||||||
|  | 	seedFunc.value(durFunc, seed); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; | ||||||
|  | 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ | ||||||
|  | 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; | ||||||
|  | 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); | ||||||
|  | 		noProgIns = (popSize - noSusIns).rand + 1; | ||||||
|  | 		noSilentIns = popSize - noSusIns - noProgIns; | ||||||
|  | 
 | ||||||
|  | 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); | ||||||
|  | 
 | ||||||
|  | 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); | ||||||
|  | 		if(silent == nil, {silent = []}); | ||||||
|  | 		[sus.scramble, prog, silent.scramble] | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | updateVoices = {arg ins, sus; | ||||||
|  | 	var voices, candidates, nWeights, nProbs, sel; | ||||||
|  | 
 | ||||||
|  | 	voices = lastXChanges.deepCopy.last; | ||||||
|  | 
 | ||||||
|  | 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; | ||||||
|  | 	candidates = difference(candidates.asSet, voices.asSet).asList; | ||||||
|  | 	nProbs = candidates.collect({arg candidate; | ||||||
|  | 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; | ||||||
|  | 
 | ||||||
|  | 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); | ||||||
|  | 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); | ||||||
|  | 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); | ||||||
|  | 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); | ||||||
|  | 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); | ||||||
|  | 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); | ||||||
|  | 		//maybe what you want here is a vector to another root and then favoring movement towards it. | ||||||
|  | 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); | ||||||
|  | 
 | ||||||
|  | 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	nWeights = passagesWeights; | ||||||
|  | 
 | ||||||
|  | 	//this handles nWeights of 0; mainly for testing | ||||||
|  | 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; | ||||||
|  | 	nWeights = nWeights.select({arg weight; weight != 0}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; | ||||||
|  | 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) | ||||||
|  | 	}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; | ||||||
|  | 
 | ||||||
|  | 	sel = candidates.wchoose(nProbs); | ||||||
|  | 
 | ||||||
|  | 	voices[ins] = sel; | ||||||
|  | 	lastXChanges = lastXChanges.add(voices).keep(-5); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; | ||||||
|  | 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, pad, lastXChangesHold, voices, adder; | ||||||
|  | 	# sus, prog, silent = order; | ||||||
|  | 	flatOrder = silent ++ sus ++ prog; | ||||||
|  | 	lastXChangesHold = lastXChanges.deepCopy; | ||||||
|  | 	voices = lastState.deepCopy; | ||||||
|  | 	isInChord = popSize.collect({false}); | ||||||
|  | 	allowChord = false; | ||||||
|  | 	pad = false; | ||||||
|  | 	res = []; | ||||||
|  | 	"------generating motif".postln; | ||||||
|  | 	//need to figure out here if voices move between motifs | ||||||
|  | 	flatOrder.do({arg ins, i; | ||||||
|  | 
 | ||||||
|  | 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); | ||||||
|  | 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); | ||||||
|  | 
 | ||||||
|  | 		if(voices[ins] != adder, { | ||||||
|  | 			var dur; | ||||||
|  | 
 | ||||||
|  | 			if((sus ++ silent).includes(ins), { | ||||||
|  | 				allowChord = (ins != sus.last); | ||||||
|  | 				pad = (ins == sus.last); | ||||||
|  | 			}, { | ||||||
|  | 				if(i < (flatOrder.size - 1), { | ||||||
|  | 					allowChord = (isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not; | ||||||
|  | 					pad = false; | ||||||
|  | 				}, { | ||||||
|  | 					allowChord = false; | ||||||
|  | 					pad = true | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if((orderIndex == 0) && sus.includes(ins), { | ||||||
|  | 				dur = entrancesDurFunc.value(allowChord, pad); | ||||||
|  | 			}, { | ||||||
|  | 				dur = passagesDurFunc.value(allowChord, pad); | ||||||
|  | 			}); | ||||||
|  | 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); | ||||||
|  | 
 | ||||||
|  | 			voices[ins] = adder; | ||||||
|  | 			res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// pad ending | ||||||
|  | 	if(orderIndex == (orders.size - 1), { | ||||||
|  | 		(0..(popSize-1)).scramble.do({arg ins; | ||||||
|  | 			if(res.last.first[ins] != ["Rest"], { | ||||||
|  | 				var dur; | ||||||
|  | 				voices[ins] = ["Rest"]; | ||||||
|  | 				allowChord = (voices != popSize.collect({["Rest"]})); | ||||||
|  | 				pad = allowChord.not; | ||||||
|  | 				dur = exitsDurFunc.value(allowChord, pad); | ||||||
|  | 				res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	//format and return | ||||||
|  | 	if(startFromLast, {lastXChanges = lastXChangesHold}); | ||||||
|  | 	res; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------primary routines | ||||||
|  | 
 | ||||||
|  | genMotif = { | ||||||
|  | 	var repeats, fSeq; | ||||||
|  | 
 | ||||||
|  | 	repeats = 1; | ||||||
|  | 	fSeq = []; | ||||||
|  | 
 | ||||||
|  | 	repeats.do({arg index; | ||||||
|  | 		var motif; | ||||||
|  | 
 | ||||||
|  | 		motif = []; | ||||||
|  | 
 | ||||||
|  | 		orders.do({arg order, o; | ||||||
|  | 			var lastState, subMotif; | ||||||
|  | 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); | ||||||
|  | 			subMotif = genSubMotif.value(order, o, lastState, isLastOrder: o == (orders.size - 1)); | ||||||
|  | 			motif = motif.add(subMotif); | ||||||
|  | 
 | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		sanityCheck.value(motif, index); | ||||||
|  | 
 | ||||||
|  | 		fSeq = fSeq.add(motif); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSecondarySeq = {arg seq; | ||||||
|  | 	var curdles, fSeq; | ||||||
|  | 	curdles = []; | ||||||
|  | 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); | ||||||
|  | 
 | ||||||
|  | 	fSeq = seq.clumps(curdles).collect({arg clump, m; | ||||||
|  | 		var repeats, paddedSeq; | ||||||
|  | 
 | ||||||
|  | 		//add rest | ||||||
|  | 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); | ||||||
|  | 
 | ||||||
|  | 		//implement repeats | ||||||
|  | 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); | ||||||
|  | 		repeats.collect({paddedSeq}); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------audition funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~addr.sendMsg(~indexPath, ~indexMsg); | ||||||
|  | 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); | ||||||
|  | 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~msg.postln; | ||||||
|  | 		~addr.sendMsg(~path, *~msg); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | genPatterns = {arg inSeq, addr, oneShot = false; | ||||||
|  | 	var voices, durs, pbinds, res, indices, sectionDurs, msg, ids, seq; | ||||||
|  | 	seq = inSeq.collect({arg mSeq; mSeq[0]}); | ||||||
|  | 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	pbinds = voices.flop.collect({arg voice, v; | ||||||
|  | 		var clumps, hdScores, freqs, fDurs; | ||||||
|  | 		clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 		freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 		fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \string_model, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			), | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \sine, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	}).flatten; | ||||||
|  | 	if(oneShot.not, { | ||||||
|  | 		msg = inSeq.collect({arg mSeq, m; mSeq[1..]}); | ||||||
|  | 		//ids = inSeq.collect({arg mSeq, m; mSeq[2]}); | ||||||
|  | 		sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); | ||||||
|  | 		pbinds = pbinds ++ | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \osc, | ||||||
|  | 				\addr, addr, | ||||||
|  | 				\path, "/playing", | ||||||
|  | 				\msg, Pseq(msg, 1), | ||||||
|  | 				\dur, Pseq(sectionDurs, 1) | ||||||
|  | 			); | ||||||
|  | 		] | ||||||
|  | 	}); | ||||||
|  | 	res = Ppar(pbinds); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | genMidiPatterns = {arg seq; | ||||||
|  | 	var voices, durs, patterns, res, mOut, pbRange; | ||||||
|  | 	pbRange = 1; //semitones - change this as needed for your situation | ||||||
|  | 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); | ||||||
|  | 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	res = Ppar( | ||||||
|  | 		voices.flop.collect({arg voice, v; | ||||||
|  | 			var clumps, hdScores, freqs, fDurs; | ||||||
|  | 
 | ||||||
|  | 			mOut.program(v, 70); | ||||||
|  | 
 | ||||||
|  | 			clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \midi, | ||||||
|  | 				\chan, v, | ||||||
|  | 				\noteval, Pseq(freqs.cpsmidi - 24, 1), | ||||||
|  | 				\note, Pfunc({ | event | event[\noteval].floor }), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\midiout, mOut, | ||||||
|  | 				\amp, 1, | ||||||
|  | 				\bend, Pfunc({ | ||||||
|  | 					| event | | ||||||
|  | 					if (event[\note].isRest.not) { | ||||||
|  | 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; | ||||||
|  | 						m.bend(v, pitchbendvalue); | ||||||
|  | 					}; | ||||||
|  | 					0; // return something other than nil to avoid stopping the pattern | ||||||
|  | 				}), | ||||||
|  | 			); | ||||||
|  | 		}); | ||||||
|  | 	); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------resource management funcs | ||||||
|  | 
 | ||||||
|  | genUID = {Date.seed.asHexString.toLower}; | ||||||
|  | 
 | ||||||
|  | seedFunc = {arg func, seed; | ||||||
|  | 	var funcArgs, next; | ||||||
|  | 	next = Routine({loop{func.valueArray(funcArgs).yield }}); | ||||||
|  | 	next.randSeed_(seed); | ||||||
|  | 	{arg ...args; funcArgs = args; next.value} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | stringifyToDepth = {arg data, maxDepth = 1; | ||||||
|  | 	var prettyString = "", rCount = 0, writeArray, indent; | ||||||
|  | 
 | ||||||
|  | 	if(maxDepth == 0, { | ||||||
|  | 		data.asCompileString | ||||||
|  | 	}, { | ||||||
|  | 		indent = {arg size; size.collect({" "}).join("")}; | ||||||
|  | 		writeArray = {arg array; | ||||||
|  | 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; | ||||||
|  | 			rCount = rCount + 1; | ||||||
|  | 			if(rCount < maxDepth, { | ||||||
|  | 				array.do({arg subArray; writeArray.value(subArray)}); | ||||||
|  | 			}, { | ||||||
|  | 				prettyString = prettyString ++ array.collect({arg subArray; | ||||||
|  | 					indent.value(rCount + 1) ++ subArray.asCompileString | ||||||
|  | 				}).join(",\n"); | ||||||
|  | 			}); | ||||||
|  | 			rCount = rCount - 1; | ||||||
|  | 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		writeArray.value(data); | ||||||
|  | 		prettyString.replace(",\n\n", "\n").drop(-2); | ||||||
|  | 	}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | sanityCheck = {arg motif, index; | ||||||
|  | 	//print functions = very helpful | ||||||
|  | 	("----------" + index + "------------").postln; | ||||||
|  | 
 | ||||||
|  | 	motif.flatten.do({arg val, v; | ||||||
|  | 		if(v > 0, { | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); | ||||||
|  | 		}); | ||||||
|  | 		val.postln | ||||||
|  | 	}); | ||||||
|  | 	"***********".postln; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; | ||||||
|  | 	var res; | ||||||
|  | 
 | ||||||
|  | 	res = in; | ||||||
|  | 	if(res.isNil.not, { | ||||||
|  | 		if((res.isArray && res.isString.not), { | ||||||
|  | 			res = res.asCompileString; | ||||||
|  | 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); | ||||||
|  | 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); | ||||||
|  | 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); | ||||||
|  | 			res = res.replace("Rest", "\"Rest\""); | ||||||
|  | 			res = res.interpret; | ||||||
|  | 		}, { | ||||||
|  | 			//res.postln; | ||||||
|  | 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | writeResources = {arg path, dict; | ||||||
|  | 	var file, modelItems, resString; | ||||||
|  | 	file = File(path,"w"); | ||||||
|  | 
 | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	resString = nameSpaces.collect({arg nameSpace; | ||||||
|  | 		var depth = 0, insert = " "; | ||||||
|  | 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "order", {depth = 1; insert = "\n"}); | ||||||
|  | 		if((nameSpace == "ref_uid") && (dict[nameSpace] == nil), {dict[nameSpace] = "nil"}); | ||||||
|  | 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(dict[nameSpace], depth) | ||||||
|  | 	}).join(",\n"); | ||||||
|  | 
 | ||||||
|  | 	resString = "{\n" ++ resString ++ "\n}"; | ||||||
|  | 
 | ||||||
|  | 	file.write(resString); | ||||||
|  | 	file.close; | ||||||
|  | 	resString | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; | ||||||
|  | 
 | ||||||
|  | loadModelJSON = {arg jsonObject; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS; nS->msgInterpret.value(jsonObject[nS])})); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | setGlobalVars = {arg dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	# seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 	entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 	motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | globalVarsToDict = { | ||||||
|  | 	var modelItems, dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerFile = {arg path; | ||||||
|  | 	ledgerPath = path; | ||||||
|  | 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; | ||||||
|  | 
 | ||||||
|  | saveLedger = {arg ledger, path; | ||||||
|  | 	var file; | ||||||
|  | 	file = File(path, "w"); | ||||||
|  | 	file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); | ||||||
|  | 	file.close; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------global vars | ||||||
|  | 
 | ||||||
|  | primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; | ||||||
|  | //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; | ||||||
|  | exPath = thisProcess.nowExecutingPath; | ||||||
|  | dir = exPath.dirname; | ||||||
|  | //popSize = 4; | ||||||
|  | dims = primes.size; | ||||||
|  | tuples = genTuples.value(); | ||||||
|  | //refUID = nil; | ||||||
|  | group = Group.new; | ||||||
|  | ~group = group; | ||||||
|  | loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); | ||||||
|  | //passagesWeights = [1, 1, 1, 1, 1]; | ||||||
|  | //susWeights = [1, 1, 1]; | ||||||
|  | // order really matters!!!! | ||||||
|  | nameSpaces = [ | ||||||
|  | 	"music_data", "last_changes", "cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", | ||||||
|  | 	"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", | ||||||
|  | 	"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", | ||||||
|  | 	"motif_edited", "order_edited" | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------OSC funcs | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_ledger, {arg msg, time, addr, port; | ||||||
|  | 	loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \load_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_model, {arg msg, time, addr, port; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = loadModelFile.value(msg[1].asString); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | }, \load_model); | ||||||
|  | 
 | ||||||
|  | OSCdef(\save_ledger, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	ledger = msgInterpret.value(msg[1].asString.parseJSON["ledger"], false).postln; | ||||||
|  | 	//loadLedgerJSON.value(msg[0]) | ||||||
|  | 	saveLedger.value(ledger, msg[2].asString); | ||||||
|  | 	//loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \save_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\generate, {arg msg, time, addr, port; | ||||||
|  | 	var path, dict, durSeeds, musPath, modelString; | ||||||
|  | 	msg.postln; | ||||||
|  | 
 | ||||||
|  | 	path = msg[1].asString; | ||||||
|  | 
 | ||||||
|  | 	dict = loadModelFile.value(path); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | 
 | ||||||
|  | 	popSize = ranges.size; | ||||||
|  | 
 | ||||||
|  | 	//refUID.postln; | ||||||
|  | 
 | ||||||
|  | 	loadLedgerFile.value(ledgerPath); | ||||||
|  | 	if(ledger == nil, {ledger = ["tmp"]}); | ||||||
|  | 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); | ||||||
|  | 
 | ||||||
|  | 	lastXChanges = if(refUID == nil, { | ||||||
|  | 		[initVoices.value().deepCopy]; | ||||||
|  | 	}, { | ||||||
|  | 		var file; | ||||||
|  | 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); | ||||||
|  | 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	durSeeds = seedFunc.value({3.collect({rrand(100000, 999999)})}, durSeed).value.postln; | ||||||
|  | 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..4] ++ [entrancesProbVals[5..]] ++ [durSeeds[0]]); | ||||||
|  | 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..4] ++ [passagesProbVals[5..]] ++ [durSeeds[1]]); | ||||||
|  | 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..4] ++ [exitsProbVals[5..]] ++ [durSeeds[2]]); | ||||||
|  | 
 | ||||||
|  | 	if(orders == nil, { | ||||||
|  | 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); | ||||||
|  | 		//addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); | ||||||
|  | 	}); | ||||||
|  | 	seq = seedFunc.value(genMotif, motifSeed).value; | ||||||
|  | 
 | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	modelString = writeResources.value(path, dict); | ||||||
|  | 
 | ||||||
|  | 	//addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); | ||||||
|  | 	addr.sendMsg("/generated", path, modelString, ledgerPath); | ||||||
|  | }, \generate); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | OSCdef(\commit, {arg msg, time, addr, port; | ||||||
|  | 	var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; | ||||||
|  | 	//msg.postln; | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	test1 = msg[1].asString.parseJSON; | ||||||
|  | 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; | ||||||
|  | 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; | ||||||
|  | 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; | ||||||
|  | 	(test1["music"] == test2["music_data"]).postln; | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; | ||||||
|  | 	musicChanged = (musicData != seq).postln; | ||||||
|  | 
 | ||||||
|  | 	curUID = genUID.value; | ||||||
|  | 
 | ||||||
|  | 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); | ||||||
|  | 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); | ||||||
|  | 
 | ||||||
|  | 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	if(musicChanged, { | ||||||
|  | 		seq = musicData; | ||||||
|  | 		dict["music_data"] = seq; | ||||||
|  | 		dict["motif_edited"] = "true" | ||||||
|  | 	}); | ||||||
|  | 	dict["cur_uid"] = curUID; | ||||||
|  | 
 | ||||||
|  | 	writeResources.value(modelPath, dict); | ||||||
|  | 
 | ||||||
|  | 	File.delete(ledgerPath ++ "_bak"); | ||||||
|  | 	File.copy(ledgerPath, ledgerPath ++ "_bak"); | ||||||
|  | 	File.delete(ledgerPath); | ||||||
|  | 	ledger = ledger.drop(-1).add(curUID); | ||||||
|  | 
 | ||||||
|  | 	saveLedger.value(ledger, ledgerPath); | ||||||
|  | 
 | ||||||
|  | 	addr.sendMsg("/committed", curUID, ledgerPath); | ||||||
|  | 	//refUID = curUID; | ||||||
|  | 
 | ||||||
|  | }, \commit); | ||||||
|  | 
 | ||||||
|  | OSCdef(\transport, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	if(msg[1] == 0, { | ||||||
|  | 		player.stop; | ||||||
|  | 		group.set(\gate, 0); | ||||||
|  | 	}, { | ||||||
|  | 		// the cued sequence can now be read from file, so this can be cleaned up | ||||||
|  | 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; | ||||||
|  | 		if(msg[1] == 1, { | ||||||
|  | 			pSeq = []; | ||||||
|  | 			cuedSeek = (seq != nil); | ||||||
|  | 			indexStart = msg[2].asInteger; | ||||||
|  | 			indexEnd = ledger.size - if(cuedSeek, {2}, {1}); | ||||||
|  | 			//ledger.postln; | ||||||
|  | 			if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { | ||||||
|  | 				ledger[indexStart..indexEnd].do({arg uid, index; | ||||||
|  | 					var path, file; | ||||||
|  | 					path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 					file = File(path, "r"); | ||||||
|  | 					pSeq = pSeq.add([msgInterpret.value(file.readAllString.postln.parseJSON["music_data"]), path, indexStart + index, uid]); | ||||||
|  | 					file.close; | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if(cuedSeek, { | ||||||
|  | 				var path, file; | ||||||
|  | 				path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; | ||||||
|  | 				file = File(path, "r"); | ||||||
|  | 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, ledger.size - 1, "tmp"]); | ||||||
|  | 				file.close; | ||||||
|  | 			}); | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr); | ||||||
|  | 		}, { | ||||||
|  | 			pSeq = [loadModelJSON.value(msg[2].asString.parseJSON)["music_data"].postln]; | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr, true); | ||||||
|  | 		}); | ||||||
|  | 		player = Pfset(pattern: patterns, cleanupFunc: { | ||||||
|  | 			addr.sendMsg("/transport", 0); | ||||||
|  | 			addr.sendMsg("/one_shot", 0); | ||||||
|  | 		}); | ||||||
|  | 		player = player.play | ||||||
|  | 	}); | ||||||
|  | }, \transport); | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | //synthdefs | ||||||
|  | ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sineBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~bassBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~hdustBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~samplerBusArray = 2.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sBuf = Buffer.alloc(s, 10, 2); | ||||||
|  | SynthDef(\string_model, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~stringModelBusArray), sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | 	//Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var sig; | ||||||
|  | 	sig = SinOsc.ar(freq); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.asr(0.3, 0.4, 0.3), gate, timeScale: dur, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; | ||||||
|  | 	var nameSpaces, sigs, hierarchicalDust; | ||||||
|  | 
 | ||||||
|  | 	hierarchicalDust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	sigs = [~stringModelBusArray, ~sineBusArray, ~bassBusArray, ~hdustBusArray, ~samplerBusArray].collect({arg busArray, i; | ||||||
|  | 		var nameSpace, sig; | ||||||
|  | 		nameSpace = ['string', 'sine', 'bass', 'hdust', 'sampler'][i]; | ||||||
|  | 		sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = Mix.ar(sig) * pow(NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.1), 2); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	sigs = Mix.ar(sigs / 4); | ||||||
|  | 	Out.ar(0, sigs) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\bass, { | ||||||
|  | 	var switches, drone; | ||||||
|  | 	switches = {|i| Dust.kr(0.1)} ! 9; | ||||||
|  | 	drone = {|i| var harm = pow(2, 2 - (i / 3).trunc), amp = (1 / pow(harm, 2)); | ||||||
|  | 		SinOsc.ar(60 * harm + TRand.kr(-3, 3, switches[i]), 0, amp)} ! 9; | ||||||
|  | 	Out.ar(~bassBusArray[0], Mix.new(drone) * 0.2); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sampler, { | ||||||
|  | 	Out.ar(~samplerBusArray, PlayBuf.ar(2, ~sBuf, BufRateScale.kr(~sBuf), doneAction: 2)) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | // main routine | ||||||
|  | SynthDef(\hdust, { | ||||||
|  | 	arg gate = 0; | ||||||
|  | 	var hierarchical_dust, low_sine, high_sine, brown_noise, white_noise; | ||||||
|  | 	// this triggers the combinations of sources | ||||||
|  | 	// it is similar to the Supercollider UGen called dust but with a hierarchical structure | ||||||
|  | 	hierarchical_dust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(0.1)) | ||||||
|  | 	); | ||||||
|  | 	// adjust the multiplier at the end of each line for adjusting levels | ||||||
|  | 	// note with each trigger, each source has a 1 in 3 chance of sounding | ||||||
|  | 	low_sine = SinOsc.ar(76.midicps / 16) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.1; | ||||||
|  | 	high_sine = SinOsc.ar(76.midicps * 8) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.01; | ||||||
|  | 	brown_noise = BrownNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.025; | ||||||
|  | 	white_noise = WhiteNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.02; | ||||||
|  | 	Out.ar(~hdustBusArray[0], | ||||||
|  | 		((low_sine + high_sine + brown_noise + white_noise) ) | ||||||
|  | 	); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | var bass, hdust, sampler, mixer; | ||||||
|  | bass = Synth.tail(~group, \bass); | ||||||
|  | hdust = Synth.tail(~group, \hdust); | ||||||
|  | sampler = Synth.head(~group, \sampler); | ||||||
|  | mixer = Synth.tail(~group, \mixer); | ||||||
|  | OSCdef(\mixer, {arg msg, time, addr, port; | ||||||
|  | 	mixer.set((msg[1] ++ '_' ++ msg[2] ++ '_' ++ msg[3]), msg[4]) | ||||||
|  | }, \mixer); | ||||||
|  | 
 | ||||||
|  | OSCdef(\sampler, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	sampler.free; | ||||||
|  | 	~sBuf.free; | ||||||
|  | 	~sBuf = Buffer.read(s, msg[1].asString.postln, action: {sampler = Synth.head(~group, \sampler)}); | ||||||
|  | }, \sampler); | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /* old something | ||||||
|  | ( | ||||||
|  | SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	freq = WhiteNoise.ar * 3 + freq; | ||||||
|  | 	freqFinal = Duty.ar((1/freq), 0, freq); | ||||||
|  | 	trig = Changed.ar(freqFinal); | ||||||
|  | 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); | ||||||
|  | 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); | ||||||
|  | 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 
 | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | ) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| @ -0,0 +1,51 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ] ], 4.5 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ] ], 0.75 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 1 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ] ], 4.25 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ 0, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 0, 0, 1 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ] ], 0.75 ], | ||||||
|  |     [ [ [ 0, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 1, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ] ], 0.625 ], | ||||||
|  |     [ [ [ 0, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.75 ], | ||||||
|  |     [ [ [ -1, 1, 0, 0, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 4.875 ], | ||||||
|  |     [ [ [ -1, 1, 0, 0, 1, 0 ], [ "Rest" ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], | ||||||
|  |     [ [ [ -1, 1, 0, 0, 1, 0 ], [ "Rest" ], [ 0, 1, 1, 0, 0, 0 ], [ "Rest" ] ], 1 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, 1, 0, 0, 0 ], [ "Rest" ] ], 1 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.125 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 1 ], [ 1, -1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 0, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 0, 0, 1 ], [ 1, -1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 0, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 0, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ -1, 1, 0, 0, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "50fec831", | ||||||
|  | "ref_uid": "7264e3ac", | ||||||
|  | "order_seed": 982967, | ||||||
|  | "dur_seed": 762088, | ||||||
|  | "motifs_seed": 404006, | ||||||
|  | "entrances_probs_vals": [ 0, 1.67, 4.8015873015873, 0.24725274725275, 1.15, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0, 1.67, 4.8015873015873, 0.24725274725275, 1.15, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0, 1.67, 4.8015873015873, 0.24725274725275, 1.15, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ -1100, 460.68111455108 ], [ -507, 1084.8297213622 ], [ 884.21052631579, 2237 ], [ 1040.2476780186, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 3 ], [ 1, 1 ], [ 2 ] ], | ||||||
|  |   [ [ 3 ], [ 0, 1, 2, 0 ], [  ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.73, 0.23, 0 ], | ||||||
|  | "order_size": [ 1, 3 ], | ||||||
|  | "passages_size": [ 0, 2 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,887 @@ | |||||||
|  | ( | ||||||
|  | // helper funcs | ||||||
|  | var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; | ||||||
|  | 
 | ||||||
|  | // score funcs | ||||||
|  | var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; | ||||||
|  | 
 | ||||||
|  | // subroutines | ||||||
|  | var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; | ||||||
|  | 
 | ||||||
|  | // primary routines | ||||||
|  | var genMotif, genSecondarySeq; | ||||||
|  | 
 | ||||||
|  | // audition funcs | ||||||
|  | var genPatterns, genMidiPatterns; | ||||||
|  | 
 | ||||||
|  | // resource management funcs | ||||||
|  | var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, | ||||||
|  | msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON, | ||||||
|  | setGlobalVars, globalVarsToDict, saveLedger; | ||||||
|  | 
 | ||||||
|  | // model vars | ||||||
|  | //(model and global vars mostly set by OSC funcs | ||||||
|  | var seq, lastXChanges, | ||||||
|  | curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | motifEdited, orderEdited; | ||||||
|  | 
 | ||||||
|  | // model aux vars | ||||||
|  | var entrancesDurFunc, passagesDurFunc, exitsDurFunc; | ||||||
|  | 
 | ||||||
|  | // other global vars | ||||||
|  | var popSize, exPath, dir, primes, dims, tuples, | ||||||
|  | group, player, ledgerPath, ledger, currentlyPlayingUID, | ||||||
|  | nameSpaces; | ||||||
|  | 
 | ||||||
|  | // install JSON quark | ||||||
|  | if(Quarks.isInstalled("JSONlib").not, { | ||||||
|  | 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); | ||||||
|  | 	thisProcess.recompile; | ||||||
|  | 	//HelpBrowser.openHelpFor("Classes/JSONlib"); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------helper funcs | ||||||
|  | 
 | ||||||
|  | hsArrayToCents = { | ||||||
|  | 	arg hsArray; | ||||||
|  | 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pDist = { | ||||||
|  | 	arg array1, array2, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); | ||||||
|  | 	if(signed, {pDistance}, {abs(pDistance)}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hdSum = { | ||||||
|  | 	arg hsArrays; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays.size; | ||||||
|  | 	distances = (size - 1).collect({arg i; | ||||||
|  | 		((i + 1)..(size - 1)).collect({arg j; | ||||||
|  | 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsChordalDistance = { | ||||||
|  | 	arg hsArrays1, hsArrays2; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays1.size; | ||||||
|  | 	distances = hsArrays1.size.collect({arg i; | ||||||
|  | 		hsArrays2.size.collect({arg j; | ||||||
|  | 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsArrayToFreq = { | ||||||
|  | 	arg array; | ||||||
|  | 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------score funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | isInRange = { | ||||||
|  | 	arg hsArray, min, max; | ||||||
|  | 	var cents; | ||||||
|  | 	cents = hsArrayToCents.value(hsArray); | ||||||
|  | 	(cents >= min) && (cents <= max) | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | spacingScore = { | ||||||
|  | 	arg hsArrays, min; | ||||||
|  | 	var centsArray; | ||||||
|  | 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); | ||||||
|  | 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | rangeScore = { | ||||||
|  | 	arg hsArray1, hsArray2, min, max, low, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | intervalScore = { | ||||||
|  | 	arg hsArray1, hsArray2, mean, sd, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	pDistance.gaussCurve(1, mean, sd) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | inclusionScore = { | ||||||
|  | 	arg array, test, min = 0.01; | ||||||
|  | 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------subroutines | ||||||
|  | 
 | ||||||
|  | genTuples = { | ||||||
|  | 	var tuples; | ||||||
|  | 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); | ||||||
|  | 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | initVoices = { | ||||||
|  | 	var init, voicesInit; | ||||||
|  | 	voicesInit = popSize.collect({dims.collect({0})}); | ||||||
|  | 	/* | ||||||
|  | 	voicesInit = [dims.collect({0})]; | ||||||
|  | 	(popSize - 1).do({ | ||||||
|  | 		arg rep, new; | ||||||
|  | 		rep = dims.rand; | ||||||
|  | 		new = voicesInit.last.deepCopy; | ||||||
|  | 		new[rep] = new[rep] + [-1, 1].choose(); | ||||||
|  | 		voicesInit = voicesInit.add(new); | ||||||
|  | 	}); | ||||||
|  | 	*/ | ||||||
|  | 	voicesInit.deepCopy; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; | ||||||
|  | 	var env, pTable, durFunc; | ||||||
|  | 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; | ||||||
|  | 	pTable = env.asRandomTable; | ||||||
|  | 	[chordProb, minPad, maxPad, minDur, maxDur, envData].postln; | ||||||
|  | 	durFunc = {arg allowChord, pad = false; | ||||||
|  | 		var res; | ||||||
|  | 		res = if(allowChord.not, { | ||||||
|  | 			pTable.tableRand * (maxDur - minDur) + minDur | ||||||
|  | 		}, { | ||||||
|  | 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (maxDur - minDur) + minDur}); | ||||||
|  | 		}).round(0.125); | ||||||
|  | 		if(pad, {res = res + rrand(minPad.asFloat, maxPad.asFloat).round(0.125)}); | ||||||
|  | 		if(res.asInteger == res, {res = res.asInteger}); | ||||||
|  | 		res | ||||||
|  | 	}; | ||||||
|  | 	seedFunc.value(durFunc, seed); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; | ||||||
|  | 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ | ||||||
|  | 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; | ||||||
|  | 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); | ||||||
|  | 		noProgIns = (popSize - noSusIns).rand + 1; | ||||||
|  | 		noSilentIns = popSize - noSusIns - noProgIns; | ||||||
|  | 
 | ||||||
|  | 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); | ||||||
|  | 
 | ||||||
|  | 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); | ||||||
|  | 		if(silent == nil, {silent = []}); | ||||||
|  | 		[sus.scramble, prog, silent.scramble] | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | updateVoices = {arg ins, sus; | ||||||
|  | 	var voices, candidates, nWeights, nProbs, sel; | ||||||
|  | 
 | ||||||
|  | 	voices = lastXChanges.deepCopy.last; | ||||||
|  | 
 | ||||||
|  | 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; | ||||||
|  | 	candidates = difference(candidates.asSet, voices.asSet).asList; | ||||||
|  | 	nProbs = candidates.collect({arg candidate; | ||||||
|  | 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; | ||||||
|  | 
 | ||||||
|  | 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); | ||||||
|  | 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); | ||||||
|  | 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); | ||||||
|  | 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); | ||||||
|  | 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); | ||||||
|  | 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); | ||||||
|  | 		//maybe what you want here is a vector to another root and then favoring movement towards it. | ||||||
|  | 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); | ||||||
|  | 
 | ||||||
|  | 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	nWeights = passagesWeights; | ||||||
|  | 
 | ||||||
|  | 	//this handles nWeights of 0; mainly for testing | ||||||
|  | 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; | ||||||
|  | 	nWeights = nWeights.select({arg weight; weight != 0}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; | ||||||
|  | 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) | ||||||
|  | 	}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; | ||||||
|  | 
 | ||||||
|  | 	sel = candidates.wchoose(nProbs); | ||||||
|  | 
 | ||||||
|  | 	voices[ins] = sel; | ||||||
|  | 	lastXChanges = lastXChanges.add(voices).keep(-5); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; | ||||||
|  | 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, pad, lastXChangesHold, voices, adder; | ||||||
|  | 	# sus, prog, silent = order; | ||||||
|  | 	flatOrder = silent ++ sus ++ prog; | ||||||
|  | 	lastXChangesHold = lastXChanges.deepCopy; | ||||||
|  | 	voices = lastState.deepCopy; | ||||||
|  | 	isInChord = popSize.collect({false}); | ||||||
|  | 	allowChord = false; | ||||||
|  | 	pad = false; | ||||||
|  | 	res = []; | ||||||
|  | 	"------generating motif".postln; | ||||||
|  | 	//need to figure out here if voices move between motifs | ||||||
|  | 	flatOrder.do({arg ins, i; | ||||||
|  | 
 | ||||||
|  | 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); | ||||||
|  | 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); | ||||||
|  | 
 | ||||||
|  | 		if(voices[ins] != adder, { | ||||||
|  | 			var dur; | ||||||
|  | 
 | ||||||
|  | 			if((sus ++ silent).includes(ins), { | ||||||
|  | 				allowChord = (ins != sus.last); | ||||||
|  | 				pad = (ins == sus.last); | ||||||
|  | 			}, { | ||||||
|  | 				if(i < (flatOrder.size - 1), { | ||||||
|  | 					allowChord = (isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not; | ||||||
|  | 					pad = false; | ||||||
|  | 				}, { | ||||||
|  | 					allowChord = false; | ||||||
|  | 					pad = true | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if((orderIndex == 0) && sus.includes(ins), { | ||||||
|  | 				dur = entrancesDurFunc.value(allowChord, pad); | ||||||
|  | 			}, { | ||||||
|  | 				dur = passagesDurFunc.value(allowChord, pad); | ||||||
|  | 			}); | ||||||
|  | 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); | ||||||
|  | 
 | ||||||
|  | 			voices[ins] = adder; | ||||||
|  | 			res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// pad ending | ||||||
|  | 	if(orderIndex == (orders.size - 1), { | ||||||
|  | 		(0..(popSize-1)).scramble.do({arg ins; | ||||||
|  | 			if(res.last.first[ins] != ["Rest"], { | ||||||
|  | 				var dur; | ||||||
|  | 				voices[ins] = ["Rest"]; | ||||||
|  | 				allowChord = (voices != popSize.collect({["Rest"]})); | ||||||
|  | 				pad = allowChord.not; | ||||||
|  | 				dur = exitsDurFunc.value(allowChord, pad); | ||||||
|  | 				res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	//format and return | ||||||
|  | 	if(startFromLast, {lastXChanges = lastXChangesHold}); | ||||||
|  | 	res; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------primary routines | ||||||
|  | 
 | ||||||
|  | genMotif = { | ||||||
|  | 	var repeats, fSeq; | ||||||
|  | 
 | ||||||
|  | 	repeats = 1; | ||||||
|  | 	fSeq = []; | ||||||
|  | 
 | ||||||
|  | 	repeats.do({arg index; | ||||||
|  | 		var motif; | ||||||
|  | 
 | ||||||
|  | 		motif = []; | ||||||
|  | 
 | ||||||
|  | 		orders.do({arg order, o; | ||||||
|  | 			var lastState, subMotif; | ||||||
|  | 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); | ||||||
|  | 			subMotif = genSubMotif.value(order, o, lastState, isLastOrder: o == (orders.size - 1)); | ||||||
|  | 			motif = motif.add(subMotif); | ||||||
|  | 
 | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		sanityCheck.value(motif, index); | ||||||
|  | 
 | ||||||
|  | 		fSeq = fSeq.add(motif); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSecondarySeq = {arg seq; | ||||||
|  | 	var curdles, fSeq; | ||||||
|  | 	curdles = []; | ||||||
|  | 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); | ||||||
|  | 
 | ||||||
|  | 	fSeq = seq.clumps(curdles).collect({arg clump, m; | ||||||
|  | 		var repeats, paddedSeq; | ||||||
|  | 
 | ||||||
|  | 		//add rest | ||||||
|  | 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); | ||||||
|  | 
 | ||||||
|  | 		//implement repeats | ||||||
|  | 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); | ||||||
|  | 		repeats.collect({paddedSeq}); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------audition funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~addr.sendMsg(~indexPath, ~indexMsg); | ||||||
|  | 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); | ||||||
|  | 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~msg.postln; | ||||||
|  | 		~addr.sendMsg(~path, *~msg); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | genPatterns = {arg inSeq, addr, oneShot = false; | ||||||
|  | 	var voices, durs, pbinds, res, indices, sectionDurs, msg, ids, seq; | ||||||
|  | 	seq = inSeq.collect({arg mSeq; mSeq[0]}); | ||||||
|  | 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	pbinds = voices.flop.collect({arg voice, v; | ||||||
|  | 		var clumps, hdScores, freqs, fDurs; | ||||||
|  | 		clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 		freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 		fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \string_model, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			), | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \sine, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	}).flatten; | ||||||
|  | 	if(oneShot.not, { | ||||||
|  | 		msg = inSeq.collect({arg mSeq, m; mSeq[1..]}); | ||||||
|  | 		//ids = inSeq.collect({arg mSeq, m; mSeq[2]}); | ||||||
|  | 		sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); | ||||||
|  | 		pbinds = pbinds ++ | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \osc, | ||||||
|  | 				\addr, addr, | ||||||
|  | 				\path, "/playing", | ||||||
|  | 				\msg, Pseq(msg, 1), | ||||||
|  | 				\dur, Pseq(sectionDurs, 1) | ||||||
|  | 			); | ||||||
|  | 		] | ||||||
|  | 	}); | ||||||
|  | 	res = Ppar(pbinds); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | genMidiPatterns = {arg seq; | ||||||
|  | 	var voices, durs, patterns, res, mOut, pbRange; | ||||||
|  | 	pbRange = 1; //semitones - change this as needed for your situation | ||||||
|  | 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); | ||||||
|  | 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	res = Ppar( | ||||||
|  | 		voices.flop.collect({arg voice, v; | ||||||
|  | 			var clumps, hdScores, freqs, fDurs; | ||||||
|  | 
 | ||||||
|  | 			mOut.program(v, 70); | ||||||
|  | 
 | ||||||
|  | 			clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \midi, | ||||||
|  | 				\chan, v, | ||||||
|  | 				\noteval, Pseq(freqs.cpsmidi - 24, 1), | ||||||
|  | 				\note, Pfunc({ | event | event[\noteval].floor }), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\midiout, mOut, | ||||||
|  | 				\amp, 1, | ||||||
|  | 				\bend, Pfunc({ | ||||||
|  | 					| event | | ||||||
|  | 					if (event[\note].isRest.not) { | ||||||
|  | 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; | ||||||
|  | 						m.bend(v, pitchbendvalue); | ||||||
|  | 					}; | ||||||
|  | 					0; // return something other than nil to avoid stopping the pattern | ||||||
|  | 				}), | ||||||
|  | 			); | ||||||
|  | 		}); | ||||||
|  | 	); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------resource management funcs | ||||||
|  | 
 | ||||||
|  | genUID = {Date.seed.asHexString.toLower}; | ||||||
|  | 
 | ||||||
|  | seedFunc = {arg func, seed; | ||||||
|  | 	var funcArgs, next; | ||||||
|  | 	next = Routine({loop{func.valueArray(funcArgs).yield }}); | ||||||
|  | 	next.randSeed_(seed); | ||||||
|  | 	{arg ...args; funcArgs = args; next.value} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | stringifyToDepth = {arg data, maxDepth = 1; | ||||||
|  | 	var prettyString = "", rCount = 0, writeArray, indent; | ||||||
|  | 
 | ||||||
|  | 	if(maxDepth == 0, { | ||||||
|  | 		data.asCompileString | ||||||
|  | 	}, { | ||||||
|  | 		indent = {arg size; size.collect({" "}).join("")}; | ||||||
|  | 		writeArray = {arg array; | ||||||
|  | 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; | ||||||
|  | 			rCount = rCount + 1; | ||||||
|  | 			if(rCount < maxDepth, { | ||||||
|  | 				array.do({arg subArray; writeArray.value(subArray)}); | ||||||
|  | 			}, { | ||||||
|  | 				prettyString = prettyString ++ array.collect({arg subArray; | ||||||
|  | 					indent.value(rCount + 1) ++ subArray.asCompileString | ||||||
|  | 				}).join(",\n"); | ||||||
|  | 			}); | ||||||
|  | 			rCount = rCount - 1; | ||||||
|  | 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		writeArray.value(data); | ||||||
|  | 		prettyString.replace(",\n\n", "\n").drop(-2); | ||||||
|  | 	}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | sanityCheck = {arg motif, index; | ||||||
|  | 	//print functions = very helpful | ||||||
|  | 	("----------" + index + "------------").postln; | ||||||
|  | 
 | ||||||
|  | 	motif.flatten.do({arg val, v; | ||||||
|  | 		if(v > 0, { | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); | ||||||
|  | 		}); | ||||||
|  | 		val.postln | ||||||
|  | 	}); | ||||||
|  | 	"***********".postln; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; | ||||||
|  | 	var res; | ||||||
|  | 
 | ||||||
|  | 	res = in; | ||||||
|  | 	if(res.isNil.not, { | ||||||
|  | 		if((res.isArray && res.isString.not), { | ||||||
|  | 			res = res.asCompileString; | ||||||
|  | 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); | ||||||
|  | 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); | ||||||
|  | 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); | ||||||
|  | 			res = res.replace("Rest", "\"Rest\""); | ||||||
|  | 			res = res.interpret; | ||||||
|  | 		}, { | ||||||
|  | 			//res.postln; | ||||||
|  | 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | writeResources = {arg path, dict; | ||||||
|  | 	var file, modelItems, resString; | ||||||
|  | 	file = File(path,"w"); | ||||||
|  | 
 | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	resString = nameSpaces.collect({arg nameSpace; | ||||||
|  | 		var depth = 0, insert = " "; | ||||||
|  | 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "order", {depth = 1; insert = "\n"}); | ||||||
|  | 		if((nameSpace == "ref_uid") && (dict[nameSpace] == nil), {dict[nameSpace] = "nil"}); | ||||||
|  | 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(dict[nameSpace], depth) | ||||||
|  | 	}).join(",\n"); | ||||||
|  | 
 | ||||||
|  | 	resString = "{\n" ++ resString ++ "\n}"; | ||||||
|  | 
 | ||||||
|  | 	file.write(resString); | ||||||
|  | 	file.close; | ||||||
|  | 	resString | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; | ||||||
|  | 
 | ||||||
|  | loadModelJSON = {arg jsonObject; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS; nS->msgInterpret.value(jsonObject[nS])})); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | setGlobalVars = {arg dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	# seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 	entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 	motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | globalVarsToDict = { | ||||||
|  | 	var modelItems, dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerFile = {arg path; | ||||||
|  | 	ledgerPath = path; | ||||||
|  | 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; | ||||||
|  | 
 | ||||||
|  | saveLedger = {arg ledger, path; | ||||||
|  | 	var file; | ||||||
|  | 	file = File(path, "w"); | ||||||
|  | 	file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); | ||||||
|  | 	file.close; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------global vars | ||||||
|  | 
 | ||||||
|  | primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; | ||||||
|  | //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; | ||||||
|  | exPath = thisProcess.nowExecutingPath; | ||||||
|  | dir = exPath.dirname; | ||||||
|  | //popSize = 4; | ||||||
|  | dims = primes.size; | ||||||
|  | tuples = genTuples.value(); | ||||||
|  | //refUID = nil; | ||||||
|  | group = Group.new; | ||||||
|  | ~group = group; | ||||||
|  | loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); | ||||||
|  | //passagesWeights = [1, 1, 1, 1, 1]; | ||||||
|  | //susWeights = [1, 1, 1]; | ||||||
|  | // order really matters!!!! | ||||||
|  | nameSpaces = [ | ||||||
|  | 	"music_data", "last_changes", "cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", | ||||||
|  | 	"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", | ||||||
|  | 	"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", | ||||||
|  | 	"motif_edited", "order_edited" | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------OSC funcs | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_ledger, {arg msg, time, addr, port; | ||||||
|  | 	loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \load_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_model, {arg msg, time, addr, port; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = loadModelFile.value(msg[1].asString); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | }, \load_model); | ||||||
|  | 
 | ||||||
|  | OSCdef(\save_ledger, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	ledger = msgInterpret.value(msg[1].asString.parseJSON["ledger"], false).postln; | ||||||
|  | 	//loadLedgerJSON.value(msg[0]) | ||||||
|  | 	saveLedger.value(ledger, msg[2].asString); | ||||||
|  | 	//loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \save_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\generate, {arg msg, time, addr, port; | ||||||
|  | 	var path, dict, durSeeds, musPath, modelString; | ||||||
|  | 	msg.postln; | ||||||
|  | 
 | ||||||
|  | 	path = msg[1].asString; | ||||||
|  | 
 | ||||||
|  | 	dict = loadModelFile.value(path); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | 
 | ||||||
|  | 	popSize = ranges.size; | ||||||
|  | 
 | ||||||
|  | 	//refUID.postln; | ||||||
|  | 
 | ||||||
|  | 	loadLedgerFile.value(ledgerPath); | ||||||
|  | 	if(ledger == nil, {ledger = ["tmp"]}); | ||||||
|  | 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); | ||||||
|  | 
 | ||||||
|  | 	lastXChanges = if(refUID == nil, { | ||||||
|  | 		[initVoices.value().deepCopy]; | ||||||
|  | 	}, { | ||||||
|  | 		var file; | ||||||
|  | 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); | ||||||
|  | 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	durSeeds = seedFunc.value({3.collect({rrand(100000, 999999)})}, durSeed).value.postln; | ||||||
|  | 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..4] ++ [entrancesProbVals[5..]] ++ [durSeeds[0]]); | ||||||
|  | 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..4] ++ [passagesProbVals[5..]] ++ [durSeeds[1]]); | ||||||
|  | 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..4] ++ [exitsProbVals[5..]] ++ [durSeeds[2]]); | ||||||
|  | 
 | ||||||
|  | 	if(orders == nil, { | ||||||
|  | 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); | ||||||
|  | 		//addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); | ||||||
|  | 	}); | ||||||
|  | 	seq = seedFunc.value(genMotif, motifSeed).value; | ||||||
|  | 
 | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	modelString = writeResources.value(path, dict); | ||||||
|  | 
 | ||||||
|  | 	//addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); | ||||||
|  | 	addr.sendMsg("/generated", path, modelString, ledgerPath); | ||||||
|  | }, \generate); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | OSCdef(\commit, {arg msg, time, addr, port; | ||||||
|  | 	var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; | ||||||
|  | 	//msg.postln; | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	test1 = msg[1].asString.parseJSON; | ||||||
|  | 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; | ||||||
|  | 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; | ||||||
|  | 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; | ||||||
|  | 	(test1["music"] == test2["music_data"]).postln; | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; | ||||||
|  | 	musicChanged = (musicData != seq).postln; | ||||||
|  | 
 | ||||||
|  | 	curUID = genUID.value; | ||||||
|  | 
 | ||||||
|  | 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); | ||||||
|  | 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); | ||||||
|  | 
 | ||||||
|  | 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	if(musicChanged, { | ||||||
|  | 		seq = musicData; | ||||||
|  | 		dict["music_data"] = seq; | ||||||
|  | 		dict["motif_edited"] = "true" | ||||||
|  | 	}); | ||||||
|  | 	dict["cur_uid"] = curUID; | ||||||
|  | 
 | ||||||
|  | 	writeResources.value(modelPath, dict); | ||||||
|  | 
 | ||||||
|  | 	File.delete(ledgerPath ++ "_bak"); | ||||||
|  | 	File.copy(ledgerPath, ledgerPath ++ "_bak"); | ||||||
|  | 	File.delete(ledgerPath); | ||||||
|  | 	ledger = ledger.drop(-1).add(curUID); | ||||||
|  | 
 | ||||||
|  | 	saveLedger.value(ledger, ledgerPath); | ||||||
|  | 
 | ||||||
|  | 	addr.sendMsg("/committed", curUID, ledgerPath); | ||||||
|  | 	//refUID = curUID; | ||||||
|  | 
 | ||||||
|  | }, \commit); | ||||||
|  | 
 | ||||||
|  | OSCdef(\transport, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	if(msg[1] == 0, { | ||||||
|  | 		player.stop; | ||||||
|  | 		group.set(\gate, 0); | ||||||
|  | 	}, { | ||||||
|  | 		// the cued sequence can now be read from file, so this can be cleaned up | ||||||
|  | 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; | ||||||
|  | 		if(msg[1] == 1, { | ||||||
|  | 			pSeq = []; | ||||||
|  | 			cuedSeek = (seq != nil); | ||||||
|  | 			indexStart = msg[2].asInteger; | ||||||
|  | 			indexEnd = ledger.size - if(cuedSeek, {2}, {1}); | ||||||
|  | 			//ledger.postln; | ||||||
|  | 			if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { | ||||||
|  | 				ledger[indexStart..indexEnd].do({arg uid, index; | ||||||
|  | 					var path, file; | ||||||
|  | 					path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 					file = File(path, "r"); | ||||||
|  | 					pSeq = pSeq.add([msgInterpret.value(file.readAllString.postln.parseJSON["music_data"]), path, indexStart + index, uid]); | ||||||
|  | 					file.close; | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if(cuedSeek, { | ||||||
|  | 				var path, file; | ||||||
|  | 				path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; | ||||||
|  | 				file = File(path, "r"); | ||||||
|  | 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, ledger.size - 1, "tmp"]); | ||||||
|  | 				file.close; | ||||||
|  | 			}); | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr); | ||||||
|  | 		}, { | ||||||
|  | 			pSeq = [loadModelJSON.value(msg[2].asString.parseJSON)["music_data"].postln]; | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr, true); | ||||||
|  | 		}); | ||||||
|  | 		player = Pfset(pattern: patterns, cleanupFunc: { | ||||||
|  | 			addr.sendMsg("/transport", 0); | ||||||
|  | 			addr.sendMsg("/one_shot", 0); | ||||||
|  | 		}); | ||||||
|  | 		player = player.play | ||||||
|  | 	}); | ||||||
|  | }, \transport); | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | //synthdefs | ||||||
|  | ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sineBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~bassBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~hdustBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~samplerBusArray = 2.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sBuf = Buffer.alloc(s, 10, 2); | ||||||
|  | SynthDef(\string_model, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~stringModelBusArray), sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | 	//Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var sig; | ||||||
|  | 	sig = SinOsc.ar(freq); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.asr(0.3, 0.4, 0.3), gate, timeScale: dur, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; | ||||||
|  | 	var nameSpaces, sigs, hierarchicalDust; | ||||||
|  | 
 | ||||||
|  | 	hierarchicalDust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	sigs = [~stringModelBusArray, ~sineBusArray, ~bassBusArray, ~hdustBusArray, ~samplerBusArray].collect({arg busArray, i; | ||||||
|  | 		var nameSpace, sig; | ||||||
|  | 		nameSpace = ['string', 'sine', 'bass', 'hdust', 'sampler'][i]; | ||||||
|  | 		sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = Mix.ar(sig) * pow(NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.1), 2); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	sigs = Mix.ar(sigs / 4); | ||||||
|  | 	Out.ar(0, sigs) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\bass, { | ||||||
|  | 	var switches, drone; | ||||||
|  | 	switches = {|i| Dust.kr(0.1)} ! 9; | ||||||
|  | 	drone = {|i| var harm = pow(2, 2 - (i / 3).trunc), amp = (1 / pow(harm, 2)); | ||||||
|  | 		SinOsc.ar(60 * harm + TRand.kr(-3, 3, switches[i]), 0, amp)} ! 9; | ||||||
|  | 	Out.ar(~bassBusArray[0], Mix.new(drone) * 0.2); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sampler, { | ||||||
|  | 	Out.ar(~samplerBusArray, PlayBuf.ar(2, ~sBuf, BufRateScale.kr(~sBuf), doneAction: 2)) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | // main routine | ||||||
|  | SynthDef(\hdust, { | ||||||
|  | 	arg gate = 0; | ||||||
|  | 	var hierarchical_dust, low_sine, high_sine, brown_noise, white_noise; | ||||||
|  | 	// this triggers the combinations of sources | ||||||
|  | 	// it is similar to the Supercollider UGen called dust but with a hierarchical structure | ||||||
|  | 	hierarchical_dust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(0.1)) | ||||||
|  | 	); | ||||||
|  | 	// adjust the multiplier at the end of each line for adjusting levels | ||||||
|  | 	// note with each trigger, each source has a 1 in 3 chance of sounding | ||||||
|  | 	low_sine = SinOsc.ar(76.midicps / 16) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.1; | ||||||
|  | 	high_sine = SinOsc.ar(76.midicps * 8) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.01; | ||||||
|  | 	brown_noise = BrownNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.025; | ||||||
|  | 	white_noise = WhiteNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.02; | ||||||
|  | 	Out.ar(~hdustBusArray[0], | ||||||
|  | 		((low_sine + high_sine + brown_noise + white_noise) ) | ||||||
|  | 	); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | var bass, hdust, sampler, mixer; | ||||||
|  | bass = Synth.tail(~group, \bass); | ||||||
|  | hdust = Synth.tail(~group, \hdust); | ||||||
|  | sampler = Synth.head(~group, \sampler); | ||||||
|  | mixer = Synth.tail(~group, \mixer); | ||||||
|  | OSCdef(\mixer, {arg msg, time, addr, port; | ||||||
|  | 	mixer.set((msg[1] ++ '_' ++ msg[2] ++ '_' ++ msg[3]), msg[4]) | ||||||
|  | }, \mixer); | ||||||
|  | 
 | ||||||
|  | OSCdef(\sampler, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	sampler.free; | ||||||
|  | 	~sBuf.free; | ||||||
|  | 	~sBuf = Buffer.read(s, msg[1].asString.postln, action: {sampler = Synth.head(~group, \sampler)}); | ||||||
|  | }, \sampler); | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /* old something | ||||||
|  | ( | ||||||
|  | SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	freq = WhiteNoise.ar * 3 + freq; | ||||||
|  | 	freqFinal = Duty.ar((1/freq), 0, freq); | ||||||
|  | 	trig = Changed.ar(freqFinal); | ||||||
|  | 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); | ||||||
|  | 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); | ||||||
|  | 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 
 | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | ) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| @ -0,0 +1,43 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 2.25 ], | ||||||
|  |     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.75 ], | ||||||
|  |     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 3.125 ], | ||||||
|  |     [ [ [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 2.625 ], | ||||||
|  |     [ [ [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 3 ], | ||||||
|  |     [ [ [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.25 ], | ||||||
|  |     [ [ [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 2.75 ], | ||||||
|  |     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 2.75 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.5 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "5267b235", | ||||||
|  | "ref_uid": "nil", | ||||||
|  | "order_seed": 474005, | ||||||
|  | "dur_seed": 826425, | ||||||
|  | "motifs_seed": 116157, | ||||||
|  | "entrances_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ 1419.1950464396, 2400 ], [ 1519.5046439628, 2400 ], [ 1541.7956656347, 2237 ], [ 1519.5046439628, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 2, 1, 3 ], [ 0, 0 ], [  ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.75, 0.69, 0.75 ], | ||||||
|  | "order_size": [ 1, 2 ], | ||||||
|  | "passages_size": [ 0, 2 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,887 @@ | |||||||
|  | ( | ||||||
|  | // helper funcs | ||||||
|  | var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; | ||||||
|  | 
 | ||||||
|  | // score funcs | ||||||
|  | var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; | ||||||
|  | 
 | ||||||
|  | // subroutines | ||||||
|  | var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; | ||||||
|  | 
 | ||||||
|  | // primary routines | ||||||
|  | var genMotif, genSecondarySeq; | ||||||
|  | 
 | ||||||
|  | // audition funcs | ||||||
|  | var genPatterns, genMidiPatterns; | ||||||
|  | 
 | ||||||
|  | // resource management funcs | ||||||
|  | var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, | ||||||
|  | msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON, | ||||||
|  | setGlobalVars, globalVarsToDict, saveLedger; | ||||||
|  | 
 | ||||||
|  | // model vars | ||||||
|  | //(model and global vars mostly set by OSC funcs | ||||||
|  | var seq, lastXChanges, | ||||||
|  | curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | motifEdited, orderEdited; | ||||||
|  | 
 | ||||||
|  | // model aux vars | ||||||
|  | var entrancesDurFunc, passagesDurFunc, exitsDurFunc; | ||||||
|  | 
 | ||||||
|  | // other global vars | ||||||
|  | var popSize, exPath, dir, primes, dims, tuples, | ||||||
|  | group, player, ledgerPath, ledger, currentlyPlayingUID, | ||||||
|  | nameSpaces; | ||||||
|  | 
 | ||||||
|  | // install JSON quark | ||||||
|  | if(Quarks.isInstalled("JSONlib").not, { | ||||||
|  | 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); | ||||||
|  | 	thisProcess.recompile; | ||||||
|  | 	//HelpBrowser.openHelpFor("Classes/JSONlib"); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------helper funcs | ||||||
|  | 
 | ||||||
|  | hsArrayToCents = { | ||||||
|  | 	arg hsArray; | ||||||
|  | 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pDist = { | ||||||
|  | 	arg array1, array2, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); | ||||||
|  | 	if(signed, {pDistance}, {abs(pDistance)}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hdSum = { | ||||||
|  | 	arg hsArrays; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays.size; | ||||||
|  | 	distances = (size - 1).collect({arg i; | ||||||
|  | 		((i + 1)..(size - 1)).collect({arg j; | ||||||
|  | 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsChordalDistance = { | ||||||
|  | 	arg hsArrays1, hsArrays2; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays1.size; | ||||||
|  | 	distances = hsArrays1.size.collect({arg i; | ||||||
|  | 		hsArrays2.size.collect({arg j; | ||||||
|  | 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsArrayToFreq = { | ||||||
|  | 	arg array; | ||||||
|  | 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------score funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | isInRange = { | ||||||
|  | 	arg hsArray, min, max; | ||||||
|  | 	var cents; | ||||||
|  | 	cents = hsArrayToCents.value(hsArray); | ||||||
|  | 	(cents >= min) && (cents <= max) | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | spacingScore = { | ||||||
|  | 	arg hsArrays, min; | ||||||
|  | 	var centsArray; | ||||||
|  | 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); | ||||||
|  | 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | rangeScore = { | ||||||
|  | 	arg hsArray1, hsArray2, min, max, low, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | intervalScore = { | ||||||
|  | 	arg hsArray1, hsArray2, mean, sd, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	pDistance.gaussCurve(1, mean, sd) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | inclusionScore = { | ||||||
|  | 	arg array, test, min = 0.01; | ||||||
|  | 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------subroutines | ||||||
|  | 
 | ||||||
|  | genTuples = { | ||||||
|  | 	var tuples; | ||||||
|  | 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); | ||||||
|  | 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | initVoices = { | ||||||
|  | 	var init, voicesInit; | ||||||
|  | 	voicesInit = popSize.collect({dims.collect({0})}); | ||||||
|  | 	/* | ||||||
|  | 	voicesInit = [dims.collect({0})]; | ||||||
|  | 	(popSize - 1).do({ | ||||||
|  | 		arg rep, new; | ||||||
|  | 		rep = dims.rand; | ||||||
|  | 		new = voicesInit.last.deepCopy; | ||||||
|  | 		new[rep] = new[rep] + [-1, 1].choose(); | ||||||
|  | 		voicesInit = voicesInit.add(new); | ||||||
|  | 	}); | ||||||
|  | 	*/ | ||||||
|  | 	voicesInit.deepCopy; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; | ||||||
|  | 	var env, pTable, durFunc; | ||||||
|  | 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; | ||||||
|  | 	pTable = env.asRandomTable; | ||||||
|  | 	[chordProb, minPad, maxPad, minDur, maxDur, envData].postln; | ||||||
|  | 	durFunc = {arg allowChord, pad = false; | ||||||
|  | 		var res; | ||||||
|  | 		res = if(allowChord.not, { | ||||||
|  | 			pTable.tableRand * (maxDur - minDur) + minDur | ||||||
|  | 		}, { | ||||||
|  | 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (maxDur - minDur) + minDur}); | ||||||
|  | 		}).round(0.125); | ||||||
|  | 		if(pad, {res = res + rrand(minPad.asFloat, maxPad.asFloat).round(0.125)}); | ||||||
|  | 		if(res.asInteger == res, {res = res.asInteger}); | ||||||
|  | 		res | ||||||
|  | 	}; | ||||||
|  | 	seedFunc.value(durFunc, seed); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; | ||||||
|  | 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ | ||||||
|  | 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; | ||||||
|  | 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); | ||||||
|  | 		noProgIns = (popSize - noSusIns).rand + 1; | ||||||
|  | 		noSilentIns = popSize - noSusIns - noProgIns; | ||||||
|  | 
 | ||||||
|  | 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); | ||||||
|  | 
 | ||||||
|  | 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); | ||||||
|  | 		if(silent == nil, {silent = []}); | ||||||
|  | 		[sus.scramble, prog, silent.scramble] | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | updateVoices = {arg ins, sus; | ||||||
|  | 	var voices, candidates, nWeights, nProbs, sel; | ||||||
|  | 
 | ||||||
|  | 	voices = lastXChanges.deepCopy.last; | ||||||
|  | 
 | ||||||
|  | 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; | ||||||
|  | 	candidates = difference(candidates.asSet, voices.asSet).asList; | ||||||
|  | 	nProbs = candidates.collect({arg candidate; | ||||||
|  | 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; | ||||||
|  | 
 | ||||||
|  | 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); | ||||||
|  | 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); | ||||||
|  | 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); | ||||||
|  | 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); | ||||||
|  | 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); | ||||||
|  | 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); | ||||||
|  | 		//maybe what you want here is a vector to another root and then favoring movement towards it. | ||||||
|  | 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); | ||||||
|  | 
 | ||||||
|  | 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	nWeights = passagesWeights; | ||||||
|  | 
 | ||||||
|  | 	//this handles nWeights of 0; mainly for testing | ||||||
|  | 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; | ||||||
|  | 	nWeights = nWeights.select({arg weight; weight != 0}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; | ||||||
|  | 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) | ||||||
|  | 	}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; | ||||||
|  | 
 | ||||||
|  | 	sel = candidates.wchoose(nProbs); | ||||||
|  | 
 | ||||||
|  | 	voices[ins] = sel; | ||||||
|  | 	lastXChanges = lastXChanges.add(voices).keep(-5); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; | ||||||
|  | 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, pad, lastXChangesHold, voices, adder; | ||||||
|  | 	# sus, prog, silent = order; | ||||||
|  | 	flatOrder = silent ++ sus ++ prog; | ||||||
|  | 	lastXChangesHold = lastXChanges.deepCopy; | ||||||
|  | 	voices = lastState.deepCopy; | ||||||
|  | 	isInChord = popSize.collect({false}); | ||||||
|  | 	allowChord = false; | ||||||
|  | 	pad = false; | ||||||
|  | 	res = []; | ||||||
|  | 	"------generating motif".postln; | ||||||
|  | 	//need to figure out here if voices move between motifs | ||||||
|  | 	flatOrder.do({arg ins, i; | ||||||
|  | 
 | ||||||
|  | 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); | ||||||
|  | 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); | ||||||
|  | 
 | ||||||
|  | 		if(voices[ins] != adder, { | ||||||
|  | 			var dur; | ||||||
|  | 
 | ||||||
|  | 			if((sus ++ silent).includes(ins), { | ||||||
|  | 				allowChord = (ins != sus.last); | ||||||
|  | 				pad = (ins == sus.last); | ||||||
|  | 			}, { | ||||||
|  | 				if(i < (flatOrder.size - 1), { | ||||||
|  | 					allowChord = (isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not; | ||||||
|  | 					pad = false; | ||||||
|  | 				}, { | ||||||
|  | 					allowChord = false; | ||||||
|  | 					pad = true | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if((orderIndex == 0) && sus.includes(ins), { | ||||||
|  | 				dur = entrancesDurFunc.value(allowChord, pad); | ||||||
|  | 			}, { | ||||||
|  | 				dur = passagesDurFunc.value(allowChord, pad); | ||||||
|  | 			}); | ||||||
|  | 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); | ||||||
|  | 
 | ||||||
|  | 			voices[ins] = adder; | ||||||
|  | 			res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// pad ending | ||||||
|  | 	if(orderIndex == (orders.size - 1), { | ||||||
|  | 		(0..(popSize-1)).scramble.do({arg ins; | ||||||
|  | 			if(res.last.first[ins] != ["Rest"], { | ||||||
|  | 				var dur; | ||||||
|  | 				voices[ins] = ["Rest"]; | ||||||
|  | 				allowChord = (voices != popSize.collect({["Rest"]})); | ||||||
|  | 				pad = allowChord.not; | ||||||
|  | 				dur = exitsDurFunc.value(allowChord, pad); | ||||||
|  | 				res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	//format and return | ||||||
|  | 	if(startFromLast, {lastXChanges = lastXChangesHold}); | ||||||
|  | 	res; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------primary routines | ||||||
|  | 
 | ||||||
|  | genMotif = { | ||||||
|  | 	var repeats, fSeq; | ||||||
|  | 
 | ||||||
|  | 	repeats = 1; | ||||||
|  | 	fSeq = []; | ||||||
|  | 
 | ||||||
|  | 	repeats.do({arg index; | ||||||
|  | 		var motif; | ||||||
|  | 
 | ||||||
|  | 		motif = []; | ||||||
|  | 
 | ||||||
|  | 		orders.do({arg order, o; | ||||||
|  | 			var lastState, subMotif; | ||||||
|  | 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); | ||||||
|  | 			subMotif = genSubMotif.value(order, o, lastState, isLastOrder: o == (orders.size - 1)); | ||||||
|  | 			motif = motif.add(subMotif); | ||||||
|  | 
 | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		sanityCheck.value(motif, index); | ||||||
|  | 
 | ||||||
|  | 		fSeq = fSeq.add(motif); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSecondarySeq = {arg seq; | ||||||
|  | 	var curdles, fSeq; | ||||||
|  | 	curdles = []; | ||||||
|  | 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); | ||||||
|  | 
 | ||||||
|  | 	fSeq = seq.clumps(curdles).collect({arg clump, m; | ||||||
|  | 		var repeats, paddedSeq; | ||||||
|  | 
 | ||||||
|  | 		//add rest | ||||||
|  | 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); | ||||||
|  | 
 | ||||||
|  | 		//implement repeats | ||||||
|  | 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); | ||||||
|  | 		repeats.collect({paddedSeq}); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------audition funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~addr.sendMsg(~indexPath, ~indexMsg); | ||||||
|  | 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); | ||||||
|  | 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~msg.postln; | ||||||
|  | 		~addr.sendMsg(~path, *~msg); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | genPatterns = {arg inSeq, addr, oneShot = false; | ||||||
|  | 	var voices, durs, pbinds, res, indices, sectionDurs, msg, ids, seq; | ||||||
|  | 	seq = inSeq.collect({arg mSeq; mSeq[0]}); | ||||||
|  | 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	pbinds = voices.flop.collect({arg voice, v; | ||||||
|  | 		var clumps, hdScores, freqs, fDurs; | ||||||
|  | 		clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 		freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 		fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \string_model, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			), | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \sine, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	}).flatten; | ||||||
|  | 	if(oneShot.not, { | ||||||
|  | 		msg = inSeq.collect({arg mSeq, m; mSeq[1..]}); | ||||||
|  | 		//ids = inSeq.collect({arg mSeq, m; mSeq[2]}); | ||||||
|  | 		sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); | ||||||
|  | 		pbinds = pbinds ++ | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \osc, | ||||||
|  | 				\addr, addr, | ||||||
|  | 				\path, "/playing", | ||||||
|  | 				\msg, Pseq(msg, 1), | ||||||
|  | 				\dur, Pseq(sectionDurs, 1) | ||||||
|  | 			); | ||||||
|  | 		] | ||||||
|  | 	}); | ||||||
|  | 	res = Ppar(pbinds); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | genMidiPatterns = {arg seq; | ||||||
|  | 	var voices, durs, patterns, res, mOut, pbRange; | ||||||
|  | 	pbRange = 1; //semitones - change this as needed for your situation | ||||||
|  | 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); | ||||||
|  | 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	res = Ppar( | ||||||
|  | 		voices.flop.collect({arg voice, v; | ||||||
|  | 			var clumps, hdScores, freqs, fDurs; | ||||||
|  | 
 | ||||||
|  | 			mOut.program(v, 70); | ||||||
|  | 
 | ||||||
|  | 			clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \midi, | ||||||
|  | 				\chan, v, | ||||||
|  | 				\noteval, Pseq(freqs.cpsmidi - 24, 1), | ||||||
|  | 				\note, Pfunc({ | event | event[\noteval].floor }), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\midiout, mOut, | ||||||
|  | 				\amp, 1, | ||||||
|  | 				\bend, Pfunc({ | ||||||
|  | 					| event | | ||||||
|  | 					if (event[\note].isRest.not) { | ||||||
|  | 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; | ||||||
|  | 						m.bend(v, pitchbendvalue); | ||||||
|  | 					}; | ||||||
|  | 					0; // return something other than nil to avoid stopping the pattern | ||||||
|  | 				}), | ||||||
|  | 			); | ||||||
|  | 		}); | ||||||
|  | 	); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------resource management funcs | ||||||
|  | 
 | ||||||
|  | genUID = {Date.seed.asHexString.toLower}; | ||||||
|  | 
 | ||||||
|  | seedFunc = {arg func, seed; | ||||||
|  | 	var funcArgs, next; | ||||||
|  | 	next = Routine({loop{func.valueArray(funcArgs).yield }}); | ||||||
|  | 	next.randSeed_(seed); | ||||||
|  | 	{arg ...args; funcArgs = args; next.value} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | stringifyToDepth = {arg data, maxDepth = 1; | ||||||
|  | 	var prettyString = "", rCount = 0, writeArray, indent; | ||||||
|  | 
 | ||||||
|  | 	if(maxDepth == 0, { | ||||||
|  | 		data.asCompileString | ||||||
|  | 	}, { | ||||||
|  | 		indent = {arg size; size.collect({" "}).join("")}; | ||||||
|  | 		writeArray = {arg array; | ||||||
|  | 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; | ||||||
|  | 			rCount = rCount + 1; | ||||||
|  | 			if(rCount < maxDepth, { | ||||||
|  | 				array.do({arg subArray; writeArray.value(subArray)}); | ||||||
|  | 			}, { | ||||||
|  | 				prettyString = prettyString ++ array.collect({arg subArray; | ||||||
|  | 					indent.value(rCount + 1) ++ subArray.asCompileString | ||||||
|  | 				}).join(",\n"); | ||||||
|  | 			}); | ||||||
|  | 			rCount = rCount - 1; | ||||||
|  | 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		writeArray.value(data); | ||||||
|  | 		prettyString.replace(",\n\n", "\n").drop(-2); | ||||||
|  | 	}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | sanityCheck = {arg motif, index; | ||||||
|  | 	//print functions = very helpful | ||||||
|  | 	("----------" + index + "------------").postln; | ||||||
|  | 
 | ||||||
|  | 	motif.flatten.do({arg val, v; | ||||||
|  | 		if(v > 0, { | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); | ||||||
|  | 		}); | ||||||
|  | 		val.postln | ||||||
|  | 	}); | ||||||
|  | 	"***********".postln; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; | ||||||
|  | 	var res; | ||||||
|  | 
 | ||||||
|  | 	res = in; | ||||||
|  | 	if(res.isNil.not, { | ||||||
|  | 		if((res.isArray && res.isString.not), { | ||||||
|  | 			res = res.asCompileString; | ||||||
|  | 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); | ||||||
|  | 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); | ||||||
|  | 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); | ||||||
|  | 			res = res.replace("Rest", "\"Rest\""); | ||||||
|  | 			res = res.interpret; | ||||||
|  | 		}, { | ||||||
|  | 			//res.postln; | ||||||
|  | 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | writeResources = {arg path, dict; | ||||||
|  | 	var file, modelItems, resString; | ||||||
|  | 	file = File(path,"w"); | ||||||
|  | 
 | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	resString = nameSpaces.collect({arg nameSpace; | ||||||
|  | 		var depth = 0, insert = " "; | ||||||
|  | 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "order", {depth = 1; insert = "\n"}); | ||||||
|  | 		if((nameSpace == "ref_uid") && (dict[nameSpace] == nil), {dict[nameSpace] = "nil"}); | ||||||
|  | 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(dict[nameSpace], depth) | ||||||
|  | 	}).join(",\n"); | ||||||
|  | 
 | ||||||
|  | 	resString = "{\n" ++ resString ++ "\n}"; | ||||||
|  | 
 | ||||||
|  | 	file.write(resString); | ||||||
|  | 	file.close; | ||||||
|  | 	resString | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; | ||||||
|  | 
 | ||||||
|  | loadModelJSON = {arg jsonObject; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS; nS->msgInterpret.value(jsonObject[nS])})); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | setGlobalVars = {arg dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	# seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 	entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 	motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | globalVarsToDict = { | ||||||
|  | 	var modelItems, dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerFile = {arg path; | ||||||
|  | 	ledgerPath = path; | ||||||
|  | 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; | ||||||
|  | 
 | ||||||
|  | saveLedger = {arg ledger, path; | ||||||
|  | 	var file; | ||||||
|  | 	file = File(path, "w"); | ||||||
|  | 	file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); | ||||||
|  | 	file.close; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------global vars | ||||||
|  | 
 | ||||||
|  | primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; | ||||||
|  | //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; | ||||||
|  | exPath = thisProcess.nowExecutingPath; | ||||||
|  | dir = exPath.dirname; | ||||||
|  | //popSize = 4; | ||||||
|  | dims = primes.size; | ||||||
|  | tuples = genTuples.value(); | ||||||
|  | //refUID = nil; | ||||||
|  | group = Group.new; | ||||||
|  | ~group = group; | ||||||
|  | loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); | ||||||
|  | //passagesWeights = [1, 1, 1, 1, 1]; | ||||||
|  | //susWeights = [1, 1, 1]; | ||||||
|  | // order really matters!!!! | ||||||
|  | nameSpaces = [ | ||||||
|  | 	"music_data", "last_changes", "cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", | ||||||
|  | 	"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", | ||||||
|  | 	"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", | ||||||
|  | 	"motif_edited", "order_edited" | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------OSC funcs | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_ledger, {arg msg, time, addr, port; | ||||||
|  | 	loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \load_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_model, {arg msg, time, addr, port; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = loadModelFile.value(msg[1].asString); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | }, \load_model); | ||||||
|  | 
 | ||||||
|  | OSCdef(\save_ledger, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	ledger = msgInterpret.value(msg[1].asString.parseJSON["ledger"], false).postln; | ||||||
|  | 	//loadLedgerJSON.value(msg[0]) | ||||||
|  | 	saveLedger.value(ledger, msg[2].asString); | ||||||
|  | 	//loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \save_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\generate, {arg msg, time, addr, port; | ||||||
|  | 	var path, dict, durSeeds, musPath, modelString; | ||||||
|  | 	msg.postln; | ||||||
|  | 
 | ||||||
|  | 	path = msg[1].asString; | ||||||
|  | 
 | ||||||
|  | 	dict = loadModelFile.value(path); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | 
 | ||||||
|  | 	popSize = ranges.size; | ||||||
|  | 
 | ||||||
|  | 	//refUID.postln; | ||||||
|  | 
 | ||||||
|  | 	loadLedgerFile.value(ledgerPath); | ||||||
|  | 	if(ledger == nil, {ledger = ["tmp"]}); | ||||||
|  | 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); | ||||||
|  | 
 | ||||||
|  | 	lastXChanges = if(refUID == nil, { | ||||||
|  | 		[initVoices.value().deepCopy]; | ||||||
|  | 	}, { | ||||||
|  | 		var file; | ||||||
|  | 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); | ||||||
|  | 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	durSeeds = seedFunc.value({3.collect({rrand(100000, 999999)})}, durSeed).value.postln; | ||||||
|  | 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..4] ++ [entrancesProbVals[5..]] ++ [durSeeds[0]]); | ||||||
|  | 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..4] ++ [passagesProbVals[5..]] ++ [durSeeds[1]]); | ||||||
|  | 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..4] ++ [exitsProbVals[5..]] ++ [durSeeds[2]]); | ||||||
|  | 
 | ||||||
|  | 	if(orders == nil, { | ||||||
|  | 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); | ||||||
|  | 		//addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); | ||||||
|  | 	}); | ||||||
|  | 	seq = seedFunc.value(genMotif, motifSeed).value; | ||||||
|  | 
 | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	modelString = writeResources.value(path, dict); | ||||||
|  | 
 | ||||||
|  | 	//addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); | ||||||
|  | 	addr.sendMsg("/generated", path, modelString, ledgerPath); | ||||||
|  | }, \generate); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | OSCdef(\commit, {arg msg, time, addr, port; | ||||||
|  | 	var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; | ||||||
|  | 	//msg.postln; | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	test1 = msg[1].asString.parseJSON; | ||||||
|  | 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; | ||||||
|  | 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; | ||||||
|  | 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; | ||||||
|  | 	(test1["music"] == test2["music_data"]).postln; | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; | ||||||
|  | 	musicChanged = (musicData != seq).postln; | ||||||
|  | 
 | ||||||
|  | 	curUID = genUID.value; | ||||||
|  | 
 | ||||||
|  | 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); | ||||||
|  | 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); | ||||||
|  | 
 | ||||||
|  | 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	if(musicChanged, { | ||||||
|  | 		seq = musicData; | ||||||
|  | 		dict["music_data"] = seq; | ||||||
|  | 		dict["motif_edited"] = "true" | ||||||
|  | 	}); | ||||||
|  | 	dict["cur_uid"] = curUID; | ||||||
|  | 
 | ||||||
|  | 	writeResources.value(modelPath, dict); | ||||||
|  | 
 | ||||||
|  | 	File.delete(ledgerPath ++ "_bak"); | ||||||
|  | 	File.copy(ledgerPath, ledgerPath ++ "_bak"); | ||||||
|  | 	File.delete(ledgerPath); | ||||||
|  | 	ledger = ledger.drop(-1).add(curUID); | ||||||
|  | 
 | ||||||
|  | 	saveLedger.value(ledger, ledgerPath); | ||||||
|  | 
 | ||||||
|  | 	addr.sendMsg("/committed", curUID, ledgerPath); | ||||||
|  | 	//refUID = curUID; | ||||||
|  | 
 | ||||||
|  | }, \commit); | ||||||
|  | 
 | ||||||
|  | OSCdef(\transport, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	if(msg[1] == 0, { | ||||||
|  | 		player.stop; | ||||||
|  | 		group.set(\gate, 0); | ||||||
|  | 	}, { | ||||||
|  | 		// the cued sequence can now be read from file, so this can be cleaned up | ||||||
|  | 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; | ||||||
|  | 		if(msg[1] == 1, { | ||||||
|  | 			pSeq = []; | ||||||
|  | 			cuedSeek = (seq != nil); | ||||||
|  | 			indexStart = msg[2].asInteger; | ||||||
|  | 			indexEnd = ledger.size - if(cuedSeek, {2}, {1}); | ||||||
|  | 			//ledger.postln; | ||||||
|  | 			if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { | ||||||
|  | 				ledger[indexStart..indexEnd].do({arg uid, index; | ||||||
|  | 					var path, file; | ||||||
|  | 					path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 					file = File(path, "r"); | ||||||
|  | 					pSeq = pSeq.add([msgInterpret.value(file.readAllString.postln.parseJSON["music_data"]), path, indexStart + index, uid]); | ||||||
|  | 					file.close; | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if(cuedSeek, { | ||||||
|  | 				var path, file; | ||||||
|  | 				path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; | ||||||
|  | 				file = File(path, "r"); | ||||||
|  | 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, ledger.size - 1, "tmp"]); | ||||||
|  | 				file.close; | ||||||
|  | 			}); | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr); | ||||||
|  | 		}, { | ||||||
|  | 			pSeq = [loadModelJSON.value(msg[2].asString.parseJSON)["music_data"].postln]; | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr, true); | ||||||
|  | 		}); | ||||||
|  | 		player = Pfset(pattern: patterns, cleanupFunc: { | ||||||
|  | 			addr.sendMsg("/transport", 0); | ||||||
|  | 			addr.sendMsg("/one_shot", 0); | ||||||
|  | 		}); | ||||||
|  | 		player = player.play | ||||||
|  | 	}); | ||||||
|  | }, \transport); | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | //synthdefs | ||||||
|  | ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sineBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~bassBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~hdustBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~samplerBusArray = 2.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sBuf = Buffer.alloc(s, 10, 2); | ||||||
|  | SynthDef(\string_model, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~stringModelBusArray), sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | 	//Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var sig; | ||||||
|  | 	sig = SinOsc.ar(freq); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.asr(0.3, 0.4, 0.3), gate, timeScale: dur, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; | ||||||
|  | 	var nameSpaces, sigs, hierarchicalDust; | ||||||
|  | 
 | ||||||
|  | 	hierarchicalDust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	sigs = [~stringModelBusArray, ~sineBusArray, ~bassBusArray, ~hdustBusArray, ~samplerBusArray].collect({arg busArray, i; | ||||||
|  | 		var nameSpace, sig; | ||||||
|  | 		nameSpace = ['string', 'sine', 'bass', 'hdust', 'sampler'][i]; | ||||||
|  | 		sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = Mix.ar(sig) * pow(NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.1), 2); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	sigs = Mix.ar(sigs / 4); | ||||||
|  | 	Out.ar(0, sigs) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\bass, { | ||||||
|  | 	var switches, drone; | ||||||
|  | 	switches = {|i| Dust.kr(0.1)} ! 9; | ||||||
|  | 	drone = {|i| var harm = pow(2, 2 - (i / 3).trunc), amp = (1 / pow(harm, 2)); | ||||||
|  | 		SinOsc.ar(60 * harm + TRand.kr(-3, 3, switches[i]), 0, amp)} ! 9; | ||||||
|  | 	Out.ar(~bassBusArray[0], Mix.new(drone) * 0.2); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sampler, { | ||||||
|  | 	Out.ar(~samplerBusArray, PlayBuf.ar(2, ~sBuf, BufRateScale.kr(~sBuf), doneAction: 2)) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | // main routine | ||||||
|  | SynthDef(\hdust, { | ||||||
|  | 	arg gate = 0; | ||||||
|  | 	var hierarchical_dust, low_sine, high_sine, brown_noise, white_noise; | ||||||
|  | 	// this triggers the combinations of sources | ||||||
|  | 	// it is similar to the Supercollider UGen called dust but with a hierarchical structure | ||||||
|  | 	hierarchical_dust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(0.1)) | ||||||
|  | 	); | ||||||
|  | 	// adjust the multiplier at the end of each line for adjusting levels | ||||||
|  | 	// note with each trigger, each source has a 1 in 3 chance of sounding | ||||||
|  | 	low_sine = SinOsc.ar(76.midicps / 16) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.1; | ||||||
|  | 	high_sine = SinOsc.ar(76.midicps * 8) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.01; | ||||||
|  | 	brown_noise = BrownNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.025; | ||||||
|  | 	white_noise = WhiteNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.02; | ||||||
|  | 	Out.ar(~hdustBusArray[0], | ||||||
|  | 		((low_sine + high_sine + brown_noise + white_noise) ) | ||||||
|  | 	); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | var bass, hdust, sampler, mixer; | ||||||
|  | bass = Synth.tail(~group, \bass); | ||||||
|  | hdust = Synth.tail(~group, \hdust); | ||||||
|  | sampler = Synth.head(~group, \sampler); | ||||||
|  | mixer = Synth.tail(~group, \mixer); | ||||||
|  | OSCdef(\mixer, {arg msg, time, addr, port; | ||||||
|  | 	mixer.set((msg[1] ++ '_' ++ msg[2] ++ '_' ++ msg[3]), msg[4]) | ||||||
|  | }, \mixer); | ||||||
|  | 
 | ||||||
|  | OSCdef(\sampler, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	sampler.free; | ||||||
|  | 	~sBuf.free; | ||||||
|  | 	~sBuf = Buffer.read(s, msg[1].asString.postln, action: {sampler = Synth.head(~group, \sampler)}); | ||||||
|  | }, \sampler); | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /* old something | ||||||
|  | ( | ||||||
|  | SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	freq = WhiteNoise.ar * 3 + freq; | ||||||
|  | 	freqFinal = Duty.ar((1/freq), 0, freq); | ||||||
|  | 	trig = Changed.ar(freqFinal); | ||||||
|  | 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); | ||||||
|  | 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); | ||||||
|  | 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 
 | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | ) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| @ -0,0 +1,43 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 3.625 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.75 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 4.125 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 2.375 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.25 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.75 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "5625a95a", | ||||||
|  | "ref_uid": "nil", | ||||||
|  | "order_seed": 871476, | ||||||
|  | "dur_seed": 417039, | ||||||
|  | "motifs_seed": 168381, | ||||||
|  | "entrances_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ 1419.1950464396, 2400 ], [ 1519.5046439628, 2400 ], [ 1541.7956656347, 2237 ], [ 1519.5046439628, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 3, 1 ], [ 2, 2 ], [  ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.75, 0.69, 0.75 ], | ||||||
|  | "order_size": [ 1, 2 ], | ||||||
|  | "passages_size": [ 0, 2 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,49 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ -2, 3, -2, 1, 1, 1 ], [ "Rest" ], [ "Rest" ] ], 0.125 ], | ||||||
|  |     [ [ [ -5, 3, -2, 2, 1, 1 ], [ -2, 3, -2, 1, 1, 1 ], [ "Rest" ], [ "Rest" ] ], 0.5 ], | ||||||
|  |     [ [ [ -5, 3, -2, 2, 1, 1 ], [ -2, 3, -2, 1, 1, 1 ], [ "Rest" ], [ -4, 5, -2, 2, 2, -1 ] ], 0.625 ], | ||||||
|  |     [ [ [ -5, 3, -2, 2, 1, 1 ], [ -2, 3, -2, 1, 1, 1 ], [ -2, 2, -2, 1, 1, 1 ], [ -4, 5, -2, 2, 2, -1 ] ], 5.625 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ -5, 3, -2, 2, 1, 1 ], [ -2, 3, -2, 1, 1, 1 ], [ -3, 4, -2, 2, 2, -1 ], [ -4, 5, -2, 2, 2, -1 ] ], 1.125 ], | ||||||
|  |     [ [ [ -5, 3, -2, 2, 1, 1 ], [ -3, 3, -1, 2, 1, 1 ], [ -3, 4, -2, 2, 2, -1 ], [ -4, 5, -2, 2, 2, -1 ] ], 2.5 ], | ||||||
|  |     [ [ [ -5, 3, -2, 2, 1, 1 ], [ -3, 3, -1, 2, 1, 1 ], [ -3, 4, -2, 2, 2, -1 ], [ "Rest" ] ], 1.375 ], | ||||||
|  |     [ [ [ "Rest" ], [ -3, 3, -1, 2, 1, 1 ], [ -3, 4, -2, 2, 2, -1 ], [ "Rest" ] ], 0.75 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ -3, 4, -2, 2, 2, -1 ], [ "Rest" ] ], 0 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.125 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ -5, 3, -2, 2, 1, 1 ], [ -4, 5, -2, 3, 2, -1 ], [ -4, 3, -2, 3, 1, 1 ], [ -4, 5, -2, 2, 2, -1 ] ], | ||||||
|  |   [ [ -5, 3, -2, 2, 1, 1 ], [ -2, 3, -2, 1, 1, 1 ], [ -4, 3, -2, 3, 1, 1 ], [ -4, 5, -2, 2, 2, -1 ] ], | ||||||
|  |   [ [ -5, 3, -2, 2, 1, 1 ], [ -2, 3, -2, 1, 1, 1 ], [ -2, 2, -2, 1, 1, 1 ], [ -4, 5, -2, 2, 2, -1 ] ], | ||||||
|  |   [ [ -5, 3, -2, 2, 1, 1 ], [ -2, 3, -2, 1, 1, 1 ], [ -3, 4, -2, 2, 2, -1 ], [ -4, 5, -2, 2, 2, -1 ] ], | ||||||
|  |   [ [ -5, 3, -2, 2, 1, 1 ], [ -3, 3, -1, 2, 1, 1 ], [ -3, 4, -2, 2, 2, -1 ], [ -4, 5, -2, 2, 2, -1 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "6409252e", | ||||||
|  | "ref_uid": "tmp", | ||||||
|  | "order_seed": 825836, | ||||||
|  | "dur_seed": 453411, | ||||||
|  | "motifs_seed": 115471, | ||||||
|  | "entrances_probs_vals": [ 0.29, 0, 1.3492063492064, 0, 0.65934065934066, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0.29, 0, 5, 0.58, 1.7582417582418, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0.29, 0, 5, 0.58, 1.7582417582418, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ -3600, -349 ], [ 799, 1758 ], [ -282, 1013 ], [ -282, 799 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 1, 0, 3 ], [ 2 ], [  ] ], | ||||||
|  |   [ [ 3, 0 ], [ 2, 1 ], [  ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.39, 0.32, 0.77 ], | ||||||
|  | "order_size": [ 1, 3 ], | ||||||
|  | "passages_size": [ 0, 0 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,887 @@ | |||||||
|  | ( | ||||||
|  | // helper funcs | ||||||
|  | var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; | ||||||
|  | 
 | ||||||
|  | // score funcs | ||||||
|  | var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; | ||||||
|  | 
 | ||||||
|  | // subroutines | ||||||
|  | var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; | ||||||
|  | 
 | ||||||
|  | // primary routines | ||||||
|  | var genMotif, genSecondarySeq; | ||||||
|  | 
 | ||||||
|  | // audition funcs | ||||||
|  | var genPatterns, genMidiPatterns; | ||||||
|  | 
 | ||||||
|  | // resource management funcs | ||||||
|  | var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, | ||||||
|  | msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON, | ||||||
|  | setGlobalVars, globalVarsToDict, saveLedger; | ||||||
|  | 
 | ||||||
|  | // model vars | ||||||
|  | //(model and global vars mostly set by OSC funcs | ||||||
|  | var seq, lastXChanges, | ||||||
|  | curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | motifEdited, orderEdited; | ||||||
|  | 
 | ||||||
|  | // model aux vars | ||||||
|  | var entrancesDurFunc, passagesDurFunc, exitsDurFunc; | ||||||
|  | 
 | ||||||
|  | // other global vars | ||||||
|  | var popSize, exPath, dir, primes, dims, tuples, | ||||||
|  | group, player, ledgerPath, ledger, currentlyPlayingUID, | ||||||
|  | nameSpaces; | ||||||
|  | 
 | ||||||
|  | // install JSON quark | ||||||
|  | if(Quarks.isInstalled("JSONlib").not, { | ||||||
|  | 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); | ||||||
|  | 	thisProcess.recompile; | ||||||
|  | 	//HelpBrowser.openHelpFor("Classes/JSONlib"); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------helper funcs | ||||||
|  | 
 | ||||||
|  | hsArrayToCents = { | ||||||
|  | 	arg hsArray; | ||||||
|  | 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pDist = { | ||||||
|  | 	arg array1, array2, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); | ||||||
|  | 	if(signed, {pDistance}, {abs(pDistance)}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hdSum = { | ||||||
|  | 	arg hsArrays; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays.size; | ||||||
|  | 	distances = (size - 1).collect({arg i; | ||||||
|  | 		((i + 1)..(size - 1)).collect({arg j; | ||||||
|  | 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsChordalDistance = { | ||||||
|  | 	arg hsArrays1, hsArrays2; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays1.size; | ||||||
|  | 	distances = hsArrays1.size.collect({arg i; | ||||||
|  | 		hsArrays2.size.collect({arg j; | ||||||
|  | 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsArrayToFreq = { | ||||||
|  | 	arg array; | ||||||
|  | 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------score funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | isInRange = { | ||||||
|  | 	arg hsArray, min, max; | ||||||
|  | 	var cents; | ||||||
|  | 	cents = hsArrayToCents.value(hsArray); | ||||||
|  | 	(cents >= min) && (cents <= max) | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | spacingScore = { | ||||||
|  | 	arg hsArrays, min; | ||||||
|  | 	var centsArray; | ||||||
|  | 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); | ||||||
|  | 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | rangeScore = { | ||||||
|  | 	arg hsArray1, hsArray2, min, max, low, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | intervalScore = { | ||||||
|  | 	arg hsArray1, hsArray2, mean, sd, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	pDistance.gaussCurve(1, mean, sd) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | inclusionScore = { | ||||||
|  | 	arg array, test, min = 0.01; | ||||||
|  | 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------subroutines | ||||||
|  | 
 | ||||||
|  | genTuples = { | ||||||
|  | 	var tuples; | ||||||
|  | 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); | ||||||
|  | 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | initVoices = { | ||||||
|  | 	var init, voicesInit; | ||||||
|  | 	voicesInit = popSize.collect({dims.collect({0})}); | ||||||
|  | 	/* | ||||||
|  | 	voicesInit = [dims.collect({0})]; | ||||||
|  | 	(popSize - 1).do({ | ||||||
|  | 		arg rep, new; | ||||||
|  | 		rep = dims.rand; | ||||||
|  | 		new = voicesInit.last.deepCopy; | ||||||
|  | 		new[rep] = new[rep] + [-1, 1].choose(); | ||||||
|  | 		voicesInit = voicesInit.add(new); | ||||||
|  | 	}); | ||||||
|  | 	*/ | ||||||
|  | 	voicesInit.deepCopy; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; | ||||||
|  | 	var env, pTable, durFunc; | ||||||
|  | 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; | ||||||
|  | 	pTable = env.asRandomTable; | ||||||
|  | 	[chordProb, minPad, maxPad, minDur, maxDur, envData].postln; | ||||||
|  | 	durFunc = {arg allowChord, pad = false; | ||||||
|  | 		var res; | ||||||
|  | 		res = if(allowChord.not, { | ||||||
|  | 			pTable.tableRand * (maxDur - minDur) + minDur | ||||||
|  | 		}, { | ||||||
|  | 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (maxDur - minDur) + minDur}); | ||||||
|  | 		}).round(0.125); | ||||||
|  | 		if(pad, {res = res + rrand(minPad.asFloat, maxPad.asFloat).round(0.125)}); | ||||||
|  | 		if(res.asInteger == res, {res = res.asInteger}); | ||||||
|  | 		res | ||||||
|  | 	}; | ||||||
|  | 	seedFunc.value(durFunc, seed); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; | ||||||
|  | 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ | ||||||
|  | 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; | ||||||
|  | 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); | ||||||
|  | 		noProgIns = (popSize - noSusIns).rand + 1; | ||||||
|  | 		noSilentIns = popSize - noSusIns - noProgIns; | ||||||
|  | 
 | ||||||
|  | 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); | ||||||
|  | 
 | ||||||
|  | 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); | ||||||
|  | 		if(silent == nil, {silent = []}); | ||||||
|  | 		[sus.scramble, prog, silent.scramble] | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | updateVoices = {arg ins, sus; | ||||||
|  | 	var voices, candidates, nWeights, nProbs, sel; | ||||||
|  | 
 | ||||||
|  | 	voices = lastXChanges.deepCopy.last; | ||||||
|  | 
 | ||||||
|  | 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; | ||||||
|  | 	candidates = difference(candidates.asSet, voices.asSet).asList; | ||||||
|  | 	nProbs = candidates.collect({arg candidate; | ||||||
|  | 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; | ||||||
|  | 
 | ||||||
|  | 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); | ||||||
|  | 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); | ||||||
|  | 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); | ||||||
|  | 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); | ||||||
|  | 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); | ||||||
|  | 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); | ||||||
|  | 		//maybe what you want here is a vector to another root and then favoring movement towards it. | ||||||
|  | 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); | ||||||
|  | 
 | ||||||
|  | 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	nWeights = passagesWeights; | ||||||
|  | 
 | ||||||
|  | 	//this handles nWeights of 0; mainly for testing | ||||||
|  | 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; | ||||||
|  | 	nWeights = nWeights.select({arg weight; weight != 0}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; | ||||||
|  | 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) | ||||||
|  | 	}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; | ||||||
|  | 
 | ||||||
|  | 	sel = candidates.wchoose(nProbs); | ||||||
|  | 
 | ||||||
|  | 	voices[ins] = sel; | ||||||
|  | 	lastXChanges = lastXChanges.add(voices).keep(-5); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; | ||||||
|  | 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, pad, lastXChangesHold, voices, adder; | ||||||
|  | 	# sus, prog, silent = order; | ||||||
|  | 	flatOrder = silent ++ sus ++ prog; | ||||||
|  | 	lastXChangesHold = lastXChanges.deepCopy; | ||||||
|  | 	voices = lastState.deepCopy; | ||||||
|  | 	isInChord = popSize.collect({false}); | ||||||
|  | 	allowChord = false; | ||||||
|  | 	pad = false; | ||||||
|  | 	res = []; | ||||||
|  | 	"------generating motif".postln; | ||||||
|  | 	//need to figure out here if voices move between motifs | ||||||
|  | 	flatOrder.do({arg ins, i; | ||||||
|  | 
 | ||||||
|  | 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); | ||||||
|  | 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); | ||||||
|  | 
 | ||||||
|  | 		if(voices[ins] != adder, { | ||||||
|  | 			var dur; | ||||||
|  | 
 | ||||||
|  | 			if((sus ++ silent).includes(ins), { | ||||||
|  | 				allowChord = (ins != sus.last); | ||||||
|  | 				pad = (ins == sus.last); | ||||||
|  | 			}, { | ||||||
|  | 				if(i < (flatOrder.size - 1), { | ||||||
|  | 					allowChord = (isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not; | ||||||
|  | 					pad = false; | ||||||
|  | 				}, { | ||||||
|  | 					allowChord = false; | ||||||
|  | 					pad = true | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if((orderIndex == 0) && sus.includes(ins), { | ||||||
|  | 				dur = entrancesDurFunc.value(allowChord, pad); | ||||||
|  | 			}, { | ||||||
|  | 				dur = passagesDurFunc.value(allowChord, pad); | ||||||
|  | 			}); | ||||||
|  | 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); | ||||||
|  | 
 | ||||||
|  | 			voices[ins] = adder; | ||||||
|  | 			res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// pad ending | ||||||
|  | 	if(orderIndex == (orders.size - 1), { | ||||||
|  | 		(0..(popSize-1)).scramble.do({arg ins; | ||||||
|  | 			if(res.last.first[ins] != ["Rest"], { | ||||||
|  | 				var dur; | ||||||
|  | 				voices[ins] = ["Rest"]; | ||||||
|  | 				allowChord = (voices != popSize.collect({["Rest"]})); | ||||||
|  | 				pad = allowChord.not; | ||||||
|  | 				dur = exitsDurFunc.value(allowChord, pad); | ||||||
|  | 				res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	//format and return | ||||||
|  | 	if(startFromLast, {lastXChanges = lastXChangesHold}); | ||||||
|  | 	res; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------primary routines | ||||||
|  | 
 | ||||||
|  | genMotif = { | ||||||
|  | 	var repeats, fSeq; | ||||||
|  | 
 | ||||||
|  | 	repeats = 1; | ||||||
|  | 	fSeq = []; | ||||||
|  | 
 | ||||||
|  | 	repeats.do({arg index; | ||||||
|  | 		var motif; | ||||||
|  | 
 | ||||||
|  | 		motif = []; | ||||||
|  | 
 | ||||||
|  | 		orders.do({arg order, o; | ||||||
|  | 			var lastState, subMotif; | ||||||
|  | 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); | ||||||
|  | 			subMotif = genSubMotif.value(order, o, lastState, isLastOrder: o == (orders.size - 1)); | ||||||
|  | 			motif = motif.add(subMotif); | ||||||
|  | 
 | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		sanityCheck.value(motif, index); | ||||||
|  | 
 | ||||||
|  | 		fSeq = fSeq.add(motif); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSecondarySeq = {arg seq; | ||||||
|  | 	var curdles, fSeq; | ||||||
|  | 	curdles = []; | ||||||
|  | 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); | ||||||
|  | 
 | ||||||
|  | 	fSeq = seq.clumps(curdles).collect({arg clump, m; | ||||||
|  | 		var repeats, paddedSeq; | ||||||
|  | 
 | ||||||
|  | 		//add rest | ||||||
|  | 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); | ||||||
|  | 
 | ||||||
|  | 		//implement repeats | ||||||
|  | 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); | ||||||
|  | 		repeats.collect({paddedSeq}); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------audition funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~addr.sendMsg(~indexPath, ~indexMsg); | ||||||
|  | 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); | ||||||
|  | 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~msg.postln; | ||||||
|  | 		~addr.sendMsg(~path, *~msg); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | genPatterns = {arg inSeq, addr, oneShot = false; | ||||||
|  | 	var voices, durs, pbinds, res, indices, sectionDurs, msg, ids, seq; | ||||||
|  | 	seq = inSeq.collect({arg mSeq; mSeq[0]}); | ||||||
|  | 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	pbinds = voices.flop.collect({arg voice, v; | ||||||
|  | 		var clumps, hdScores, freqs, fDurs; | ||||||
|  | 		clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 		freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 		fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \string_model, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			), | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \sine, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	}).flatten; | ||||||
|  | 	if(oneShot.not, { | ||||||
|  | 		msg = inSeq.collect({arg mSeq, m; mSeq[1..]}); | ||||||
|  | 		//ids = inSeq.collect({arg mSeq, m; mSeq[2]}); | ||||||
|  | 		sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); | ||||||
|  | 		pbinds = pbinds ++ | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \osc, | ||||||
|  | 				\addr, addr, | ||||||
|  | 				\path, "/playing", | ||||||
|  | 				\msg, Pseq(msg, 1), | ||||||
|  | 				\dur, Pseq(sectionDurs, 1) | ||||||
|  | 			); | ||||||
|  | 		] | ||||||
|  | 	}); | ||||||
|  | 	res = Ppar(pbinds); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | genMidiPatterns = {arg seq; | ||||||
|  | 	var voices, durs, patterns, res, mOut, pbRange; | ||||||
|  | 	pbRange = 1; //semitones - change this as needed for your situation | ||||||
|  | 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); | ||||||
|  | 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	res = Ppar( | ||||||
|  | 		voices.flop.collect({arg voice, v; | ||||||
|  | 			var clumps, hdScores, freqs, fDurs; | ||||||
|  | 
 | ||||||
|  | 			mOut.program(v, 70); | ||||||
|  | 
 | ||||||
|  | 			clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \midi, | ||||||
|  | 				\chan, v, | ||||||
|  | 				\noteval, Pseq(freqs.cpsmidi - 24, 1), | ||||||
|  | 				\note, Pfunc({ | event | event[\noteval].floor }), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\midiout, mOut, | ||||||
|  | 				\amp, 1, | ||||||
|  | 				\bend, Pfunc({ | ||||||
|  | 					| event | | ||||||
|  | 					if (event[\note].isRest.not) { | ||||||
|  | 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; | ||||||
|  | 						m.bend(v, pitchbendvalue); | ||||||
|  | 					}; | ||||||
|  | 					0; // return something other than nil to avoid stopping the pattern | ||||||
|  | 				}), | ||||||
|  | 			); | ||||||
|  | 		}); | ||||||
|  | 	); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------resource management funcs | ||||||
|  | 
 | ||||||
|  | genUID = {Date.seed.asHexString.toLower}; | ||||||
|  | 
 | ||||||
|  | seedFunc = {arg func, seed; | ||||||
|  | 	var funcArgs, next; | ||||||
|  | 	next = Routine({loop{func.valueArray(funcArgs).yield }}); | ||||||
|  | 	next.randSeed_(seed); | ||||||
|  | 	{arg ...args; funcArgs = args; next.value} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | stringifyToDepth = {arg data, maxDepth = 1; | ||||||
|  | 	var prettyString = "", rCount = 0, writeArray, indent; | ||||||
|  | 
 | ||||||
|  | 	if(maxDepth == 0, { | ||||||
|  | 		data.asCompileString | ||||||
|  | 	}, { | ||||||
|  | 		indent = {arg size; size.collect({" "}).join("")}; | ||||||
|  | 		writeArray = {arg array; | ||||||
|  | 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; | ||||||
|  | 			rCount = rCount + 1; | ||||||
|  | 			if(rCount < maxDepth, { | ||||||
|  | 				array.do({arg subArray; writeArray.value(subArray)}); | ||||||
|  | 			}, { | ||||||
|  | 				prettyString = prettyString ++ array.collect({arg subArray; | ||||||
|  | 					indent.value(rCount + 1) ++ subArray.asCompileString | ||||||
|  | 				}).join(",\n"); | ||||||
|  | 			}); | ||||||
|  | 			rCount = rCount - 1; | ||||||
|  | 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		writeArray.value(data); | ||||||
|  | 		prettyString.replace(",\n\n", "\n").drop(-2); | ||||||
|  | 	}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | sanityCheck = {arg motif, index; | ||||||
|  | 	//print functions = very helpful | ||||||
|  | 	("----------" + index + "------------").postln; | ||||||
|  | 
 | ||||||
|  | 	motif.flatten.do({arg val, v; | ||||||
|  | 		if(v > 0, { | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); | ||||||
|  | 		}); | ||||||
|  | 		val.postln | ||||||
|  | 	}); | ||||||
|  | 	"***********".postln; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; | ||||||
|  | 	var res; | ||||||
|  | 
 | ||||||
|  | 	res = in; | ||||||
|  | 	if(res.isNil.not, { | ||||||
|  | 		if((res.isArray && res.isString.not), { | ||||||
|  | 			res = res.asCompileString; | ||||||
|  | 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); | ||||||
|  | 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); | ||||||
|  | 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); | ||||||
|  | 			res = res.replace("Rest", "\"Rest\""); | ||||||
|  | 			res = res.interpret; | ||||||
|  | 		}, { | ||||||
|  | 			//res.postln; | ||||||
|  | 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | writeResources = {arg path, dict; | ||||||
|  | 	var file, modelItems, resString; | ||||||
|  | 	file = File(path,"w"); | ||||||
|  | 
 | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	resString = nameSpaces.collect({arg nameSpace; | ||||||
|  | 		var depth = 0, insert = " "; | ||||||
|  | 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "order", {depth = 1; insert = "\n"}); | ||||||
|  | 		if((nameSpace == "ref_uid") && (dict[nameSpace] == nil), {dict[nameSpace] = "nil"}); | ||||||
|  | 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(dict[nameSpace], depth) | ||||||
|  | 	}).join(",\n"); | ||||||
|  | 
 | ||||||
|  | 	resString = "{\n" ++ resString ++ "\n}"; | ||||||
|  | 
 | ||||||
|  | 	file.write(resString); | ||||||
|  | 	file.close; | ||||||
|  | 	resString | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; | ||||||
|  | 
 | ||||||
|  | loadModelJSON = {arg jsonObject; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS; nS->msgInterpret.value(jsonObject[nS])})); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | setGlobalVars = {arg dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	# seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 	entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 	motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | globalVarsToDict = { | ||||||
|  | 	var modelItems, dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerFile = {arg path; | ||||||
|  | 	ledgerPath = path; | ||||||
|  | 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; | ||||||
|  | 
 | ||||||
|  | saveLedger = {arg ledger, path; | ||||||
|  | 	var file; | ||||||
|  | 	file = File(path, "w"); | ||||||
|  | 	file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); | ||||||
|  | 	file.close; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------global vars | ||||||
|  | 
 | ||||||
|  | primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; | ||||||
|  | //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; | ||||||
|  | exPath = thisProcess.nowExecutingPath; | ||||||
|  | dir = exPath.dirname; | ||||||
|  | //popSize = 4; | ||||||
|  | dims = primes.size; | ||||||
|  | tuples = genTuples.value(); | ||||||
|  | //refUID = nil; | ||||||
|  | group = Group.new; | ||||||
|  | ~group = group; | ||||||
|  | loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); | ||||||
|  | //passagesWeights = [1, 1, 1, 1, 1]; | ||||||
|  | //susWeights = [1, 1, 1]; | ||||||
|  | // order really matters!!!! | ||||||
|  | nameSpaces = [ | ||||||
|  | 	"music_data", "last_changes", "cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", | ||||||
|  | 	"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", | ||||||
|  | 	"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", | ||||||
|  | 	"motif_edited", "order_edited" | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------OSC funcs | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_ledger, {arg msg, time, addr, port; | ||||||
|  | 	loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \load_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_model, {arg msg, time, addr, port; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = loadModelFile.value(msg[1].asString); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | }, \load_model); | ||||||
|  | 
 | ||||||
|  | OSCdef(\save_ledger, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	ledger = msgInterpret.value(msg[1].asString.parseJSON["ledger"], false).postln; | ||||||
|  | 	//loadLedgerJSON.value(msg[0]) | ||||||
|  | 	saveLedger.value(ledger, msg[2].asString); | ||||||
|  | 	//loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \save_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\generate, {arg msg, time, addr, port; | ||||||
|  | 	var path, dict, durSeeds, musPath, modelString; | ||||||
|  | 	msg.postln; | ||||||
|  | 
 | ||||||
|  | 	path = msg[1].asString; | ||||||
|  | 
 | ||||||
|  | 	dict = loadModelFile.value(path); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | 
 | ||||||
|  | 	popSize = ranges.size; | ||||||
|  | 
 | ||||||
|  | 	//refUID.postln; | ||||||
|  | 
 | ||||||
|  | 	loadLedgerFile.value(ledgerPath); | ||||||
|  | 	if(ledger == nil, {ledger = ["tmp"]}); | ||||||
|  | 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); | ||||||
|  | 
 | ||||||
|  | 	lastXChanges = if(refUID == nil, { | ||||||
|  | 		[initVoices.value().deepCopy]; | ||||||
|  | 	}, { | ||||||
|  | 		var file; | ||||||
|  | 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); | ||||||
|  | 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	durSeeds = seedFunc.value({3.collect({rrand(100000, 999999)})}, durSeed).value.postln; | ||||||
|  | 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..4] ++ [entrancesProbVals[5..]] ++ [durSeeds[0]]); | ||||||
|  | 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..4] ++ [passagesProbVals[5..]] ++ [durSeeds[1]]); | ||||||
|  | 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..4] ++ [exitsProbVals[5..]] ++ [durSeeds[2]]); | ||||||
|  | 
 | ||||||
|  | 	if(orders == nil, { | ||||||
|  | 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); | ||||||
|  | 		//addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); | ||||||
|  | 	}); | ||||||
|  | 	seq = seedFunc.value(genMotif, motifSeed).value; | ||||||
|  | 
 | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	modelString = writeResources.value(path, dict); | ||||||
|  | 
 | ||||||
|  | 	//addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); | ||||||
|  | 	addr.sendMsg("/generated", path, modelString, ledgerPath); | ||||||
|  | }, \generate); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | OSCdef(\commit, {arg msg, time, addr, port; | ||||||
|  | 	var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; | ||||||
|  | 	//msg.postln; | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	test1 = msg[1].asString.parseJSON; | ||||||
|  | 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; | ||||||
|  | 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; | ||||||
|  | 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; | ||||||
|  | 	(test1["music"] == test2["music_data"]).postln; | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; | ||||||
|  | 	musicChanged = (musicData != seq).postln; | ||||||
|  | 
 | ||||||
|  | 	curUID = genUID.value; | ||||||
|  | 
 | ||||||
|  | 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); | ||||||
|  | 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); | ||||||
|  | 
 | ||||||
|  | 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	if(musicChanged, { | ||||||
|  | 		seq = musicData; | ||||||
|  | 		dict["music_data"] = seq; | ||||||
|  | 		dict["motif_edited"] = "true" | ||||||
|  | 	}); | ||||||
|  | 	dict["cur_uid"] = curUID; | ||||||
|  | 
 | ||||||
|  | 	writeResources.value(modelPath, dict); | ||||||
|  | 
 | ||||||
|  | 	File.delete(ledgerPath ++ "_bak"); | ||||||
|  | 	File.copy(ledgerPath, ledgerPath ++ "_bak"); | ||||||
|  | 	File.delete(ledgerPath); | ||||||
|  | 	ledger = ledger.drop(-1).add(curUID); | ||||||
|  | 
 | ||||||
|  | 	saveLedger.value(ledger, ledgerPath); | ||||||
|  | 
 | ||||||
|  | 	addr.sendMsg("/committed", curUID, ledgerPath); | ||||||
|  | 	//refUID = curUID; | ||||||
|  | 
 | ||||||
|  | }, \commit); | ||||||
|  | 
 | ||||||
|  | OSCdef(\transport, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	if(msg[1] == 0, { | ||||||
|  | 		player.stop; | ||||||
|  | 		group.set(\gate, 0); | ||||||
|  | 	}, { | ||||||
|  | 		// the cued sequence can now be read from file, so this can be cleaned up | ||||||
|  | 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; | ||||||
|  | 		if(msg[1] == 1, { | ||||||
|  | 			pSeq = []; | ||||||
|  | 			cuedSeek = (seq != nil); | ||||||
|  | 			indexStart = msg[2].asInteger; | ||||||
|  | 			indexEnd = ledger.size - if(cuedSeek, {2}, {1}); | ||||||
|  | 			//ledger.postln; | ||||||
|  | 			if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { | ||||||
|  | 				ledger[indexStart..indexEnd].do({arg uid, index; | ||||||
|  | 					var path, file; | ||||||
|  | 					path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 					file = File(path, "r"); | ||||||
|  | 					pSeq = pSeq.add([msgInterpret.value(file.readAllString.postln.parseJSON["music_data"]), path, indexStart + index, uid]); | ||||||
|  | 					file.close; | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if(cuedSeek, { | ||||||
|  | 				var path, file; | ||||||
|  | 				path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; | ||||||
|  | 				file = File(path, "r"); | ||||||
|  | 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, ledger.size - 1, "tmp"]); | ||||||
|  | 				file.close; | ||||||
|  | 			}); | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr); | ||||||
|  | 		}, { | ||||||
|  | 			pSeq = [loadModelJSON.value(msg[2].asString.parseJSON)["music_data"].postln]; | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr, true); | ||||||
|  | 		}); | ||||||
|  | 		player = Pfset(pattern: patterns, cleanupFunc: { | ||||||
|  | 			addr.sendMsg("/transport", 0); | ||||||
|  | 			addr.sendMsg("/one_shot", 0); | ||||||
|  | 		}); | ||||||
|  | 		player = player.play | ||||||
|  | 	}); | ||||||
|  | }, \transport); | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | //synthdefs | ||||||
|  | ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sineBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~bassBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~hdustBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~samplerBusArray = 2.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sBuf = Buffer.alloc(s, 10, 2); | ||||||
|  | SynthDef(\string_model, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~stringModelBusArray), sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | 	//Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var sig; | ||||||
|  | 	sig = SinOsc.ar(freq); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.asr(0.3, 0.4, 0.3), gate, timeScale: dur, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; | ||||||
|  | 	var nameSpaces, sigs, hierarchicalDust; | ||||||
|  | 
 | ||||||
|  | 	hierarchicalDust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	sigs = [~stringModelBusArray, ~sineBusArray, ~bassBusArray, ~hdustBusArray, ~samplerBusArray].collect({arg busArray, i; | ||||||
|  | 		var nameSpace, sig; | ||||||
|  | 		nameSpace = ['string', 'sine', 'bass', 'hdust', 'sampler'][i]; | ||||||
|  | 		sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = Mix.ar(sig) * pow(NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.1), 2); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	sigs = Mix.ar(sigs / 4); | ||||||
|  | 	Out.ar(0, sigs) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\bass, { | ||||||
|  | 	var switches, drone; | ||||||
|  | 	switches = {|i| Dust.kr(0.1)} ! 9; | ||||||
|  | 	drone = {|i| var harm = pow(2, 2 - (i / 3).trunc), amp = (1 / pow(harm, 2)); | ||||||
|  | 		SinOsc.ar(60 * harm + TRand.kr(-3, 3, switches[i]), 0, amp)} ! 9; | ||||||
|  | 	Out.ar(~bassBusArray[0], Mix.new(drone) * 0.2); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sampler, { | ||||||
|  | 	Out.ar(~samplerBusArray, PlayBuf.ar(2, ~sBuf, BufRateScale.kr(~sBuf), doneAction: 2)) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | // main routine | ||||||
|  | SynthDef(\hdust, { | ||||||
|  | 	arg gate = 0; | ||||||
|  | 	var hierarchical_dust, low_sine, high_sine, brown_noise, white_noise; | ||||||
|  | 	// this triggers the combinations of sources | ||||||
|  | 	// it is similar to the Supercollider UGen called dust but with a hierarchical structure | ||||||
|  | 	hierarchical_dust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(0.1)) | ||||||
|  | 	); | ||||||
|  | 	// adjust the multiplier at the end of each line for adjusting levels | ||||||
|  | 	// note with each trigger, each source has a 1 in 3 chance of sounding | ||||||
|  | 	low_sine = SinOsc.ar(76.midicps / 16) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.1; | ||||||
|  | 	high_sine = SinOsc.ar(76.midicps * 8) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.01; | ||||||
|  | 	brown_noise = BrownNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.025; | ||||||
|  | 	white_noise = WhiteNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.02; | ||||||
|  | 	Out.ar(~hdustBusArray[0], | ||||||
|  | 		((low_sine + high_sine + brown_noise + white_noise) ) | ||||||
|  | 	); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | var bass, hdust, sampler, mixer; | ||||||
|  | bass = Synth.tail(~group, \bass); | ||||||
|  | hdust = Synth.tail(~group, \hdust); | ||||||
|  | sampler = Synth.head(~group, \sampler); | ||||||
|  | mixer = Synth.tail(~group, \mixer); | ||||||
|  | OSCdef(\mixer, {arg msg, time, addr, port; | ||||||
|  | 	mixer.set((msg[1] ++ '_' ++ msg[2] ++ '_' ++ msg[3]), msg[4]) | ||||||
|  | }, \mixer); | ||||||
|  | 
 | ||||||
|  | OSCdef(\sampler, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	sampler.free; | ||||||
|  | 	~sBuf.free; | ||||||
|  | 	~sBuf = Buffer.read(s, msg[1].asString.postln, action: {sampler = Synth.head(~group, \sampler)}); | ||||||
|  | }, \sampler); | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /* old something | ||||||
|  | ( | ||||||
|  | SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	freq = WhiteNoise.ar * 3 + freq; | ||||||
|  | 	freqFinal = Duty.ar((1/freq), 0, freq); | ||||||
|  | 	trig = Changed.ar(freqFinal); | ||||||
|  | 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); | ||||||
|  | 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); | ||||||
|  | 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 
 | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | ) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| @ -0,0 +1,43 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ 2, -1, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.75 ], | ||||||
|  |     [ [ [ 2, -1, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 4.5 ], | ||||||
|  |     [ [ [ 2, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], 2.25 ], | ||||||
|  |     [ [ [ 2, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 3.5 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 2.25 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 2, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "6a3f7c7c", | ||||||
|  | "ref_uid": "5267b235", | ||||||
|  | "order_seed": 857701, | ||||||
|  | "dur_seed": 870436, | ||||||
|  | "motifs_seed": 456020, | ||||||
|  | "entrances_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ 1419.1950464396, 2400 ], [ 1519.5046439628, 2400 ], [ 1541.7956656347, 2237 ], [ 1519.5046439628, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 3 ], [ 2, 2 ], [ 1 ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.75, 0.69, 0.75 ], | ||||||
|  | "order_size": [ 1, 2 ], | ||||||
|  | "passages_size": [ 0, 2 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,887 @@ | |||||||
|  | ( | ||||||
|  | // helper funcs | ||||||
|  | var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; | ||||||
|  | 
 | ||||||
|  | // score funcs | ||||||
|  | var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; | ||||||
|  | 
 | ||||||
|  | // subroutines | ||||||
|  | var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; | ||||||
|  | 
 | ||||||
|  | // primary routines | ||||||
|  | var genMotif, genSecondarySeq; | ||||||
|  | 
 | ||||||
|  | // audition funcs | ||||||
|  | var genPatterns, genMidiPatterns; | ||||||
|  | 
 | ||||||
|  | // resource management funcs | ||||||
|  | var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, | ||||||
|  | msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON, | ||||||
|  | setGlobalVars, globalVarsToDict, saveLedger; | ||||||
|  | 
 | ||||||
|  | // model vars | ||||||
|  | //(model and global vars mostly set by OSC funcs | ||||||
|  | var seq, lastXChanges, | ||||||
|  | curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | motifEdited, orderEdited; | ||||||
|  | 
 | ||||||
|  | // model aux vars | ||||||
|  | var entrancesDurFunc, passagesDurFunc, exitsDurFunc; | ||||||
|  | 
 | ||||||
|  | // other global vars | ||||||
|  | var popSize, exPath, dir, primes, dims, tuples, | ||||||
|  | group, player, ledgerPath, ledger, currentlyPlayingUID, | ||||||
|  | nameSpaces; | ||||||
|  | 
 | ||||||
|  | // install JSON quark | ||||||
|  | if(Quarks.isInstalled("JSONlib").not, { | ||||||
|  | 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); | ||||||
|  | 	thisProcess.recompile; | ||||||
|  | 	//HelpBrowser.openHelpFor("Classes/JSONlib"); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------helper funcs | ||||||
|  | 
 | ||||||
|  | hsArrayToCents = { | ||||||
|  | 	arg hsArray; | ||||||
|  | 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pDist = { | ||||||
|  | 	arg array1, array2, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); | ||||||
|  | 	if(signed, {pDistance}, {abs(pDistance)}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hdSum = { | ||||||
|  | 	arg hsArrays; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays.size; | ||||||
|  | 	distances = (size - 1).collect({arg i; | ||||||
|  | 		((i + 1)..(size - 1)).collect({arg j; | ||||||
|  | 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsChordalDistance = { | ||||||
|  | 	arg hsArrays1, hsArrays2; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays1.size; | ||||||
|  | 	distances = hsArrays1.size.collect({arg i; | ||||||
|  | 		hsArrays2.size.collect({arg j; | ||||||
|  | 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsArrayToFreq = { | ||||||
|  | 	arg array; | ||||||
|  | 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------score funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | isInRange = { | ||||||
|  | 	arg hsArray, min, max; | ||||||
|  | 	var cents; | ||||||
|  | 	cents = hsArrayToCents.value(hsArray); | ||||||
|  | 	(cents >= min) && (cents <= max) | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | spacingScore = { | ||||||
|  | 	arg hsArrays, min; | ||||||
|  | 	var centsArray; | ||||||
|  | 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); | ||||||
|  | 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | rangeScore = { | ||||||
|  | 	arg hsArray1, hsArray2, min, max, low, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | intervalScore = { | ||||||
|  | 	arg hsArray1, hsArray2, mean, sd, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	pDistance.gaussCurve(1, mean, sd) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | inclusionScore = { | ||||||
|  | 	arg array, test, min = 0.01; | ||||||
|  | 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------subroutines | ||||||
|  | 
 | ||||||
|  | genTuples = { | ||||||
|  | 	var tuples; | ||||||
|  | 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); | ||||||
|  | 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | initVoices = { | ||||||
|  | 	var init, voicesInit; | ||||||
|  | 	voicesInit = popSize.collect({dims.collect({0})}); | ||||||
|  | 	/* | ||||||
|  | 	voicesInit = [dims.collect({0})]; | ||||||
|  | 	(popSize - 1).do({ | ||||||
|  | 		arg rep, new; | ||||||
|  | 		rep = dims.rand; | ||||||
|  | 		new = voicesInit.last.deepCopy; | ||||||
|  | 		new[rep] = new[rep] + [-1, 1].choose(); | ||||||
|  | 		voicesInit = voicesInit.add(new); | ||||||
|  | 	}); | ||||||
|  | 	*/ | ||||||
|  | 	voicesInit.deepCopy; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; | ||||||
|  | 	var env, pTable, durFunc; | ||||||
|  | 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; | ||||||
|  | 	pTable = env.asRandomTable; | ||||||
|  | 	[chordProb, minPad, maxPad, minDur, maxDur, envData].postln; | ||||||
|  | 	durFunc = {arg allowChord, pad = false; | ||||||
|  | 		var res; | ||||||
|  | 		res = if(allowChord.not, { | ||||||
|  | 			pTable.tableRand * (maxDur - minDur) + minDur | ||||||
|  | 		}, { | ||||||
|  | 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (maxDur - minDur) + minDur}); | ||||||
|  | 		}).round(0.125); | ||||||
|  | 		if(pad, {res = res + rrand(minPad.asFloat, maxPad.asFloat).round(0.125)}); | ||||||
|  | 		if(res.asInteger == res, {res = res.asInteger}); | ||||||
|  | 		res | ||||||
|  | 	}; | ||||||
|  | 	seedFunc.value(durFunc, seed); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; | ||||||
|  | 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ | ||||||
|  | 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; | ||||||
|  | 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); | ||||||
|  | 		noProgIns = (popSize - noSusIns).rand + 1; | ||||||
|  | 		noSilentIns = popSize - noSusIns - noProgIns; | ||||||
|  | 
 | ||||||
|  | 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); | ||||||
|  | 
 | ||||||
|  | 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); | ||||||
|  | 		if(silent == nil, {silent = []}); | ||||||
|  | 		[sus.scramble, prog, silent.scramble] | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | updateVoices = {arg ins, sus; | ||||||
|  | 	var voices, candidates, nWeights, nProbs, sel; | ||||||
|  | 
 | ||||||
|  | 	voices = lastXChanges.deepCopy.last; | ||||||
|  | 
 | ||||||
|  | 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; | ||||||
|  | 	candidates = difference(candidates.asSet, voices.asSet).asList; | ||||||
|  | 	nProbs = candidates.collect({arg candidate; | ||||||
|  | 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; | ||||||
|  | 
 | ||||||
|  | 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); | ||||||
|  | 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); | ||||||
|  | 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); | ||||||
|  | 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); | ||||||
|  | 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); | ||||||
|  | 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); | ||||||
|  | 		//maybe what you want here is a vector to another root and then favoring movement towards it. | ||||||
|  | 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); | ||||||
|  | 
 | ||||||
|  | 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	nWeights = passagesWeights; | ||||||
|  | 
 | ||||||
|  | 	//this handles nWeights of 0; mainly for testing | ||||||
|  | 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; | ||||||
|  | 	nWeights = nWeights.select({arg weight; weight != 0}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; | ||||||
|  | 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) | ||||||
|  | 	}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; | ||||||
|  | 
 | ||||||
|  | 	sel = candidates.wchoose(nProbs); | ||||||
|  | 
 | ||||||
|  | 	voices[ins] = sel; | ||||||
|  | 	lastXChanges = lastXChanges.add(voices).keep(-5); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; | ||||||
|  | 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, pad, lastXChangesHold, voices, adder; | ||||||
|  | 	# sus, prog, silent = order; | ||||||
|  | 	flatOrder = silent ++ sus ++ prog; | ||||||
|  | 	lastXChangesHold = lastXChanges.deepCopy; | ||||||
|  | 	voices = lastState.deepCopy; | ||||||
|  | 	isInChord = popSize.collect({false}); | ||||||
|  | 	allowChord = false; | ||||||
|  | 	pad = false; | ||||||
|  | 	res = []; | ||||||
|  | 	"------generating motif".postln; | ||||||
|  | 	//need to figure out here if voices move between motifs | ||||||
|  | 	flatOrder.do({arg ins, i; | ||||||
|  | 
 | ||||||
|  | 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); | ||||||
|  | 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); | ||||||
|  | 
 | ||||||
|  | 		if(voices[ins] != adder, { | ||||||
|  | 			var dur; | ||||||
|  | 
 | ||||||
|  | 			if((sus ++ silent).includes(ins), { | ||||||
|  | 				allowChord = (ins != sus.last); | ||||||
|  | 				pad = (ins == sus.last); | ||||||
|  | 			}, { | ||||||
|  | 				if(i < (flatOrder.size - 1), { | ||||||
|  | 					allowChord = (isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not; | ||||||
|  | 					pad = false; | ||||||
|  | 				}, { | ||||||
|  | 					allowChord = false; | ||||||
|  | 					pad = true | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if((orderIndex == 0) && sus.includes(ins), { | ||||||
|  | 				dur = entrancesDurFunc.value(allowChord, pad); | ||||||
|  | 			}, { | ||||||
|  | 				dur = passagesDurFunc.value(allowChord, pad); | ||||||
|  | 			}); | ||||||
|  | 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); | ||||||
|  | 
 | ||||||
|  | 			voices[ins] = adder; | ||||||
|  | 			res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// pad ending | ||||||
|  | 	if(orderIndex == (orders.size - 1), { | ||||||
|  | 		(0..(popSize-1)).scramble.do({arg ins; | ||||||
|  | 			if(res.last.first[ins] != ["Rest"], { | ||||||
|  | 				var dur; | ||||||
|  | 				voices[ins] = ["Rest"]; | ||||||
|  | 				allowChord = (voices != popSize.collect({["Rest"]})); | ||||||
|  | 				pad = allowChord.not; | ||||||
|  | 				dur = exitsDurFunc.value(allowChord, pad); | ||||||
|  | 				res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	//format and return | ||||||
|  | 	if(startFromLast, {lastXChanges = lastXChangesHold}); | ||||||
|  | 	res; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------primary routines | ||||||
|  | 
 | ||||||
|  | genMotif = { | ||||||
|  | 	var repeats, fSeq; | ||||||
|  | 
 | ||||||
|  | 	repeats = 1; | ||||||
|  | 	fSeq = []; | ||||||
|  | 
 | ||||||
|  | 	repeats.do({arg index; | ||||||
|  | 		var motif; | ||||||
|  | 
 | ||||||
|  | 		motif = []; | ||||||
|  | 
 | ||||||
|  | 		orders.do({arg order, o; | ||||||
|  | 			var lastState, subMotif; | ||||||
|  | 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); | ||||||
|  | 			subMotif = genSubMotif.value(order, o, lastState, isLastOrder: o == (orders.size - 1)); | ||||||
|  | 			motif = motif.add(subMotif); | ||||||
|  | 
 | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		sanityCheck.value(motif, index); | ||||||
|  | 
 | ||||||
|  | 		fSeq = fSeq.add(motif); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSecondarySeq = {arg seq; | ||||||
|  | 	var curdles, fSeq; | ||||||
|  | 	curdles = []; | ||||||
|  | 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); | ||||||
|  | 
 | ||||||
|  | 	fSeq = seq.clumps(curdles).collect({arg clump, m; | ||||||
|  | 		var repeats, paddedSeq; | ||||||
|  | 
 | ||||||
|  | 		//add rest | ||||||
|  | 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); | ||||||
|  | 
 | ||||||
|  | 		//implement repeats | ||||||
|  | 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); | ||||||
|  | 		repeats.collect({paddedSeq}); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------audition funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~addr.sendMsg(~indexPath, ~indexMsg); | ||||||
|  | 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); | ||||||
|  | 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~msg.postln; | ||||||
|  | 		~addr.sendMsg(~path, *~msg); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | genPatterns = {arg inSeq, addr, oneShot = false; | ||||||
|  | 	var voices, durs, pbinds, res, indices, sectionDurs, msg, ids, seq; | ||||||
|  | 	seq = inSeq.collect({arg mSeq; mSeq[0]}); | ||||||
|  | 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	pbinds = voices.flop.collect({arg voice, v; | ||||||
|  | 		var clumps, hdScores, freqs, fDurs; | ||||||
|  | 		clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 		freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 		fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \string_model, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			), | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \sine, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	}).flatten; | ||||||
|  | 	if(oneShot.not, { | ||||||
|  | 		msg = inSeq.collect({arg mSeq, m; mSeq[1..]}); | ||||||
|  | 		//ids = inSeq.collect({arg mSeq, m; mSeq[2]}); | ||||||
|  | 		sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); | ||||||
|  | 		pbinds = pbinds ++ | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \osc, | ||||||
|  | 				\addr, addr, | ||||||
|  | 				\path, "/playing", | ||||||
|  | 				\msg, Pseq(msg, 1), | ||||||
|  | 				\dur, Pseq(sectionDurs, 1) | ||||||
|  | 			); | ||||||
|  | 		] | ||||||
|  | 	}); | ||||||
|  | 	res = Ppar(pbinds); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | genMidiPatterns = {arg seq; | ||||||
|  | 	var voices, durs, patterns, res, mOut, pbRange; | ||||||
|  | 	pbRange = 1; //semitones - change this as needed for your situation | ||||||
|  | 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); | ||||||
|  | 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	res = Ppar( | ||||||
|  | 		voices.flop.collect({arg voice, v; | ||||||
|  | 			var clumps, hdScores, freqs, fDurs; | ||||||
|  | 
 | ||||||
|  | 			mOut.program(v, 70); | ||||||
|  | 
 | ||||||
|  | 			clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \midi, | ||||||
|  | 				\chan, v, | ||||||
|  | 				\noteval, Pseq(freqs.cpsmidi - 24, 1), | ||||||
|  | 				\note, Pfunc({ | event | event[\noteval].floor }), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\midiout, mOut, | ||||||
|  | 				\amp, 1, | ||||||
|  | 				\bend, Pfunc({ | ||||||
|  | 					| event | | ||||||
|  | 					if (event[\note].isRest.not) { | ||||||
|  | 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; | ||||||
|  | 						m.bend(v, pitchbendvalue); | ||||||
|  | 					}; | ||||||
|  | 					0; // return something other than nil to avoid stopping the pattern | ||||||
|  | 				}), | ||||||
|  | 			); | ||||||
|  | 		}); | ||||||
|  | 	); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------resource management funcs | ||||||
|  | 
 | ||||||
|  | genUID = {Date.seed.asHexString.toLower}; | ||||||
|  | 
 | ||||||
|  | seedFunc = {arg func, seed; | ||||||
|  | 	var funcArgs, next; | ||||||
|  | 	next = Routine({loop{func.valueArray(funcArgs).yield }}); | ||||||
|  | 	next.randSeed_(seed); | ||||||
|  | 	{arg ...args; funcArgs = args; next.value} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | stringifyToDepth = {arg data, maxDepth = 1; | ||||||
|  | 	var prettyString = "", rCount = 0, writeArray, indent; | ||||||
|  | 
 | ||||||
|  | 	if(maxDepth == 0, { | ||||||
|  | 		data.asCompileString | ||||||
|  | 	}, { | ||||||
|  | 		indent = {arg size; size.collect({" "}).join("")}; | ||||||
|  | 		writeArray = {arg array; | ||||||
|  | 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; | ||||||
|  | 			rCount = rCount + 1; | ||||||
|  | 			if(rCount < maxDepth, { | ||||||
|  | 				array.do({arg subArray; writeArray.value(subArray)}); | ||||||
|  | 			}, { | ||||||
|  | 				prettyString = prettyString ++ array.collect({arg subArray; | ||||||
|  | 					indent.value(rCount + 1) ++ subArray.asCompileString | ||||||
|  | 				}).join(",\n"); | ||||||
|  | 			}); | ||||||
|  | 			rCount = rCount - 1; | ||||||
|  | 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		writeArray.value(data); | ||||||
|  | 		prettyString.replace(",\n\n", "\n").drop(-2); | ||||||
|  | 	}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | sanityCheck = {arg motif, index; | ||||||
|  | 	//print functions = very helpful | ||||||
|  | 	("----------" + index + "------------").postln; | ||||||
|  | 
 | ||||||
|  | 	motif.flatten.do({arg val, v; | ||||||
|  | 		if(v > 0, { | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); | ||||||
|  | 		}); | ||||||
|  | 		val.postln | ||||||
|  | 	}); | ||||||
|  | 	"***********".postln; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; | ||||||
|  | 	var res; | ||||||
|  | 
 | ||||||
|  | 	res = in; | ||||||
|  | 	if(res.isNil.not, { | ||||||
|  | 		if((res.isArray && res.isString.not), { | ||||||
|  | 			res = res.asCompileString; | ||||||
|  | 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); | ||||||
|  | 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); | ||||||
|  | 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); | ||||||
|  | 			res = res.replace("Rest", "\"Rest\""); | ||||||
|  | 			res = res.interpret; | ||||||
|  | 		}, { | ||||||
|  | 			//res.postln; | ||||||
|  | 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | writeResources = {arg path, dict; | ||||||
|  | 	var file, modelItems, resString; | ||||||
|  | 	file = File(path,"w"); | ||||||
|  | 
 | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	resString = nameSpaces.collect({arg nameSpace; | ||||||
|  | 		var depth = 0, insert = " "; | ||||||
|  | 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "order", {depth = 1; insert = "\n"}); | ||||||
|  | 		if((nameSpace == "ref_uid") && (dict[nameSpace] == nil), {dict[nameSpace] = "nil"}); | ||||||
|  | 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(dict[nameSpace], depth) | ||||||
|  | 	}).join(",\n"); | ||||||
|  | 
 | ||||||
|  | 	resString = "{\n" ++ resString ++ "\n}"; | ||||||
|  | 
 | ||||||
|  | 	file.write(resString); | ||||||
|  | 	file.close; | ||||||
|  | 	resString | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; | ||||||
|  | 
 | ||||||
|  | loadModelJSON = {arg jsonObject; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS; nS->msgInterpret.value(jsonObject[nS])})); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | setGlobalVars = {arg dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	# seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 	entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 	motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | globalVarsToDict = { | ||||||
|  | 	var modelItems, dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerFile = {arg path; | ||||||
|  | 	ledgerPath = path; | ||||||
|  | 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; | ||||||
|  | 
 | ||||||
|  | saveLedger = {arg ledger, path; | ||||||
|  | 	var file; | ||||||
|  | 	file = File(path, "w"); | ||||||
|  | 	file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); | ||||||
|  | 	file.close; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------global vars | ||||||
|  | 
 | ||||||
|  | primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; | ||||||
|  | //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; | ||||||
|  | exPath = thisProcess.nowExecutingPath; | ||||||
|  | dir = exPath.dirname; | ||||||
|  | //popSize = 4; | ||||||
|  | dims = primes.size; | ||||||
|  | tuples = genTuples.value(); | ||||||
|  | //refUID = nil; | ||||||
|  | group = Group.new; | ||||||
|  | ~group = group; | ||||||
|  | loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); | ||||||
|  | //passagesWeights = [1, 1, 1, 1, 1]; | ||||||
|  | //susWeights = [1, 1, 1]; | ||||||
|  | // order really matters!!!! | ||||||
|  | nameSpaces = [ | ||||||
|  | 	"music_data", "last_changes", "cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", | ||||||
|  | 	"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", | ||||||
|  | 	"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", | ||||||
|  | 	"motif_edited", "order_edited" | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------OSC funcs | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_ledger, {arg msg, time, addr, port; | ||||||
|  | 	loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \load_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_model, {arg msg, time, addr, port; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = loadModelFile.value(msg[1].asString); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | }, \load_model); | ||||||
|  | 
 | ||||||
|  | OSCdef(\save_ledger, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	ledger = msgInterpret.value(msg[1].asString.parseJSON["ledger"], false).postln; | ||||||
|  | 	//loadLedgerJSON.value(msg[0]) | ||||||
|  | 	saveLedger.value(ledger, msg[2].asString); | ||||||
|  | 	//loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \save_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\generate, {arg msg, time, addr, port; | ||||||
|  | 	var path, dict, durSeeds, musPath, modelString; | ||||||
|  | 	msg.postln; | ||||||
|  | 
 | ||||||
|  | 	path = msg[1].asString; | ||||||
|  | 
 | ||||||
|  | 	dict = loadModelFile.value(path); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | 
 | ||||||
|  | 	popSize = ranges.size; | ||||||
|  | 
 | ||||||
|  | 	//refUID.postln; | ||||||
|  | 
 | ||||||
|  | 	loadLedgerFile.value(ledgerPath); | ||||||
|  | 	if(ledger == nil, {ledger = ["tmp"]}); | ||||||
|  | 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); | ||||||
|  | 
 | ||||||
|  | 	lastXChanges = if(refUID == nil, { | ||||||
|  | 		[initVoices.value().deepCopy]; | ||||||
|  | 	}, { | ||||||
|  | 		var file; | ||||||
|  | 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); | ||||||
|  | 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	durSeeds = seedFunc.value({3.collect({rrand(100000, 999999)})}, durSeed).value.postln; | ||||||
|  | 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..4] ++ [entrancesProbVals[5..]] ++ [durSeeds[0]]); | ||||||
|  | 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..4] ++ [passagesProbVals[5..]] ++ [durSeeds[1]]); | ||||||
|  | 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..4] ++ [exitsProbVals[5..]] ++ [durSeeds[2]]); | ||||||
|  | 
 | ||||||
|  | 	if(orders == nil, { | ||||||
|  | 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); | ||||||
|  | 		//addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); | ||||||
|  | 	}); | ||||||
|  | 	seq = seedFunc.value(genMotif, motifSeed).value; | ||||||
|  | 
 | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	modelString = writeResources.value(path, dict); | ||||||
|  | 
 | ||||||
|  | 	//addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); | ||||||
|  | 	addr.sendMsg("/generated", path, modelString, ledgerPath); | ||||||
|  | }, \generate); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | OSCdef(\commit, {arg msg, time, addr, port; | ||||||
|  | 	var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; | ||||||
|  | 	//msg.postln; | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	test1 = msg[1].asString.parseJSON; | ||||||
|  | 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; | ||||||
|  | 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; | ||||||
|  | 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; | ||||||
|  | 	(test1["music"] == test2["music_data"]).postln; | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; | ||||||
|  | 	musicChanged = (musicData != seq).postln; | ||||||
|  | 
 | ||||||
|  | 	curUID = genUID.value; | ||||||
|  | 
 | ||||||
|  | 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); | ||||||
|  | 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); | ||||||
|  | 
 | ||||||
|  | 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	if(musicChanged, { | ||||||
|  | 		seq = musicData; | ||||||
|  | 		dict["music_data"] = seq; | ||||||
|  | 		dict["motif_edited"] = "true" | ||||||
|  | 	}); | ||||||
|  | 	dict["cur_uid"] = curUID; | ||||||
|  | 
 | ||||||
|  | 	writeResources.value(modelPath, dict); | ||||||
|  | 
 | ||||||
|  | 	File.delete(ledgerPath ++ "_bak"); | ||||||
|  | 	File.copy(ledgerPath, ledgerPath ++ "_bak"); | ||||||
|  | 	File.delete(ledgerPath); | ||||||
|  | 	ledger = ledger.drop(-1).add(curUID); | ||||||
|  | 
 | ||||||
|  | 	saveLedger.value(ledger, ledgerPath); | ||||||
|  | 
 | ||||||
|  | 	addr.sendMsg("/committed", curUID, ledgerPath); | ||||||
|  | 	//refUID = curUID; | ||||||
|  | 
 | ||||||
|  | }, \commit); | ||||||
|  | 
 | ||||||
|  | OSCdef(\transport, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	if(msg[1] == 0, { | ||||||
|  | 		player.stop; | ||||||
|  | 		group.set(\gate, 0); | ||||||
|  | 	}, { | ||||||
|  | 		// the cued sequence can now be read from file, so this can be cleaned up | ||||||
|  | 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; | ||||||
|  | 		if(msg[1] == 1, { | ||||||
|  | 			pSeq = []; | ||||||
|  | 			cuedSeek = (seq != nil); | ||||||
|  | 			indexStart = msg[2].asInteger; | ||||||
|  | 			indexEnd = ledger.size - if(cuedSeek, {2}, {1}); | ||||||
|  | 			//ledger.postln; | ||||||
|  | 			if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { | ||||||
|  | 				ledger[indexStart..indexEnd].do({arg uid, index; | ||||||
|  | 					var path, file; | ||||||
|  | 					path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 					file = File(path, "r"); | ||||||
|  | 					pSeq = pSeq.add([msgInterpret.value(file.readAllString.postln.parseJSON["music_data"]), path, indexStart + index, uid]); | ||||||
|  | 					file.close; | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if(cuedSeek, { | ||||||
|  | 				var path, file; | ||||||
|  | 				path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; | ||||||
|  | 				file = File(path, "r"); | ||||||
|  | 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, ledger.size - 1, "tmp"]); | ||||||
|  | 				file.close; | ||||||
|  | 			}); | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr); | ||||||
|  | 		}, { | ||||||
|  | 			pSeq = [loadModelJSON.value(msg[2].asString.parseJSON)["music_data"].postln]; | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr, true); | ||||||
|  | 		}); | ||||||
|  | 		player = Pfset(pattern: patterns, cleanupFunc: { | ||||||
|  | 			addr.sendMsg("/transport", 0); | ||||||
|  | 			addr.sendMsg("/one_shot", 0); | ||||||
|  | 		}); | ||||||
|  | 		player = player.play | ||||||
|  | 	}); | ||||||
|  | }, \transport); | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | //synthdefs | ||||||
|  | ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sineBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~bassBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~hdustBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~samplerBusArray = 2.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sBuf = Buffer.alloc(s, 10, 2); | ||||||
|  | SynthDef(\string_model, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~stringModelBusArray), sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | 	//Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var sig; | ||||||
|  | 	sig = SinOsc.ar(freq); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.asr(0.3, 0.4, 0.3), gate, timeScale: dur, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; | ||||||
|  | 	var nameSpaces, sigs, hierarchicalDust; | ||||||
|  | 
 | ||||||
|  | 	hierarchicalDust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	sigs = [~stringModelBusArray, ~sineBusArray, ~bassBusArray, ~hdustBusArray, ~samplerBusArray].collect({arg busArray, i; | ||||||
|  | 		var nameSpace, sig; | ||||||
|  | 		nameSpace = ['string', 'sine', 'bass', 'hdust', 'sampler'][i]; | ||||||
|  | 		sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = Mix.ar(sig) * pow(NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.1), 2); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	sigs = Mix.ar(sigs / 4); | ||||||
|  | 	Out.ar(0, sigs) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\bass, { | ||||||
|  | 	var switches, drone; | ||||||
|  | 	switches = {|i| Dust.kr(0.1)} ! 9; | ||||||
|  | 	drone = {|i| var harm = pow(2, 2 - (i / 3).trunc), amp = (1 / pow(harm, 2)); | ||||||
|  | 		SinOsc.ar(60 * harm + TRand.kr(-3, 3, switches[i]), 0, amp)} ! 9; | ||||||
|  | 	Out.ar(~bassBusArray[0], Mix.new(drone) * 0.2); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sampler, { | ||||||
|  | 	Out.ar(~samplerBusArray, PlayBuf.ar(2, ~sBuf, BufRateScale.kr(~sBuf), doneAction: 2)) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | // main routine | ||||||
|  | SynthDef(\hdust, { | ||||||
|  | 	arg gate = 0; | ||||||
|  | 	var hierarchical_dust, low_sine, high_sine, brown_noise, white_noise; | ||||||
|  | 	// this triggers the combinations of sources | ||||||
|  | 	// it is similar to the Supercollider UGen called dust but with a hierarchical structure | ||||||
|  | 	hierarchical_dust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(0.1)) | ||||||
|  | 	); | ||||||
|  | 	// adjust the multiplier at the end of each line for adjusting levels | ||||||
|  | 	// note with each trigger, each source has a 1 in 3 chance of sounding | ||||||
|  | 	low_sine = SinOsc.ar(76.midicps / 16) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.1; | ||||||
|  | 	high_sine = SinOsc.ar(76.midicps * 8) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.01; | ||||||
|  | 	brown_noise = BrownNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.025; | ||||||
|  | 	white_noise = WhiteNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.02; | ||||||
|  | 	Out.ar(~hdustBusArray[0], | ||||||
|  | 		((low_sine + high_sine + brown_noise + white_noise) ) | ||||||
|  | 	); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | var bass, hdust, sampler, mixer; | ||||||
|  | bass = Synth.tail(~group, \bass); | ||||||
|  | hdust = Synth.tail(~group, \hdust); | ||||||
|  | sampler = Synth.head(~group, \sampler); | ||||||
|  | mixer = Synth.tail(~group, \mixer); | ||||||
|  | OSCdef(\mixer, {arg msg, time, addr, port; | ||||||
|  | 	mixer.set((msg[1] ++ '_' ++ msg[2] ++ '_' ++ msg[3]), msg[4]) | ||||||
|  | }, \mixer); | ||||||
|  | 
 | ||||||
|  | OSCdef(\sampler, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	sampler.free; | ||||||
|  | 	~sBuf.free; | ||||||
|  | 	~sBuf = Buffer.read(s, msg[1].asString.postln, action: {sampler = Synth.head(~group, \sampler)}); | ||||||
|  | }, \sampler); | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /* old something | ||||||
|  | ( | ||||||
|  | SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	freq = WhiteNoise.ar * 3 + freq; | ||||||
|  | 	freqFinal = Duty.ar((1/freq), 0, freq); | ||||||
|  | 	trig = Changed.ar(freqFinal); | ||||||
|  | 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); | ||||||
|  | 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); | ||||||
|  | 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 
 | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | ) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| @ -0,0 +1,44 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ] ], 0 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ] ], 0.375 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ] ], 4.875 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ] ], 2.375 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ] ], 0.375 ], | ||||||
|  |     [ [ [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ] ], 0.375 ], | ||||||
|  |     [ [ [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.875 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 1 ] ], | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "6d0c2f19", | ||||||
|  | "ref_uid": "7e170ef8", | ||||||
|  | "order_seed": 861383, | ||||||
|  | "dur_seed": 654405, | ||||||
|  | "motifs_seed": 513928, | ||||||
|  | "entrances_probs_vals": [ 0.75, 1.67, 4.8015873015873, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0.75, 1.67, 4.8015873015873, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0.75, 1.87, 5.1984126984127, 0, 0.5, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ -384, 2400 ], [ -507, 2400 ], [ -282, 2237 ], [ -1200, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 3, 0, 1 ], [ 2 ], [  ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.75, 0.69, 0.75 ], | ||||||
|  | "order_size": [ 1, 2 ], | ||||||
|  | "passages_size": [ 0, 1 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,881 @@ | |||||||
|  | ( | ||||||
|  | // helper funcs | ||||||
|  | var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; | ||||||
|  | 
 | ||||||
|  | // score funcs | ||||||
|  | var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; | ||||||
|  | 
 | ||||||
|  | // subroutines | ||||||
|  | var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; | ||||||
|  | 
 | ||||||
|  | // primary routines | ||||||
|  | var genMotif, genSecondarySeq; | ||||||
|  | 
 | ||||||
|  | // audition funcs | ||||||
|  | var genPatterns, genMidiPatterns; | ||||||
|  | 
 | ||||||
|  | // resource management funcs | ||||||
|  | var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, | ||||||
|  | msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON, | ||||||
|  | setGlobalVars, globalVarsToDict, saveLedger; | ||||||
|  | 
 | ||||||
|  | // model vars | ||||||
|  | //(model and global vars mostly set by OSC funcs | ||||||
|  | var seq, lastXChanges, | ||||||
|  | curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | motifEdited, orderEdited; | ||||||
|  | 
 | ||||||
|  | // model aux vars | ||||||
|  | var entrancesDurFunc, passagesDurFunc, exitsDurFunc; | ||||||
|  | 
 | ||||||
|  | // other global vars | ||||||
|  | var popSize, exPath, dir, primes, dims, tuples, | ||||||
|  | group, player, ledgerPath, ledger, currentlyPlayingUID, | ||||||
|  | nameSpaces; | ||||||
|  | 
 | ||||||
|  | // install JSON quark | ||||||
|  | if(Quarks.isInstalled("JSONlib").not, { | ||||||
|  | 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); | ||||||
|  | 	thisProcess.recompile; | ||||||
|  | 	//HelpBrowser.openHelpFor("Classes/JSONlib"); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------helper funcs | ||||||
|  | 
 | ||||||
|  | hsArrayToCents = { | ||||||
|  | 	arg hsArray; | ||||||
|  | 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pDist = { | ||||||
|  | 	arg array1, array2, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); | ||||||
|  | 	if(signed, {pDistance}, {abs(pDistance)}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hdSum = { | ||||||
|  | 	arg hsArrays; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays.size; | ||||||
|  | 	distances = (size - 1).collect({arg i; | ||||||
|  | 		((i + 1)..(size - 1)).collect({arg j; | ||||||
|  | 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsChordalDistance = { | ||||||
|  | 	arg hsArrays1, hsArrays2; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays1.size; | ||||||
|  | 	distances = hsArrays1.size.collect({arg i; | ||||||
|  | 		hsArrays2.size.collect({arg j; | ||||||
|  | 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsArrayToFreq = { | ||||||
|  | 	arg array; | ||||||
|  | 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------score funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | isInRange = { | ||||||
|  | 	arg hsArray, min, max; | ||||||
|  | 	var cents; | ||||||
|  | 	cents = hsArrayToCents.value(hsArray); | ||||||
|  | 	(cents >= min) && (cents <= max) | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | spacingScore = { | ||||||
|  | 	arg hsArrays, min; | ||||||
|  | 	var centsArray; | ||||||
|  | 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); | ||||||
|  | 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | rangeScore = { | ||||||
|  | 	arg hsArray1, hsArray2, min, max, low, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | intervalScore = { | ||||||
|  | 	arg hsArray1, hsArray2, mean, sd, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	pDistance.gaussCurve(1, mean, sd) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | inclusionScore = { | ||||||
|  | 	arg array, test, min = 0.01; | ||||||
|  | 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------subroutines | ||||||
|  | 
 | ||||||
|  | genTuples = { | ||||||
|  | 	var tuples; | ||||||
|  | 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); | ||||||
|  | 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | initVoices = { | ||||||
|  | 	var init, voicesInit; | ||||||
|  | 	voicesInit = popSize.collect({dims.collect({0})}); | ||||||
|  | 	/* | ||||||
|  | 	voicesInit = [dims.collect({0})]; | ||||||
|  | 	(popSize - 1).do({ | ||||||
|  | 		arg rep, new; | ||||||
|  | 		rep = dims.rand; | ||||||
|  | 		new = voicesInit.last.deepCopy; | ||||||
|  | 		new[rep] = new[rep] + [-1, 1].choose(); | ||||||
|  | 		voicesInit = voicesInit.add(new); | ||||||
|  | 	}); | ||||||
|  | 	*/ | ||||||
|  | 	voicesInit.deepCopy; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; | ||||||
|  | 	var env, pTable, durFunc; | ||||||
|  | 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; | ||||||
|  | 	pTable = env.asRandomTable; | ||||||
|  | 	[chordProb, minPad, maxPad, minDur, maxDur, envData].postln; | ||||||
|  | 	durFunc = {arg allowChord, pad = false; | ||||||
|  | 		var res; | ||||||
|  | 		res = if(allowChord.not, { | ||||||
|  | 			pTable.tableRand * (maxDur - minDur) + minDur | ||||||
|  | 		}, { | ||||||
|  | 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (maxDur - minDur) + minDur}); | ||||||
|  | 		}).round(0.125); | ||||||
|  | 		if(pad, {res = res + rrand(minPad.asFloat, maxPad.asFloat).round(0.125)}); | ||||||
|  | 		if(res.asInteger == res, {res = res.asInteger}); | ||||||
|  | 		res | ||||||
|  | 	}; | ||||||
|  | 	seedFunc.value(durFunc, seed); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; | ||||||
|  | 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ | ||||||
|  | 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; | ||||||
|  | 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); | ||||||
|  | 		noProgIns = (popSize - noSusIns).rand + 1; | ||||||
|  | 		noSilentIns = popSize - noSusIns - noProgIns; | ||||||
|  | 
 | ||||||
|  | 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); | ||||||
|  | 
 | ||||||
|  | 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); | ||||||
|  | 		if(silent == nil, {silent = []}); | ||||||
|  | 		[sus.scramble, prog, silent.scramble] | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | updateVoices = {arg ins, sus; | ||||||
|  | 	var voices, candidates, nWeights, nProbs, sel; | ||||||
|  | 
 | ||||||
|  | 	voices = lastXChanges.deepCopy.last; | ||||||
|  | 
 | ||||||
|  | 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; | ||||||
|  | 	candidates = difference(candidates.asSet, voices.asSet).asList; | ||||||
|  | 	nProbs = candidates.collect({arg candidate; | ||||||
|  | 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; | ||||||
|  | 
 | ||||||
|  | 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); | ||||||
|  | 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); | ||||||
|  | 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); | ||||||
|  | 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); | ||||||
|  | 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); | ||||||
|  | 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); | ||||||
|  | 		//maybe what you want here is a vector to another root and then favoring movement towards it. | ||||||
|  | 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); | ||||||
|  | 
 | ||||||
|  | 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	nWeights = passagesWeights; | ||||||
|  | 
 | ||||||
|  | 	//this handles nWeights of 0; mainly for testing | ||||||
|  | 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; | ||||||
|  | 	nWeights = nWeights.select({arg weight; weight != 0}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; | ||||||
|  | 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) | ||||||
|  | 	}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; | ||||||
|  | 
 | ||||||
|  | 	sel = candidates.wchoose(nProbs); | ||||||
|  | 
 | ||||||
|  | 	voices[ins] = sel; | ||||||
|  | 	lastXChanges = lastXChanges.add(voices).keep(-5); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; | ||||||
|  | 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, pad, lastXChangesHold, voices, adder; | ||||||
|  | 	# sus, prog, silent = order; | ||||||
|  | 	flatOrder = silent ++ sus ++ prog; | ||||||
|  | 	lastXChangesHold = lastXChanges.deepCopy; | ||||||
|  | 	voices = lastState.deepCopy; | ||||||
|  | 	isInChord = popSize.collect({false}); | ||||||
|  | 	allowChord = false; | ||||||
|  | 	pad = false; | ||||||
|  | 	res = []; | ||||||
|  | 	"------generating motif".postln; | ||||||
|  | 	//need to figure out here if voices move between motifs | ||||||
|  | 	flatOrder.do({arg ins, i; | ||||||
|  | 
 | ||||||
|  | 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); | ||||||
|  | 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); | ||||||
|  | 
 | ||||||
|  | 		if(voices[ins] != adder, { | ||||||
|  | 			var dur; | ||||||
|  | 
 | ||||||
|  | 			if((sus ++ silent).includes(ins), { | ||||||
|  | 				allowChord = (ins != sus.last); | ||||||
|  | 				pad = (ins == sus.last); | ||||||
|  | 			}, { | ||||||
|  | 				if(i < (flatOrder.size - 1), { | ||||||
|  | 					allowChord = (isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not; | ||||||
|  | 					pad = false; | ||||||
|  | 				}, { | ||||||
|  | 					allowChord = false; | ||||||
|  | 					pad = true | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if((orderIndex == 0) && sus.includes(ins), { | ||||||
|  | 				dur = entrancesDurFunc.value(allowChord, pad); | ||||||
|  | 			}, { | ||||||
|  | 				dur = passagesDurFunc.value(allowChord, pad); | ||||||
|  | 			}); | ||||||
|  | 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); | ||||||
|  | 
 | ||||||
|  | 			voices[ins] = adder; | ||||||
|  | 			res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// pad ending | ||||||
|  | 	if(orderIndex == (orders.size - 1), { | ||||||
|  | 		(0..(popSize-1)).scramble.do({arg ins; | ||||||
|  | 			if(res.last.first[ins] != ["Rest"], { | ||||||
|  | 				var dur; | ||||||
|  | 				voices[ins] = ["Rest"]; | ||||||
|  | 				allowChord = (voices != popSize.collect({["Rest"]})); | ||||||
|  | 				pad = allowChord.not; | ||||||
|  | 				dur = exitsDurFunc.value(allowChord, pad); | ||||||
|  | 				res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	//format and return | ||||||
|  | 	if(startFromLast, {lastXChanges = lastXChangesHold}); | ||||||
|  | 	res; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------primary routines | ||||||
|  | 
 | ||||||
|  | genMotif = { | ||||||
|  | 	var repeats, fSeq; | ||||||
|  | 
 | ||||||
|  | 	repeats = 1; | ||||||
|  | 	fSeq = []; | ||||||
|  | 
 | ||||||
|  | 	repeats.do({arg index; | ||||||
|  | 		var motif; | ||||||
|  | 
 | ||||||
|  | 		motif = []; | ||||||
|  | 
 | ||||||
|  | 		orders.do({arg order, o; | ||||||
|  | 			var lastState, subMotif; | ||||||
|  | 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); | ||||||
|  | 			subMotif = genSubMotif.value(order, o, lastState, isLastOrder: o == (orders.size - 1)); | ||||||
|  | 			motif = motif.add(subMotif); | ||||||
|  | 
 | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		sanityCheck.value(motif, index); | ||||||
|  | 
 | ||||||
|  | 		fSeq = fSeq.add(motif); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSecondarySeq = {arg seq; | ||||||
|  | 	var curdles, fSeq; | ||||||
|  | 	curdles = []; | ||||||
|  | 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); | ||||||
|  | 
 | ||||||
|  | 	fSeq = seq.clumps(curdles).collect({arg clump, m; | ||||||
|  | 		var repeats, paddedSeq; | ||||||
|  | 
 | ||||||
|  | 		//add rest | ||||||
|  | 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); | ||||||
|  | 
 | ||||||
|  | 		//implement repeats | ||||||
|  | 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); | ||||||
|  | 		repeats.collect({paddedSeq}); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------audition funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~addr.sendMsg(~indexPath, ~indexMsg); | ||||||
|  | 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); | ||||||
|  | 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~msg.postln; | ||||||
|  | 		~addr.sendMsg(~path, *~msg); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | genPatterns = {arg inSeq, addr, oneShot = false; | ||||||
|  | 	var voices, durs, pbinds, res, indices, sectionDurs, msg, ids, seq; | ||||||
|  | 	seq = inSeq.collect({arg mSeq; mSeq[0]}); | ||||||
|  | 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	pbinds = voices.flop.collect({arg voice, v; | ||||||
|  | 		var clumps, hdScores, freqs, fDurs; | ||||||
|  | 		clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 		freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 		fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \string_model, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			), | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \sine, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	}).flatten; | ||||||
|  | 	if(oneShot.not, { | ||||||
|  | 		msg = inSeq.collect({arg mSeq, m; mSeq[1..]}); | ||||||
|  | 		//ids = inSeq.collect({arg mSeq, m; mSeq[2]}); | ||||||
|  | 		sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); | ||||||
|  | 		pbinds = pbinds ++ | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \osc, | ||||||
|  | 				\addr, addr, | ||||||
|  | 				\path, "/playing", | ||||||
|  | 				\msg, Pseq(msg, 1), | ||||||
|  | 				\dur, Pseq(sectionDurs, 1) | ||||||
|  | 			); | ||||||
|  | 		] | ||||||
|  | 	}); | ||||||
|  | 	res = Ppar(pbinds); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | genMidiPatterns = {arg seq; | ||||||
|  | 	var voices, durs, patterns, res, mOut, pbRange; | ||||||
|  | 	pbRange = 1; //semitones - change this as needed for your situation | ||||||
|  | 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); | ||||||
|  | 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	res = Ppar( | ||||||
|  | 		voices.flop.collect({arg voice, v; | ||||||
|  | 			var clumps, hdScores, freqs, fDurs; | ||||||
|  | 
 | ||||||
|  | 			mOut.program(v, 70); | ||||||
|  | 
 | ||||||
|  | 			clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \midi, | ||||||
|  | 				\chan, v, | ||||||
|  | 				\noteval, Pseq(freqs.cpsmidi - 24, 1), | ||||||
|  | 				\note, Pfunc({ | event | event[\noteval].floor }), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\midiout, mOut, | ||||||
|  | 				\amp, 1, | ||||||
|  | 				\bend, Pfunc({ | ||||||
|  | 					| event | | ||||||
|  | 					if (event[\note].isRest.not) { | ||||||
|  | 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; | ||||||
|  | 						m.bend(v, pitchbendvalue); | ||||||
|  | 					}; | ||||||
|  | 					0; // return something other than nil to avoid stopping the pattern | ||||||
|  | 				}), | ||||||
|  | 			); | ||||||
|  | 		}); | ||||||
|  | 	); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------resource management funcs | ||||||
|  | 
 | ||||||
|  | genUID = {Date.seed.asHexString.toLower}; | ||||||
|  | 
 | ||||||
|  | seedFunc = {arg func, seed; | ||||||
|  | 	var funcArgs, next; | ||||||
|  | 	next = Routine({loop{func.valueArray(funcArgs).yield }}); | ||||||
|  | 	next.randSeed_(seed); | ||||||
|  | 	{arg ...args; funcArgs = args; next.value} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | stringifyToDepth = {arg data, maxDepth = 1; | ||||||
|  | 	var prettyString = "", rCount = 0, writeArray, indent; | ||||||
|  | 
 | ||||||
|  | 	if(maxDepth == 0, { | ||||||
|  | 		data.asCompileString | ||||||
|  | 	}, { | ||||||
|  | 		indent = {arg size; size.collect({" "}).join("")}; | ||||||
|  | 		writeArray = {arg array; | ||||||
|  | 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; | ||||||
|  | 			rCount = rCount + 1; | ||||||
|  | 			if(rCount < maxDepth, { | ||||||
|  | 				array.do({arg subArray; writeArray.value(subArray)}); | ||||||
|  | 			}, { | ||||||
|  | 				prettyString = prettyString ++ array.collect({arg subArray; | ||||||
|  | 					indent.value(rCount + 1) ++ subArray.asCompileString | ||||||
|  | 				}).join(",\n"); | ||||||
|  | 			}); | ||||||
|  | 			rCount = rCount - 1; | ||||||
|  | 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		writeArray.value(data); | ||||||
|  | 		prettyString.replace(",\n\n", "\n").drop(-2); | ||||||
|  | 	}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | sanityCheck = {arg motif, index; | ||||||
|  | 	//print functions = very helpful | ||||||
|  | 	("----------" + index + "------------").postln; | ||||||
|  | 
 | ||||||
|  | 	motif.flatten.do({arg val, v; | ||||||
|  | 		if(v > 0, { | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); | ||||||
|  | 		}); | ||||||
|  | 		val.postln | ||||||
|  | 	}); | ||||||
|  | 	"***********".postln; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; | ||||||
|  | 	var res; | ||||||
|  | 
 | ||||||
|  | 	res = in; | ||||||
|  | 	if(res.isNil.not, { | ||||||
|  | 		if((res.isArray && res.isString.not), { | ||||||
|  | 			res = res.asCompileString; | ||||||
|  | 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); | ||||||
|  | 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); | ||||||
|  | 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); | ||||||
|  | 			res = res.replace("Rest", "\"Rest\""); | ||||||
|  | 			res = res.interpret; | ||||||
|  | 		}, { | ||||||
|  | 			//res.postln; | ||||||
|  | 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | writeResources = {arg path, dict; | ||||||
|  | 	var file, modelItems, resString; | ||||||
|  | 	file = File(path,"w"); | ||||||
|  | 
 | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	resString = nameSpaces.collect({arg nameSpace; | ||||||
|  | 		var depth = 0, insert = " "; | ||||||
|  | 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "order", {depth = 1; insert = "\n"}); | ||||||
|  | 		if((nameSpace == "ref_uid") && (dict[nameSpace] == nil), {dict[nameSpace] = "nil"}); | ||||||
|  | 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(dict[nameSpace], depth) | ||||||
|  | 	}).join(",\n"); | ||||||
|  | 
 | ||||||
|  | 	resString = "{\n" ++ resString ++ "\n}"; | ||||||
|  | 
 | ||||||
|  | 	file.write(resString); | ||||||
|  | 	file.close; | ||||||
|  | 	resString | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; | ||||||
|  | 
 | ||||||
|  | loadModelJSON = {arg jsonObject; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS; nS->msgInterpret.value(jsonObject[nS])})); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | setGlobalVars = {arg dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	# seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 	entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 	motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | globalVarsToDict = { | ||||||
|  | 	var modelItems, dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerFile = {arg path; | ||||||
|  | 	ledgerPath = path; | ||||||
|  | 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; | ||||||
|  | 
 | ||||||
|  | saveLedger = {arg ledger, path; | ||||||
|  | 	var file; | ||||||
|  | 	file = File(path, "w"); | ||||||
|  | 	file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); | ||||||
|  | 	file.close; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------global vars | ||||||
|  | 
 | ||||||
|  | primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; | ||||||
|  | //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; | ||||||
|  | exPath = thisProcess.nowExecutingPath; | ||||||
|  | dir = exPath.dirname; | ||||||
|  | //popSize = 4; | ||||||
|  | dims = primes.size; | ||||||
|  | tuples = genTuples.value(); | ||||||
|  | //refUID = nil; | ||||||
|  | group = Group.new; | ||||||
|  | ~group = group; | ||||||
|  | loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); | ||||||
|  | //passagesWeights = [1, 1, 1, 1, 1]; | ||||||
|  | //susWeights = [1, 1, 1]; | ||||||
|  | // order really matters!!!! | ||||||
|  | nameSpaces = [ | ||||||
|  | 	"music_data", "last_changes", "cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", | ||||||
|  | 	"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", | ||||||
|  | 	"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", | ||||||
|  | 	"motif_edited", "order_edited" | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------OSC funcs | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_ledger, {arg msg, time, addr, port; | ||||||
|  | 	loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \load_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_model, {arg msg, time, addr, port; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = loadModelFile.value(msg[1].asString); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | }, \load_model); | ||||||
|  | 
 | ||||||
|  | OSCdef(\save_ledger, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	ledger = msgInterpret.value(msg[1].asString.parseJSON["ledger"], false).postln; | ||||||
|  | 	//loadLedgerJSON.value(msg[0]) | ||||||
|  | 	saveLedger.value(ledger, msg[2].asString); | ||||||
|  | 	//loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \save_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\generate, {arg msg, time, addr, port; | ||||||
|  | 	var path, dict, durSeeds, musPath, modelString; | ||||||
|  | 	msg.postln; | ||||||
|  | 
 | ||||||
|  | 	path = msg[1].asString; | ||||||
|  | 
 | ||||||
|  | 	dict = loadModelFile.value(path); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | 
 | ||||||
|  | 	popSize = ranges.size; | ||||||
|  | 
 | ||||||
|  | 	//refUID.postln; | ||||||
|  | 
 | ||||||
|  | 	loadLedgerFile.value(ledgerPath); | ||||||
|  | 	if(ledger == nil, {ledger = ["tmp"]}); | ||||||
|  | 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); | ||||||
|  | 
 | ||||||
|  | 	lastXChanges = if(refUID == nil, { | ||||||
|  | 		[initVoices.value().deepCopy]; | ||||||
|  | 	}, { | ||||||
|  | 		var file; | ||||||
|  | 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); | ||||||
|  | 		msgInterpret.value(file.readAllString.parseJSON["last_changes"]); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	durSeeds = seedFunc.value({3.collect({rrand(100000, 999999)})}, durSeed).value.postln; | ||||||
|  | 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..4] ++ [entrancesProbVals[5..]] ++ [durSeeds[0]]); | ||||||
|  | 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..4] ++ [passagesProbVals[5..]] ++ [durSeeds[1]]); | ||||||
|  | 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..4] ++ [exitsProbVals[5..]] ++ [durSeeds[2]]); | ||||||
|  | 
 | ||||||
|  | 	if(orders == nil, { | ||||||
|  | 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); | ||||||
|  | 		//addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); | ||||||
|  | 	}); | ||||||
|  | 	seq = seedFunc.value(genMotif, motifSeed).value; | ||||||
|  | 
 | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	modelString = writeResources.value(path, dict); | ||||||
|  | 
 | ||||||
|  | 	//addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); | ||||||
|  | 	addr.sendMsg("/generated", path, modelString); | ||||||
|  | }, \generate); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | OSCdef(\commit, {arg msg, time, addr, port; | ||||||
|  | 	var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; | ||||||
|  | 	//msg.postln; | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	test1 = msg[1].asString.parseJSON; | ||||||
|  | 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; | ||||||
|  | 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; | ||||||
|  | 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; | ||||||
|  | 	(test1["music"] == test2["music_data"]).postln; | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; | ||||||
|  | 	musicChanged = (musicData != seq).postln; | ||||||
|  | 
 | ||||||
|  | 	curUID = genUID.value; | ||||||
|  | 
 | ||||||
|  | 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); | ||||||
|  | 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); | ||||||
|  | 
 | ||||||
|  | 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	if(musicChanged, { | ||||||
|  | 		seq = musicData; | ||||||
|  | 		dict["music_data"] = seq; | ||||||
|  | 		dict["motif_edited"] = "true" | ||||||
|  | 	}); | ||||||
|  | 	dict["cur_uid"] = curUID; | ||||||
|  | 
 | ||||||
|  | 	writeResources.value(modelPath, dict); | ||||||
|  | 
 | ||||||
|  | 	File.delete(ledgerPath ++ "_bak"); | ||||||
|  | 	File.copy(ledgerPath, ledgerPath ++ "_bak"); | ||||||
|  | 	File.delete(ledgerPath); | ||||||
|  | 	ledger = ledger.drop(-1).add(curUID); | ||||||
|  | 
 | ||||||
|  | 	saveLedger.value(ledger, ledgerPath); | ||||||
|  | 
 | ||||||
|  | 	addr.sendMsg("/committed", curUID, ledgerPath); | ||||||
|  | 	//refUID = curUID; | ||||||
|  | 
 | ||||||
|  | }, \commit); | ||||||
|  | 
 | ||||||
|  | OSCdef(\transport, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	if(msg[1] == 0, { | ||||||
|  | 		player.stop; | ||||||
|  | 		group.set(\gate, 0); | ||||||
|  | 	}, { | ||||||
|  | 		// the cued sequence can now be read from file, so this can be cleaned up | ||||||
|  | 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; | ||||||
|  | 		if(msg[1] == 1, { | ||||||
|  | 			pSeq = []; | ||||||
|  | 			cuedSeek = (seq != nil); | ||||||
|  | 			indexStart = msg[2].asInteger; | ||||||
|  | 			indexEnd = ledger.size - if(cuedSeek, {2}, {1}); | ||||||
|  | 			//ledger.postln; | ||||||
|  | 			if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { | ||||||
|  | 				ledger[indexStart..indexEnd].do({arg uid, index; | ||||||
|  | 					var path, file; | ||||||
|  | 					path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 					file = File(path, "r"); | ||||||
|  | 					pSeq = pSeq.add([msgInterpret.value(file.readAllString.postln.parseJSON["music_data"]), path, indexStart + index, uid]); | ||||||
|  | 					file.close; | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if(cuedSeek, { | ||||||
|  | 				var path, file; | ||||||
|  | 				path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; | ||||||
|  | 				file = File(path, "r"); | ||||||
|  | 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, ledger.size - 1, "tmp"]); | ||||||
|  | 				file.close; | ||||||
|  | 			}); | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr); | ||||||
|  | 		}, { | ||||||
|  | 			pSeq = [loadModelJSON.value(msg[2].asString.parseJSON)["music_data"].postln]; | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr, true); | ||||||
|  | 		}); | ||||||
|  | 		player = Pfset(pattern: patterns, cleanupFunc: { | ||||||
|  | 			addr.sendMsg("/transport", 0); | ||||||
|  | 			addr.sendMsg("/one_shot", 0); | ||||||
|  | 		}); | ||||||
|  | 		player = player.play | ||||||
|  | 	}); | ||||||
|  | }, \transport); | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | //synthdefs | ||||||
|  | ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sineBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~bassBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~hdustBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~samplerBusArray = 2.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sBuf = Buffer.alloc(s, 10, 2); | ||||||
|  | SynthDef(\string_model, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.5).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~stringModelBusArray), sig1 * EnvGen.kr(Env.asr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | 	//Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var sig; | ||||||
|  | 	sig = SinOsc.ar(freq); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.asr(0.3, 0.4, 0.3), gate, timeScale: dur, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; | ||||||
|  | 	var nameSpaces, sigs; | ||||||
|  | 
 | ||||||
|  | 	sigs = [~stringModelBusArray, ~sineBusArray, ~bassBusArray, ~hdustBusArray, ~samplerBusArray].collect({arg busArray, i; | ||||||
|  | 		var nameSpace, sig; | ||||||
|  | 		nameSpace = ['string', 'sine', 'bass', 'hdust', 'sampler'][i]; | ||||||
|  | 		sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = Mix.ar(sig) * NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.1); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	sigs = Mix.ar(sigs / 4); | ||||||
|  | 	Out.ar(0, sigs) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\bass, { | ||||||
|  | 	var switches, drone; | ||||||
|  | 	switches = {|i| Dust.kr(0.1)} ! 9; | ||||||
|  | 	drone = {|i| var harm = pow(2, 2 - (i / 3).trunc), amp = (1 / pow(harm, 2)); | ||||||
|  | 		SinOsc.ar(60 * harm + TRand.kr(-3, 3, switches[i]), 0, amp)} ! 9; | ||||||
|  | 	Out.ar(~bassBusArray[0], Mix.new(drone) * 0.2); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sampler, { | ||||||
|  | 	Out.ar(~samplerBusArray, PlayBuf.ar(2, ~sBuf, BufRateScale.kr(~sBuf), doneAction: 2)) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | // main routine | ||||||
|  | SynthDef(\hdust, { | ||||||
|  | 	arg gate = 0; | ||||||
|  | 	var hierarchical_dust, low_sine, high_sine, brown_noise, white_noise; | ||||||
|  | 	// this triggers the combinations of sources | ||||||
|  | 	// it is similar to the Supercollider UGen called dust but with a hierarchical structure | ||||||
|  | 	hierarchical_dust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(0.1)) | ||||||
|  | 	); | ||||||
|  | 	// adjust the multiplier at the end of each line for adjusting levels | ||||||
|  | 	// note with each trigger, each source has a 1 in 3 chance of sounding | ||||||
|  | 	low_sine = SinOsc.ar(76.midicps / 16) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.1; | ||||||
|  | 	high_sine = SinOsc.ar(76.midicps * 8) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.01; | ||||||
|  | 	brown_noise = BrownNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.025; | ||||||
|  | 	white_noise = WhiteNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.02; | ||||||
|  | 	Out.ar(~hdustBusArray[0], | ||||||
|  | 		((low_sine + high_sine + brown_noise + white_noise) ) | ||||||
|  | 	); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | var bass, hdust, sampler, mixer; | ||||||
|  | bass = Synth.tail(~group, \bass); | ||||||
|  | hdust = Synth.tail(~group, \hdust); | ||||||
|  | sampler = Synth.head(~group, \sampler); | ||||||
|  | mixer = Synth.tail(~group, \mixer); | ||||||
|  | OSCdef(\mixer, {arg msg, time, addr, port; | ||||||
|  | 	mixer.set((msg[1] ++ '_' ++ msg[2] ++ '_' ++ msg[3]), msg[4]) | ||||||
|  | }, \mixer); | ||||||
|  | 
 | ||||||
|  | OSCdef(\sampler, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	sampler.free; | ||||||
|  | 	~sBuf.free; | ||||||
|  | 	~sBuf = Buffer.read(s, msg[1].asString.postln, action: {sampler = Synth.head(~group, \sampler)}); | ||||||
|  | }, \sampler); | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /* old something | ||||||
|  | ( | ||||||
|  | SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	freq = WhiteNoise.ar * 3 + freq; | ||||||
|  | 	freqFinal = Duty.ar((1/freq), 0, freq); | ||||||
|  | 	trig = Changed.ar(freqFinal); | ||||||
|  | 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); | ||||||
|  | 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); | ||||||
|  | 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 
 | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | ) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| @ -0,0 +1,41 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.375 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.75 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.875 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ] ], 3.375 ], | ||||||
|  |     [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ] ], 0.25 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ] ], 2 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 2.25 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.125 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], | ||||||
|  |   [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "6d743c5c", | ||||||
|  | "ref_uid": "nil", | ||||||
|  | "order_seed": 232987, | ||||||
|  | "dur_seed": 390795, | ||||||
|  | "motifs_seed": 257319, | ||||||
|  | "entrances_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0, 0, 1.984126984127, 0, 3.0769230769231, 0, 0.64527027027027, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ 1419.1950464396, 2400 ], [ 1519.5046439628, 2400 ], [ 1541.7956656347, 2237 ], [ 1519.5046439628, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 1, 2 ], [ 3 ], [  ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.75, 0.69, 0.75 ], | ||||||
|  | "order_size": [ 1, 2 ], | ||||||
|  | "passages_size": [ 0, 2 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,894 @@ | |||||||
|  | ( | ||||||
|  | // helper funcs | ||||||
|  | var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; | ||||||
|  | 
 | ||||||
|  | // score funcs | ||||||
|  | var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; | ||||||
|  | 
 | ||||||
|  | // subroutines | ||||||
|  | var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; | ||||||
|  | 
 | ||||||
|  | // primary routines | ||||||
|  | var genMotif, genSecondarySeq; | ||||||
|  | 
 | ||||||
|  | // audition funcs | ||||||
|  | var genPatterns, genMidiPatterns; | ||||||
|  | 
 | ||||||
|  | // resource management funcs | ||||||
|  | var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, | ||||||
|  | msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON, | ||||||
|  | setGlobalVars, globalVarsToDict, saveLedger; | ||||||
|  | 
 | ||||||
|  | // model vars | ||||||
|  | //(model and global vars mostly set by OSC funcs | ||||||
|  | var seq, lastXChanges, | ||||||
|  | curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | motifEdited, orderEdited; | ||||||
|  | 
 | ||||||
|  | // model aux vars | ||||||
|  | var entrancesDurFunc, passagesDurFunc, exitsDurFunc; | ||||||
|  | 
 | ||||||
|  | // other global vars | ||||||
|  | var popSize, exPath, dir, primes, dims, tuples, | ||||||
|  | group, player, ledgerPath, ledger, currentlyPlayingUID, | ||||||
|  | nameSpaces; | ||||||
|  | 
 | ||||||
|  | // install JSON quark | ||||||
|  | if(Quarks.isInstalled("JSONlib").not, { | ||||||
|  | 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); | ||||||
|  | 	thisProcess.recompile; | ||||||
|  | 	//HelpBrowser.openHelpFor("Classes/JSONlib"); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------helper funcs | ||||||
|  | 
 | ||||||
|  | hsArrayToCents = { | ||||||
|  | 	arg hsArray; | ||||||
|  | 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pDist = { | ||||||
|  | 	arg array1, array2, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); | ||||||
|  | 	if(signed, {pDistance}, {abs(pDistance)}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hdSum = { | ||||||
|  | 	arg hsArrays; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays.size; | ||||||
|  | 	distances = (size - 1).collect({arg i; | ||||||
|  | 		((i + 1)..(size - 1)).collect({arg j; | ||||||
|  | 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsChordalDistance = { | ||||||
|  | 	arg hsArrays1, hsArrays2; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays1.size; | ||||||
|  | 	distances = hsArrays1.size.collect({arg i; | ||||||
|  | 		hsArrays2.size.collect({arg j; | ||||||
|  | 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsArrayToFreq = { | ||||||
|  | 	arg array; | ||||||
|  | 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------score funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | isInRange = { | ||||||
|  | 	arg hsArray, min, max; | ||||||
|  | 	var cents; | ||||||
|  | 	cents = hsArrayToCents.value(hsArray); | ||||||
|  | 	(cents >= min) && (cents <= max) | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | spacingScore = { | ||||||
|  | 	arg hsArrays, min; | ||||||
|  | 	var centsArray; | ||||||
|  | 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); | ||||||
|  | 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | rangeScore = { | ||||||
|  | 	arg hsArray1, hsArray2, min, max, low, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | intervalScore = { | ||||||
|  | 	arg hsArray1, hsArray2, mean, sd, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	pDistance.gaussCurve(1, mean, sd) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | inclusionScore = { | ||||||
|  | 	arg array, test, min = 0.01; | ||||||
|  | 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------subroutines | ||||||
|  | 
 | ||||||
|  | genTuples = { | ||||||
|  | 	var tuples; | ||||||
|  | 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); | ||||||
|  | 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | initVoices = { | ||||||
|  | 	var init, voicesInit; | ||||||
|  | 	voicesInit = popSize.collect({dims.collect({0})}); | ||||||
|  | 	/* | ||||||
|  | 	voicesInit = [dims.collect({0})]; | ||||||
|  | 	(popSize - 1).do({ | ||||||
|  | 		arg rep, new; | ||||||
|  | 		rep = dims.rand; | ||||||
|  | 		new = voicesInit.last.deepCopy; | ||||||
|  | 		new[rep] = new[rep] + [-1, 1].choose(); | ||||||
|  | 		voicesInit = voicesInit.add(new); | ||||||
|  | 	}); | ||||||
|  | 	*/ | ||||||
|  | 	voicesInit.deepCopy; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; | ||||||
|  | 	var env, pTable, durFunc; | ||||||
|  | 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; | ||||||
|  | 	pTable = env.asRandomTable; | ||||||
|  | 	[chordProb, minPad, maxPad, minDur, maxDur, envData].postln; | ||||||
|  | 	durFunc = {arg allowChord, pad = false; | ||||||
|  | 		var res; | ||||||
|  | 		res = if(allowChord.not, { | ||||||
|  | 			pTable.tableRand * (maxDur - minDur) + minDur | ||||||
|  | 		}, { | ||||||
|  | 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (maxDur - minDur) + minDur}); | ||||||
|  | 		}).round(0.125); | ||||||
|  | 		if(pad, {res = res + rrand(minPad.asFloat, maxPad.asFloat).round(0.125)}); | ||||||
|  | 		if(res.asInteger == res, {res = res.asInteger}); | ||||||
|  | 		res | ||||||
|  | 	}; | ||||||
|  | 	seedFunc.value(durFunc, seed); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; | ||||||
|  | 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ | ||||||
|  | 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; | ||||||
|  | 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); | ||||||
|  | 		noProgIns = (popSize - noSusIns).rand + 1; | ||||||
|  | 		noSilentIns = popSize - noSusIns - noProgIns; | ||||||
|  | 
 | ||||||
|  | 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); | ||||||
|  | 
 | ||||||
|  | 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); | ||||||
|  | 		if(silent == nil, {silent = []}); | ||||||
|  | 		[sus.scramble, prog, silent.scramble] | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | updateVoices = {arg ins, sus; | ||||||
|  | 	var voices, candidates, nWeights, nProbs, sel; | ||||||
|  | 
 | ||||||
|  | 	voices = lastXChanges.deepCopy.last; | ||||||
|  | 
 | ||||||
|  | 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; | ||||||
|  | 	candidates = difference(candidates.asSet, voices.asSet).asList; | ||||||
|  | 	nProbs = candidates.collect({arg candidate; | ||||||
|  | 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; | ||||||
|  | 
 | ||||||
|  | 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); | ||||||
|  | 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); | ||||||
|  | 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); | ||||||
|  | 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); | ||||||
|  | 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); | ||||||
|  | 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); | ||||||
|  | 		//maybe what you want here is a vector to another root and then favoring movement towards it. | ||||||
|  | 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); | ||||||
|  | 
 | ||||||
|  | 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	nWeights = passagesWeights; | ||||||
|  | 
 | ||||||
|  | 	//this handles nWeights of 0; mainly for testing | ||||||
|  | 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; | ||||||
|  | 	nWeights = nWeights.select({arg weight; weight != 0}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; | ||||||
|  | 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) | ||||||
|  | 	}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; | ||||||
|  | 
 | ||||||
|  | 	sel = candidates.wchoose(nProbs); | ||||||
|  | 
 | ||||||
|  | 	voices[ins] = sel; | ||||||
|  | 	lastXChanges = lastXChanges.add(voices).keep(-5); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; | ||||||
|  | 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, pad, lastXChangesHold, voices, adder; | ||||||
|  | 	# sus, prog, silent = order; | ||||||
|  | 	flatOrder = silent ++ sus ++ prog; | ||||||
|  | 	lastXChangesHold = lastXChanges.deepCopy; | ||||||
|  | 	voices = lastState.deepCopy; | ||||||
|  | 	isInChord = popSize.collect({false}); | ||||||
|  | 	allowChord = false; | ||||||
|  | 	pad = false; | ||||||
|  | 	res = []; | ||||||
|  | 	"------generating motif".postln; | ||||||
|  | 	//need to figure out here if voices move between motifs | ||||||
|  | 	flatOrder.do({arg ins, i; | ||||||
|  | 
 | ||||||
|  | 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); | ||||||
|  | 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); | ||||||
|  | 
 | ||||||
|  | 		if(voices[ins] != adder, { | ||||||
|  | 			var dur; | ||||||
|  | 
 | ||||||
|  | 			if((sus ++ silent).includes(ins), { | ||||||
|  | 				allowChord = (ins != sus.last); | ||||||
|  | 				pad = (ins == sus.last); | ||||||
|  | 			}, { | ||||||
|  | 				if(i < (flatOrder.size - 1), { | ||||||
|  | 					allowChord = (isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not; | ||||||
|  | 					pad = false; | ||||||
|  | 				}, { | ||||||
|  | 					allowChord = false; | ||||||
|  | 					pad = true | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if((orderIndex == 0) && sus.includes(ins), { | ||||||
|  | 				dur = entrancesDurFunc.value(allowChord, pad); | ||||||
|  | 			}, { | ||||||
|  | 				dur = passagesDurFunc.value(allowChord, pad); | ||||||
|  | 			}); | ||||||
|  | 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); | ||||||
|  | 
 | ||||||
|  | 			voices[ins] = adder; | ||||||
|  | 			res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// pad ending | ||||||
|  | 	if(orderIndex == (orders.size - 1), { | ||||||
|  | 		(0..(popSize-1)).scramble.do({arg ins; | ||||||
|  | 			if(res.last.first[ins] != ["Rest"], { | ||||||
|  | 				var dur; | ||||||
|  | 				voices[ins] = ["Rest"]; | ||||||
|  | 				allowChord = (voices != popSize.collect({["Rest"]})); | ||||||
|  | 				pad = allowChord.not; | ||||||
|  | 				dur = exitsDurFunc.value(allowChord, pad); | ||||||
|  | 				res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	//format and return | ||||||
|  | 	if(startFromLast, {lastXChanges = lastXChangesHold.deepCopy}); | ||||||
|  | 	res; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------primary routines | ||||||
|  | 
 | ||||||
|  | genMotif = { | ||||||
|  | 	var repeats, fSeq; | ||||||
|  | 
 | ||||||
|  | 	repeats = 1; | ||||||
|  | 	fSeq = []; | ||||||
|  | 
 | ||||||
|  | 	repeats.do({arg index; | ||||||
|  | 		var motif; | ||||||
|  | 
 | ||||||
|  | 		motif = []; | ||||||
|  | 
 | ||||||
|  | 		orders.do({arg order, o; | ||||||
|  | 			var lastState, subMotif; | ||||||
|  | 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); | ||||||
|  | 			subMotif = genSubMotif.value(order, o, lastState, isLastOrder: o == (orders.size - 1)); | ||||||
|  | 			motif = motif.add(subMotif); | ||||||
|  | 
 | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		sanityCheck.value(motif, index); | ||||||
|  | 
 | ||||||
|  | 		fSeq = fSeq.add(motif); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSecondarySeq = {arg seq; | ||||||
|  | 	var curdles, fSeq; | ||||||
|  | 	curdles = []; | ||||||
|  | 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); | ||||||
|  | 
 | ||||||
|  | 	fSeq = seq.clumps(curdles).collect({arg clump, m; | ||||||
|  | 		var repeats, paddedSeq; | ||||||
|  | 
 | ||||||
|  | 		//add rest | ||||||
|  | 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); | ||||||
|  | 
 | ||||||
|  | 		//implement repeats | ||||||
|  | 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); | ||||||
|  | 		repeats.collect({paddedSeq}); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------audition funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~addr.sendMsg(~indexPath, ~indexMsg); | ||||||
|  | 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); | ||||||
|  | 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~msg.postln; | ||||||
|  | 		~addr.sendMsg(~path, *~msg); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | genPatterns = {arg inSeq, addr, oneShot = false; | ||||||
|  | 	var voices, durs, pbinds, res, indices, sectionDurs, msg, ids, seq; | ||||||
|  | 	seq = inSeq.collect({arg mSeq; mSeq[0]}); | ||||||
|  | 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	pbinds = voices.flop.collect({arg voice, v; | ||||||
|  | 		var clumps, hdScores, freqs, fDurs; | ||||||
|  | 		clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 		freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 		fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \string_model, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			), | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \sine, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	}).flatten; | ||||||
|  | 	if(oneShot.not, { | ||||||
|  | 		msg = inSeq.collect({arg mSeq, m; mSeq[1..]}); | ||||||
|  | 		//ids = inSeq.collect({arg mSeq, m; mSeq[2]}); | ||||||
|  | 		sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); | ||||||
|  | 		pbinds = pbinds ++ | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \osc, | ||||||
|  | 				\addr, addr, | ||||||
|  | 				\path, "/playing", | ||||||
|  | 				\msg, Pseq(msg, 1), | ||||||
|  | 				\dur, Pseq(sectionDurs, 1) | ||||||
|  | 			); | ||||||
|  | 		] | ||||||
|  | 	}); | ||||||
|  | 	res = Ppar(pbinds); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | genMidiPatterns = {arg seq; | ||||||
|  | 	var voices, durs, patterns, res, mOut, pbRange; | ||||||
|  | 	pbRange = 1; //semitones - change this as needed for your situation | ||||||
|  | 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); | ||||||
|  | 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	res = Ppar( | ||||||
|  | 		voices.flop.collect({arg voice, v; | ||||||
|  | 			var clumps, hdScores, freqs, fDurs; | ||||||
|  | 
 | ||||||
|  | 			mOut.program(v, 70); | ||||||
|  | 
 | ||||||
|  | 			clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \midi, | ||||||
|  | 				\chan, v, | ||||||
|  | 				\noteval, Pseq(freqs.cpsmidi - 24, 1), | ||||||
|  | 				\note, Pfunc({ | event | event[\noteval].floor }), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\midiout, mOut, | ||||||
|  | 				\amp, 1, | ||||||
|  | 				\bend, Pfunc({ | ||||||
|  | 					| event | | ||||||
|  | 					if (event[\note].isRest.not) { | ||||||
|  | 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; | ||||||
|  | 						m.bend(v, pitchbendvalue); | ||||||
|  | 					}; | ||||||
|  | 					0; // return something other than nil to avoid stopping the pattern | ||||||
|  | 				}), | ||||||
|  | 			); | ||||||
|  | 		}); | ||||||
|  | 	); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------resource management funcs | ||||||
|  | 
 | ||||||
|  | genUID = {Date.seed.asHexString.toLower}; | ||||||
|  | 
 | ||||||
|  | seedFunc = {arg func, seed; | ||||||
|  | 	var funcArgs, next; | ||||||
|  | 	next = Routine({loop{func.valueArray(funcArgs).yield }}); | ||||||
|  | 	next.randSeed_(seed); | ||||||
|  | 	{arg ...args; funcArgs = args; next.value} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | stringifyToDepth = {arg data, maxDepth = 1; | ||||||
|  | 	var prettyString = "", rCount = 0, writeArray, indent; | ||||||
|  | 
 | ||||||
|  | 	if(maxDepth == 0, { | ||||||
|  | 		data.asCompileString | ||||||
|  | 	}, { | ||||||
|  | 		indent = {arg size; size.collect({" "}).join("")}; | ||||||
|  | 		writeArray = {arg array; | ||||||
|  | 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; | ||||||
|  | 			rCount = rCount + 1; | ||||||
|  | 			if(rCount < maxDepth, { | ||||||
|  | 				array.do({arg subArray; writeArray.value(subArray)}); | ||||||
|  | 			}, { | ||||||
|  | 				prettyString = prettyString ++ array.collect({arg subArray; | ||||||
|  | 					indent.value(rCount + 1) ++ subArray.asCompileString | ||||||
|  | 				}).join(",\n"); | ||||||
|  | 			}); | ||||||
|  | 			rCount = rCount - 1; | ||||||
|  | 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		writeArray.value(data); | ||||||
|  | 		prettyString.replace(",\n\n", "\n").drop(-2); | ||||||
|  | 	}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | sanityCheck = {arg motif, index; | ||||||
|  | 	//print functions = very helpful | ||||||
|  | 	("----------" + index + "------------").postln; | ||||||
|  | 
 | ||||||
|  | 	motif.flatten.do({arg val, v; | ||||||
|  | 		if(v > 0, { | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); | ||||||
|  | 		}); | ||||||
|  | 		val.postln | ||||||
|  | 	}); | ||||||
|  | 	"***********".postln; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; | ||||||
|  | 	var res; | ||||||
|  | 
 | ||||||
|  | 	res = in; | ||||||
|  | 	if(res.isNil.not, { | ||||||
|  | 		if((res.isArray && res.isString.not), { | ||||||
|  | 			res = res.asCompileString; | ||||||
|  | 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); | ||||||
|  | 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); | ||||||
|  | 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); | ||||||
|  | 			res = res.replace("Rest", "\"Rest\""); | ||||||
|  | 			res = res.interpret; | ||||||
|  | 		}, { | ||||||
|  | 			//res.postln; | ||||||
|  | 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | writeResources = {arg path, dict; | ||||||
|  | 	var file, modelItems, resString; | ||||||
|  | 	file = File(path,"w"); | ||||||
|  | 
 | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	resString = nameSpaces.collect({arg nameSpace; | ||||||
|  | 		var depth = 0, insert = " "; | ||||||
|  | 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "order", {depth = 1; insert = "\n"}); | ||||||
|  | 		if((nameSpace == "ref_uid") && (dict[nameSpace] == nil), {dict[nameSpace] = "nil"}); | ||||||
|  | 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(dict[nameSpace], depth) | ||||||
|  | 	}).join(",\n"); | ||||||
|  | 
 | ||||||
|  | 	resString = "{\n" ++ resString ++ "\n}"; | ||||||
|  | 
 | ||||||
|  | 	file.write(resString); | ||||||
|  | 	file.close; | ||||||
|  | 	resString | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; | ||||||
|  | 
 | ||||||
|  | loadModelJSON = {arg jsonObject; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS; nS->msgInterpret.value(jsonObject[nS])})); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | setGlobalVars = {arg dict, skipLastXChanges = false; | ||||||
|  | 	var tmpLastXChanges; | ||||||
|  | 	tmpLastXChanges = lastXChanges.deepCopy; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	# seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 	entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 	motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); | ||||||
|  | 	if(skipLastXChanges, {lastXChanges = tmpLastXChanges}); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | globalVarsToDict = { | ||||||
|  | 	var modelItems, dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerFile = {arg path; | ||||||
|  | 	ledgerPath = path; | ||||||
|  | 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; | ||||||
|  | 
 | ||||||
|  | saveLedger = {arg ledger, path; | ||||||
|  | 	var file; | ||||||
|  | 	file = File(path, "w"); | ||||||
|  | 	file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); | ||||||
|  | 	file.close; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------global vars | ||||||
|  | 
 | ||||||
|  | primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; | ||||||
|  | //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; | ||||||
|  | exPath = thisProcess.nowExecutingPath; | ||||||
|  | dir = exPath.dirname; | ||||||
|  | //popSize = 4; | ||||||
|  | dims = primes.size; | ||||||
|  | tuples = genTuples.value(); | ||||||
|  | //refUID = nil; | ||||||
|  | group = Group.new; | ||||||
|  | ~group = group; | ||||||
|  | loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); | ||||||
|  | //passagesWeights = [1, 1, 1, 1, 1]; | ||||||
|  | //susWeights = [1, 1, 1]; | ||||||
|  | // order really matters!!!! | ||||||
|  | nameSpaces = [ | ||||||
|  | 	"music_data", "last_changes", "cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", | ||||||
|  | 	"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", | ||||||
|  | 	"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", | ||||||
|  | 	"motif_edited", "order_edited" | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------OSC funcs | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_ledger, {arg msg, time, addr, port; | ||||||
|  | 	loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \load_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_model, {arg msg, time, addr, port; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = loadModelFile.value(msg[1].asString); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | }, \load_model); | ||||||
|  | 
 | ||||||
|  | OSCdef(\save_ledger, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	ledger = msgInterpret.value(msg[1].asString.parseJSON["ledger"], false).postln; | ||||||
|  | 	//loadLedgerJSON.value(msg[0]) | ||||||
|  | 	saveLedger.value(ledger, msg[2].asString); | ||||||
|  | 	//loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \save_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\generate, {arg msg, time, addr, port; | ||||||
|  | 	var path, dict, durSeeds, musPath, modelString; | ||||||
|  | 	msg.postln; | ||||||
|  | 
 | ||||||
|  | 	path = msg[1].asString; | ||||||
|  | 
 | ||||||
|  | 	dict = loadModelFile.value(path); | ||||||
|  | 	setGlobalVars.value(dict, true); | ||||||
|  | 
 | ||||||
|  | 	popSize = ranges.size; | ||||||
|  | 
 | ||||||
|  | 	//refUID.postln; | ||||||
|  | 
 | ||||||
|  | 	loadLedgerFile.value(ledgerPath); | ||||||
|  | 	if(ledger == nil, {ledger = ["tmp"]}); | ||||||
|  | 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); | ||||||
|  | 
 | ||||||
|  | 	if(refUID == nil, {lastXChanges = [initVoices.value().deepCopy]}); | ||||||
|  | 	if((refUID != nil) && (refUID != "tmp"), { | ||||||
|  | 		var file; | ||||||
|  | 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); | ||||||
|  | 		lastXChanges = msgInterpret.value(file.readAllString.parseJSON["last_changes"]); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	refUID.postln; | ||||||
|  | 	lastXChanges.collect({arg item; item.postln}); | ||||||
|  | 
 | ||||||
|  | 	durSeeds = seedFunc.value({3.collect({rrand(100000, 999999)})}, durSeed).value.postln; | ||||||
|  | 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..4] ++ [entrancesProbVals[5..]] ++ [durSeeds[0]]); | ||||||
|  | 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..4] ++ [passagesProbVals[5..]] ++ [durSeeds[1]]); | ||||||
|  | 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..4] ++ [exitsProbVals[5..]] ++ [durSeeds[2]]); | ||||||
|  | 
 | ||||||
|  | 	if(orders == nil, { | ||||||
|  | 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); | ||||||
|  | 		//addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); | ||||||
|  | 	}); | ||||||
|  | 	seq = seedFunc.value(genMotif, motifSeed).value; | ||||||
|  | 
 | ||||||
|  | 	lastXChanges.collect({arg item; item.postln}); | ||||||
|  | 
 | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	modelString = writeResources.value(path, dict); | ||||||
|  | 
 | ||||||
|  | 	//addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); | ||||||
|  | 	addr.sendMsg("/generated", path, modelString, ledgerPath); | ||||||
|  | }, \generate); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | OSCdef(\commit, {arg msg, time, addr, port; | ||||||
|  | 	var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; | ||||||
|  | 	//msg.postln; | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	test1 = msg[1].asString.parseJSON; | ||||||
|  | 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; | ||||||
|  | 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; | ||||||
|  | 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; | ||||||
|  | 	(test1["music"] == test2["music_data"]).postln; | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; | ||||||
|  | 	musicChanged = (musicData != seq).postln; | ||||||
|  | 
 | ||||||
|  | 	curUID = genUID.value; | ||||||
|  | 
 | ||||||
|  | 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); | ||||||
|  | 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); | ||||||
|  | 
 | ||||||
|  | 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	if(musicChanged, { | ||||||
|  | 		seq = musicData; | ||||||
|  | 		dict["music_data"] = seq; | ||||||
|  | 		dict["motif_edited"] = "true" | ||||||
|  | 	}); | ||||||
|  | 	dict["cur_uid"] = curUID; | ||||||
|  | 
 | ||||||
|  | 	writeResources.value(modelPath, dict); | ||||||
|  | 
 | ||||||
|  | 	File.delete(ledgerPath ++ "_bak"); | ||||||
|  | 	File.copy(ledgerPath, ledgerPath ++ "_bak"); | ||||||
|  | 	File.delete(ledgerPath); | ||||||
|  | 	ledger = ledger.drop(-1).add(curUID); | ||||||
|  | 
 | ||||||
|  | 	saveLedger.value(ledger, ledgerPath); | ||||||
|  | 
 | ||||||
|  | 	addr.sendMsg("/committed", curUID, ledgerPath); | ||||||
|  | 	//refUID = curUID; | ||||||
|  | 
 | ||||||
|  | }, \commit); | ||||||
|  | 
 | ||||||
|  | OSCdef(\transport, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	if(msg[1] == 0, { | ||||||
|  | 		player.stop; | ||||||
|  | 		group.set(\gate, 0); | ||||||
|  | 	}, { | ||||||
|  | 		// the cued sequence can now be read from file, so this can be cleaned up | ||||||
|  | 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; | ||||||
|  | 		if(msg[1] == 1, { | ||||||
|  | 			pSeq = []; | ||||||
|  | 			cuedSeek = (seq != nil); | ||||||
|  | 			indexStart = msg[2].asInteger; | ||||||
|  | 			indexEnd = ledger.size - if(cuedSeek, {2}, {1}); | ||||||
|  | 			//ledger.postln; | ||||||
|  | 			if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { | ||||||
|  | 				ledger[indexStart..indexEnd].do({arg uid, index; | ||||||
|  | 					var path, file; | ||||||
|  | 					path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 					file = File(path, "r"); | ||||||
|  | 					pSeq = pSeq.add([msgInterpret.value(file.readAllString.postln.parseJSON["music_data"]), path, indexStart + index, uid]); | ||||||
|  | 					file.close; | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if(cuedSeek, { | ||||||
|  | 				var path, file; | ||||||
|  | 				path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; | ||||||
|  | 				file = File(path, "r"); | ||||||
|  | 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, ledger.size - 1, "tmp"]); | ||||||
|  | 				file.close; | ||||||
|  | 			}); | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr); | ||||||
|  | 		}, { | ||||||
|  | 			pSeq = [loadModelJSON.value(msg[2].asString.parseJSON)["music_data"].postln]; | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr, true); | ||||||
|  | 		}); | ||||||
|  | 		player = Pfset(pattern: patterns, cleanupFunc: { | ||||||
|  | 			addr.sendMsg("/transport", 0); | ||||||
|  | 			addr.sendMsg("/one_shot", 0); | ||||||
|  | 		}); | ||||||
|  | 		player = player.play | ||||||
|  | 	}); | ||||||
|  | }, \transport); | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | //synthdefs | ||||||
|  | ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sineBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~bassBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~hdustBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~samplerBusArray = 2.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sBuf = Buffer.alloc(s, 10, 2); | ||||||
|  | SynthDef(\string_model, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~stringModelBusArray), sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | 	//Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var sig; | ||||||
|  | 	sig = SinOsc.ar(freq); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.asr(0.3, 0.4, 0.3), gate, timeScale: dur, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; | ||||||
|  | 	var nameSpaces, sigs, hierarchicalDust; | ||||||
|  | 
 | ||||||
|  | 	hierarchicalDust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	sigs = [~stringModelBusArray, ~sineBusArray, ~bassBusArray, ~hdustBusArray, ~samplerBusArray].collect({arg busArray, i; | ||||||
|  | 		var nameSpace, sig; | ||||||
|  | 		nameSpace = ['string', 'sine', 'bass', 'hdust', 'sampler'][i]; | ||||||
|  | 		sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = Mix.ar(sig) * pow(NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.1), 2); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	sigs = Mix.ar(sigs / 4); | ||||||
|  | 	Out.ar(0, sigs) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\bass, { | ||||||
|  | 	var switches, drone; | ||||||
|  | 	switches = {|i| Dust.kr(0.1)} ! 9; | ||||||
|  | 	drone = {|i| var harm = pow(2, 2 - (i / 3).trunc), amp = (1 / pow(harm, 2)); | ||||||
|  | 		SinOsc.ar(60 * harm + TRand.kr(-3, 3, switches[i]), 0, amp)} ! 9; | ||||||
|  | 	Out.ar(~bassBusArray[0], Mix.new(drone) * 0.2); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sampler, { | ||||||
|  | 	Out.ar(~samplerBusArray, PlayBuf.ar(2, ~sBuf, BufRateScale.kr(~sBuf), doneAction: 2)) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | // main routine | ||||||
|  | SynthDef(\hdust, { | ||||||
|  | 	arg gate = 0; | ||||||
|  | 	var hierarchical_dust, low_sine, high_sine, brown_noise, white_noise; | ||||||
|  | 	// this triggers the combinations of sources | ||||||
|  | 	// it is similar to the Supercollider UGen called dust but with a hierarchical structure | ||||||
|  | 	hierarchical_dust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(0.1)) | ||||||
|  | 	); | ||||||
|  | 	// adjust the multiplier at the end of each line for adjusting levels | ||||||
|  | 	// note with each trigger, each source has a 1 in 3 chance of sounding | ||||||
|  | 	low_sine = SinOsc.ar(76.midicps / 16) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.1; | ||||||
|  | 	high_sine = SinOsc.ar(76.midicps * 8) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.01; | ||||||
|  | 	brown_noise = BrownNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.025; | ||||||
|  | 	white_noise = WhiteNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.02; | ||||||
|  | 	Out.ar(~hdustBusArray[0], | ||||||
|  | 		((low_sine + high_sine + brown_noise + white_noise) ) | ||||||
|  | 	); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | var bass, hdust, sampler, mixer; | ||||||
|  | bass = Synth.tail(~group, \bass); | ||||||
|  | hdust = Synth.tail(~group, \hdust); | ||||||
|  | sampler = Synth.head(~group, \sampler); | ||||||
|  | mixer = Synth.tail(~group, \mixer); | ||||||
|  | OSCdef(\mixer, {arg msg, time, addr, port; | ||||||
|  | 	mixer.set((msg[1] ++ '_' ++ msg[2] ++ '_' ++ msg[3]), msg[4]) | ||||||
|  | }, \mixer); | ||||||
|  | 
 | ||||||
|  | OSCdef(\sampler, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	sampler.free; | ||||||
|  | 	~sBuf.free; | ||||||
|  | 	~sBuf = Buffer.read(s, msg[1].asString.postln, action: {sampler = Synth.head(~group, \sampler)}); | ||||||
|  | }, \sampler); | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /* old something | ||||||
|  | ( | ||||||
|  | SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	freq = WhiteNoise.ar * 3 + freq; | ||||||
|  | 	freqFinal = Duty.ar((1/freq), 0, freq); | ||||||
|  | 	trig = Changed.ar(freqFinal); | ||||||
|  | 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); | ||||||
|  | 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); | ||||||
|  | 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 
 | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | ) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| @ -0,0 +1,51 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ 0, 0, 0, 0, 1, -1 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 1, -1 ], [ 1, -1, 0, 0, 1, -1 ], [ "Rest" ], [ "Rest" ] ], 2.875 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 1, -1 ], [ 1, -1, 0, 0, 1, -1 ], [ "Rest" ], [ 2, -1, 0, 0, 1, -1 ] ], 3.75 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ 0, 0, 0, 0, 1, -1 ], [ 1, -1, 0, 0, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 2, -1, 0, 0, 1, -1 ] ], 2.875 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 1, -1 ], [ 0, 0, 1, 0, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 2, -1, 0, 0, 1, -1 ] ], 1.75 ], | ||||||
|  |     [ [ [ 0, 0, 0, 0, 1, -1 ], [ 0, 0, 1, 0, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 1, 1, 0, 0, 1, -1 ] ], 1.875 ], | ||||||
|  |     [ [ [ -1, 0, 0, 1, 1, -1 ], [ 0, 0, 1, 0, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 1, 1, 0, 0, 1, -1 ] ], 1.75 ], | ||||||
|  |     [ [ [ -1, 0, 0, 1, 1, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 1, 1, 0, 0, 1, -1 ] ], 2.75 ], | ||||||
|  |     [ [ [ -1, 0, 0, 1, 1, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ "Rest" ] ], 0.375 ], | ||||||
|  |     [ [ [ -1, 0, 0, 1, 1, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ "Rest" ], [ "Rest" ] ], 0.625 ], | ||||||
|  |     [ [ [ "Rest" ], [ 1, 0, 0, -1, 1, -1 ], [ "Rest" ], [ "Rest" ] ], 0.5 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 4 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 0, 0, 0, 1, -1 ], [ 1, -1, 0, 0, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 2, -1, 0, 0, 1, -1 ] ], | ||||||
|  |   [ [ 0, 0, 0, 0, 1, -1 ], [ 0, 0, 1, 0, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 2, -1, 0, 0, 1, -1 ] ], | ||||||
|  |   [ [ 0, 0, 0, 0, 1, -1 ], [ 0, 0, 1, 0, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 1, 1, 0, 0, 1, -1 ] ], | ||||||
|  |   [ [ -1, 0, 0, 1, 1, -1 ], [ 0, 0, 1, 0, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 1, 1, 0, 0, 1, -1 ] ], | ||||||
|  |   [ [ -1, 0, 0, 1, 1, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 1, 1, 0, 0, 1, -1 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "6f1305ed", | ||||||
|  | "ref_uid": "tmp", | ||||||
|  | "order_seed": 414624, | ||||||
|  | "dur_seed": 257250, | ||||||
|  | "motifs_seed": 938764, | ||||||
|  | "entrances_probs_vals": [ 0, 1.11, 3.2936507936508, 0.85, 2.1153846153846, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0, 1.11, 3.2936507936508, 0.85, 2.1153846153846, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0, 1.83, 4.8809523809524, 0.24725274725275, 1.15, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ -1100, 460.68111455108 ], [ -507, 1084.8297213622 ], [ 884.21052631579, 2237 ], [ 1040.2476780186, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 0, 1 ], [ 3 ], [ 2 ] ], | ||||||
|  |   [ [ 2 ], [ 1, 3, 0, 1 ], [  ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.73, 0.23, 0 ], | ||||||
|  | "order_size": [ 2, 2 ], | ||||||
|  | "passages_size": [ 0, 2 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,48 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 6, -5, -4, 0, -1, -2 ], [ "Rest" ] ], 0.875 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 6, -5, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 3 ], | ||||||
|  |     [ [ [ 8, -6, -4, 0, -1, -2 ], [ "Rest" ], [ 6, -5, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 1.25 ], | ||||||
|  |     [ [ [ 8, -6, -4, 0, -1, -2 ], [ 6, -5, -4, 0, -1, -3 ], [ 6, -5, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 2 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ 8, -6, -4, 0, -1, -2 ], [ "Rest" ], [ 6, -5, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 0 ], | ||||||
|  |     [ [ [ 8, -6, -4, 0, -1, -2 ], [ "Rest" ], [ 7, -7, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], 2.375 ], | ||||||
|  |     [ [ [ 8, -6, -4, 0, -1, -2 ], [ "Rest" ], [ 7, -7, -4, 0, -1, -2 ], [ "Rest" ] ], 0.875 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 7, -7, -4, 0, -1, -2 ], [ "Rest" ] ], 0 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.625 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ 7, -5, -3, 0, -1, -2 ], [ 5, -5, -2, 0, -2, -2 ], [ 5, -5, -2, 0, 0, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], | ||||||
|  |   [ [ 7, -5, -3, 0, -1, -2 ], [ 5, -5, -2, 0, -2, -2 ], [ 6, -5, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], | ||||||
|  |   [ [ 8, -6, -4, 0, -1, -2 ], [ 5, -5, -2, 0, -2, -2 ], [ 6, -5, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], | ||||||
|  |   [ [ 8, -6, -4, 0, -1, -2 ], [ 6, -5, -4, 0, -1, -3 ], [ 6, -5, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ], | ||||||
|  |   [ [ 8, -6, -4, 0, -1, -2 ], [ 6, -5, -4, 0, -1, -3 ], [ 7, -7, -4, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "703e109b", | ||||||
|  | "ref_uid": "tmp", | ||||||
|  | "order_seed": 550421, | ||||||
|  | "dur_seed": 315472, | ||||||
|  | "motifs_seed": 675194, | ||||||
|  | "entrances_probs_vals": [ 0.52, 0.56, 2.4206349206349, 0.25, 1.24, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0.52, 0.56, 2.4206349206349, 0.25, 1.24, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0.52, 0.56, 2.4206349206349, 0.25, 1.24, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ 1211.1455108359, 2400 ], [ -1650, 450 ], [ -405, 1137 ], [ 951.08359133127, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 2, 3 ], [ 0, 1 ], [  ] ], | ||||||
|  |   [ [ 3, 0 ], [ 2 ], [ 1 ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.73, 0.49, 0 ], | ||||||
|  | "order_size": [ 1, 3 ], | ||||||
|  | "passages_size": [ 0, 0 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
| @ -0,0 +1,907 @@ | |||||||
|  | ( | ||||||
|  | // helper funcs | ||||||
|  | var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; | ||||||
|  | 
 | ||||||
|  | // score funcs | ||||||
|  | var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; | ||||||
|  | 
 | ||||||
|  | // subroutines | ||||||
|  | var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; | ||||||
|  | 
 | ||||||
|  | // primary routines | ||||||
|  | var genMotif, genSecondarySeq; | ||||||
|  | 
 | ||||||
|  | // audition funcs | ||||||
|  | var genPatterns, genMidiPatterns; | ||||||
|  | 
 | ||||||
|  | // resource management funcs | ||||||
|  | var seedFunc, genUID, writeResources, stringifyToDepth, setSeeds, sanityCheck, | ||||||
|  | msgInterpret, loadLedgerFile, loadLedgerJSON, loadModelFile, loadModelJSON, | ||||||
|  | setGlobalVars, globalVarsToDict, saveLedger; | ||||||
|  | 
 | ||||||
|  | // model vars | ||||||
|  | //(model and global vars mostly set by OSC funcs | ||||||
|  | var seq, lastXChanges, | ||||||
|  | curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | motifEdited, orderEdited; | ||||||
|  | 
 | ||||||
|  | // model aux vars | ||||||
|  | var entrancesDurFunc, passagesDurFunc, exitsDurFunc; | ||||||
|  | 
 | ||||||
|  | // other global vars | ||||||
|  | var popSize, exPath, dir, primes, dims, tuples, | ||||||
|  | group, player, ledgerPath, ledger, currentlyPlayingUID, | ||||||
|  | nameSpaces; | ||||||
|  | 
 | ||||||
|  | // install JSON quark | ||||||
|  | if(Quarks.isInstalled("JSONlib").not, { | ||||||
|  | 	Quarks.install("https://github.com/musikinformatik/JSONlib.git"); | ||||||
|  | 	thisProcess.recompile; | ||||||
|  | 	//HelpBrowser.openHelpFor("Classes/JSONlib"); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------helper funcs | ||||||
|  | 
 | ||||||
|  | hsArrayToCents = { | ||||||
|  | 	arg hsArray; | ||||||
|  | 	hsArray.collect({arg dist, p; dist * 1200 * log2(primes[p][0]/primes[p][1])}).sum | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | pDist = { | ||||||
|  | 	arg array1, array2, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = hsArrayToCents.value(array1) - hsArrayToCents.value(array2); | ||||||
|  | 	if(signed, {pDistance}, {abs(pDistance)}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hdSum = { | ||||||
|  | 	arg hsArrays; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays.size; | ||||||
|  | 	distances = (size - 1).collect({arg i; | ||||||
|  | 		((i + 1)..(size - 1)).collect({arg j; | ||||||
|  | 			abs(hsArrays[i] - hsArrays[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsChordalDistance = { | ||||||
|  | 	arg hsArrays1, hsArrays2; | ||||||
|  | 	var size, distances, mean; | ||||||
|  | 	size = hsArrays1.size; | ||||||
|  | 	distances = hsArrays1.size.collect({arg i; | ||||||
|  | 		hsArrays2.size.collect({arg j; | ||||||
|  | 			abs(hsArrays1[i] - hsArrays2[j]).collect({arg dist, p; dist * log2(primes[p].product)}).sum | ||||||
|  | 		}); | ||||||
|  | 	}).flat; | ||||||
|  | 	mean = distances.sum / distances.size; | ||||||
|  | 	distances.sum | ||||||
|  | 	//mean + ((1 / sqrt((pow(distances - mean, 2)).sum / distances.size)) * mean) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | hsArrayToFreq = { | ||||||
|  | 	arg array; | ||||||
|  | 	array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------score funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | isInRange = { | ||||||
|  | 	arg hsArray, min, max; | ||||||
|  | 	var cents; | ||||||
|  | 	cents = hsArrayToCents.value(hsArray); | ||||||
|  | 	(cents >= min) && (cents <= max) | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | spacingScore = { | ||||||
|  | 	arg hsArrays, min; | ||||||
|  | 	var centsArray; | ||||||
|  | 	centsArray = hsArrays.collect({arg hsArray; hsArrayToCents.value(hsArray)}).sort({arg a, b; a < b}); | ||||||
|  | 	centsArray.differentiate.drop(1).collect({arg pDistance; if(pDistance >= min, {1}, {0.01})}).sum; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | rangeScore = { | ||||||
|  | 	arg hsArray1, hsArray2, min, max, low, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	if((pDistance >= min) && (pDistance <= max), {1}, {low}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | intervalScore = { | ||||||
|  | 	arg hsArray1, hsArray2, mean, sd, signed = false; | ||||||
|  | 	var pDistance; | ||||||
|  | 	pDistance = pDist.value(hsArray1, hsArray2, signed); | ||||||
|  | 	pDistance.gaussCurve(1, mean, sd) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | inclusionScore = { | ||||||
|  | 	arg array, test, min = 0.01; | ||||||
|  | 	if(array.collect({arg v; v.hash}).includes(test.hash), {min}, {1}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------subroutines | ||||||
|  | 
 | ||||||
|  | genTuples = { | ||||||
|  | 	var tuples; | ||||||
|  | 	tuples = dims.collect({[-1, 0, 1]}).allTuples.select({arg tuple; (abs(tuple.drop(1)).sum <= 1) && (tuple[0] == 0)}); | ||||||
|  | 	tuples = tuples ++ tuples.collect({arg tuple; [-3, -2, -1, 1, 2, 3].collect({arg octTrans; tuple.deepCopy.put(0, octTrans)})}).flatten; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | initVoices = { | ||||||
|  | 	var init, voicesInit; | ||||||
|  | 	voicesInit = popSize.collect({dims.collect({0})}); | ||||||
|  | 	/* | ||||||
|  | 	voicesInit = [dims.collect({0})]; | ||||||
|  | 	(popSize - 1).do({ | ||||||
|  | 		arg rep, new; | ||||||
|  | 		rep = dims.rand; | ||||||
|  | 		new = voicesInit.last.deepCopy; | ||||||
|  | 		new[rep] = new[rep] + [-1, 1].choose(); | ||||||
|  | 		voicesInit = voicesInit.add(new); | ||||||
|  | 	}); | ||||||
|  | 	*/ | ||||||
|  | 	voicesInit.deepCopy; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; | ||||||
|  | 	var env, pTable, durFunc; | ||||||
|  | 	env = Env.pairs([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).asSignal(256).asList.asArray; | ||||||
|  | 	pTable = env.asRandomTable; | ||||||
|  | 	[chordProb, minPad, maxPad, minDur, maxDur, envData].postln; | ||||||
|  | 	durFunc = {arg allowChord, pad = false; | ||||||
|  | 		var res; | ||||||
|  | 		res = if(allowChord.not, { | ||||||
|  | 			pTable.tableRand * (maxDur - minDur) + minDur | ||||||
|  | 		}, { | ||||||
|  | 			if(1.0.rand < chordProb, {0}, {pTable.tableRand * (maxDur - minDur) + minDur}); | ||||||
|  | 		}).round(0.125); | ||||||
|  | 		if(pad, {res = res + rrand(minPad.asFloat, maxPad.asFloat).round(0.125)}); | ||||||
|  | 		if(res.asInteger == res, {res = res.asInteger}); | ||||||
|  | 		res | ||||||
|  | 	}; | ||||||
|  | 	seedFunc.value(durFunc, seed); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; | ||||||
|  | 	((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ | ||||||
|  | 		var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; | ||||||
|  | 		noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); | ||||||
|  | 		noProgIns = (popSize - noSusIns).rand + 1; | ||||||
|  | 		noSilentIns = popSize - noSusIns - noProgIns; | ||||||
|  | 
 | ||||||
|  | 		# prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); | ||||||
|  | 
 | ||||||
|  | 		prog  = (prog.scramble ++ ((maxProgLength - minProgLength).rand + minProgLength).collect({prog.choose}).scramble); | ||||||
|  | 		if(silent == nil, {silent = []}); | ||||||
|  | 		[sus.scramble, prog, silent.scramble] | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | updateVoices = {arg ins, sus; | ||||||
|  | 	var voices, candidates, nWeights, nProbs, sel; | ||||||
|  | 
 | ||||||
|  | 	voices = lastXChanges.deepCopy.last; | ||||||
|  | 
 | ||||||
|  | 	candidates = sus.collect({arg v; tuples.collect({arg t; voices[v] + t})}).flatten; | ||||||
|  | 	candidates = difference(candidates.asSet, voices.asSet).asList; | ||||||
|  | 	nProbs = candidates.collect({arg candidate; | ||||||
|  | 		var stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; | ||||||
|  | 
 | ||||||
|  | 		//stepScore = intervalScore.value(voices[ins], candidate, 30, 400, 0.1); | ||||||
|  | 		stepScore = intervalScore.value(voices[ins], candidate, 100, 100); | ||||||
|  | 		recentlySoundedScore = inclusionScore.value(lastXChanges.flop[ins], candidate, 0); | ||||||
|  | 		isInRangeScore = rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0], ranges[ins][1], 0, true); | ||||||
|  | 		regScore = spacingScore.value(voices.deepCopy.put(ins, candidate), 300); | ||||||
|  | 		hdScore = 1/pow(hdSum.value(voices.deepCopy.put(ins, candidate)), 2); | ||||||
|  | 		//maybe what you want here is a vector to another root and then favoring movement towards it. | ||||||
|  | 		//distScore = pow(hsChordalDistance.value(voices, voices.put(ins, candidate)), 2); | ||||||
|  | 
 | ||||||
|  | 		[stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore] | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	nWeights = passagesWeights; | ||||||
|  | 
 | ||||||
|  | 	//this handles nWeights of 0; mainly for testing | ||||||
|  | 	nProbs = nProbs.flop.select({arg scores, s; nWeights[s] != 0}).flop; | ||||||
|  | 	nWeights = nWeights.select({arg weight; weight != 0}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; | ||||||
|  | 		if(scores.sum == 0, {scores}, {scores.normalizeSum * nWeights[s]}) | ||||||
|  | 	}); | ||||||
|  | 	nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; | ||||||
|  | 
 | ||||||
|  | 	sel = candidates.wchoose(nProbs); | ||||||
|  | 
 | ||||||
|  | 	voices[ins] = sel; | ||||||
|  | 	lastXChanges = lastXChanges.add(voices).keep(-5); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLast = false, isLastOrder = false; | ||||||
|  | 	var sus, prog, silent, flatOrder, res, isInChord, allowChord, pad, lastXChangesHold, voices, adder; | ||||||
|  | 	# sus, prog, silent = order; | ||||||
|  | 	flatOrder = silent ++ sus ++ prog; | ||||||
|  | 	lastXChangesHold = lastXChanges.deepCopy; | ||||||
|  | 	voices = lastState.deepCopy; | ||||||
|  | 	isInChord = popSize.collect({false}); | ||||||
|  | 	allowChord = false; | ||||||
|  | 	pad = false; | ||||||
|  | 	res = []; | ||||||
|  | 	"------generating motif".postln; | ||||||
|  | 	//need to figure out here if voices move between motifs | ||||||
|  | 	flatOrder.do({arg ins, i; | ||||||
|  | 
 | ||||||
|  | 		if(prog.includes(ins) && repeatLast.not, {updateVoices.value(ins, sus)}); | ||||||
|  | 		adder = if(silent.includes(ins), {["Rest"]}, {lastXChanges.last.deepCopy[ins]}); | ||||||
|  | 
 | ||||||
|  | 		if(voices[ins] != adder, { | ||||||
|  | 			var dur; | ||||||
|  | 
 | ||||||
|  | 			if((sus ++ silent).includes(ins), { | ||||||
|  | 				allowChord = (ins != sus.last); | ||||||
|  | 				pad = (ins == sus.last); | ||||||
|  | 			}, { | ||||||
|  | 				if(i < (flatOrder.size - 1), { | ||||||
|  | 					allowChord = (isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not; | ||||||
|  | 					pad = false; | ||||||
|  | 				}, { | ||||||
|  | 					allowChord = false; | ||||||
|  | 					pad = true | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if((orderIndex == 0) && sus.includes(ins), { | ||||||
|  | 				dur = entrancesDurFunc.value(allowChord, pad); | ||||||
|  | 			}, { | ||||||
|  | 				dur = passagesDurFunc.value(allowChord, pad); | ||||||
|  | 			}); | ||||||
|  | 			if(dur == 0, {isInChord[ins] = true}, {isInChord = popSize.collect({false})}); | ||||||
|  | 
 | ||||||
|  | 			voices[ins] = adder; | ||||||
|  | 			res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// pad ending | ||||||
|  | 	if(orderIndex == (orders.size - 1), { | ||||||
|  | 		(0..(popSize-1)).scramble.do({arg ins; | ||||||
|  | 			if(res.last.first[ins] != ["Rest"], { | ||||||
|  | 				var dur; | ||||||
|  | 				voices[ins] = ["Rest"]; | ||||||
|  | 				allowChord = (voices != popSize.collect({["Rest"]})); | ||||||
|  | 				pad = allowChord.not; | ||||||
|  | 				dur = exitsDurFunc.value(allowChord, pad); | ||||||
|  | 				res = res.add([voices.deepCopy.postln, dur]); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	//format and return | ||||||
|  | 	if(startFromLast, {lastXChanges = lastXChangesHold.deepCopy}); | ||||||
|  | 	res; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------primary routines | ||||||
|  | 
 | ||||||
|  | genMotif = { | ||||||
|  | 	var repeats, fSeq; | ||||||
|  | 
 | ||||||
|  | 	repeats = 1; | ||||||
|  | 	fSeq = []; | ||||||
|  | 
 | ||||||
|  | 	repeats.do({arg index; | ||||||
|  | 		var motif; | ||||||
|  | 
 | ||||||
|  | 		motif = []; | ||||||
|  | 
 | ||||||
|  | 		orders.do({arg order, o; | ||||||
|  | 			var lastState, subMotif; | ||||||
|  | 			lastState = if(o == 0, {popSize.collect({["Rest"]})}, {motif.last.last.first}); | ||||||
|  | 			subMotif = genSubMotif.value(order, o, lastState, isLastOrder: o == (orders.size - 1)); | ||||||
|  | 			motif = motif.add(subMotif); | ||||||
|  | 
 | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		sanityCheck.value(motif, index); | ||||||
|  | 
 | ||||||
|  | 		fSeq = fSeq.add(motif); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | genSecondarySeq = {arg seq; | ||||||
|  | 	var curdles, fSeq; | ||||||
|  | 	curdles = []; | ||||||
|  | 	while({curdles.sum < seq.size}, {curdles = curdles ++ [3.rand + 1]}); | ||||||
|  | 
 | ||||||
|  | 	fSeq = seq.clumps(curdles).collect({arg clump, m; | ||||||
|  | 		var repeats, paddedSeq; | ||||||
|  | 
 | ||||||
|  | 		//add rest | ||||||
|  | 		paddedSeq = clump.add([[[popSize.collect({["Rest"]}), 0.5.rand]]]); | ||||||
|  | 
 | ||||||
|  | 		//implement repeats | ||||||
|  | 		repeats = [0.rand + 1, 1].wchoose([1, 0].normalizeSum); | ||||||
|  | 		repeats.collect({paddedSeq}); | ||||||
|  | 	}); | ||||||
|  | 	fSeq | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------audition funcs | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~addr.sendMsg(~indexPath, ~indexMsg); | ||||||
|  | 		~addr.sendMsg(~seqPath, stringifyToDepth.value(~seqMsg, 3)); | ||||||
|  | 		//~addr.sendMsg("/STATE/OPEN", (dir.replace("supercollider", "resources") +/+ ~idMsg +/+ ~idMsg ++ "_gui_state" ++ ".state").standardizePath.postln); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | Event.addEventType(\osc, { | ||||||
|  | 	if (~addr.postln.notNil) { | ||||||
|  | 		~msg.postln; | ||||||
|  | 		~addr.sendMsg(~path, *~msg); | ||||||
|  | 	}; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | genPatterns = {arg inSeq, addr, oneShot = false; | ||||||
|  | 	var voices, durs, pbinds, res, indices, sectionDurs, msg, ids, seq; | ||||||
|  | 	seq = inSeq.collect({arg mSeq; mSeq[0]}); | ||||||
|  | 	# voices, durs =  seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	pbinds = voices.flop.collect({arg voice, v; | ||||||
|  | 		var clumps, hdScores, freqs, fDurs, attacks, rels, amps; | ||||||
|  | 		clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 		freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 		fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 		//attacks = 2.collect({rrand(1, 3)}) ++ freqs.drop(2).collect({rrand(0.3, 0.5)}); | ||||||
|  | 		attacks = fDurs.collect({arg dur; dur * rrand(0.2, 0.4)}); | ||||||
|  | 		//rels = freqs.drop(2).collect({rrand(0.3, 0.5)}) ++ 2.collect({rrand(1, 3)}); | ||||||
|  | 		rels = (clumps.size - 1).collect({arg c; | ||||||
|  | 			if(clumps[c + 1][0] == ["Rest"], {rrand(1, 3)}, {rrand(0.3, 0.5)}); | ||||||
|  | 		}); | ||||||
|  | 		amps = freqs.collect({rrand(0.6, 0.99)}); | ||||||
|  | 
 | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \string_model, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\attack, Pseq(attacks, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\release, Pseq(rels, 1), | ||||||
|  | 				//\amp, Pseq(amps, 1), | ||||||
|  | 				\amp, Pbrown(0.5, 1, 0.5), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			), | ||||||
|  | 			Pbind( | ||||||
|  | 				\instrument, \sine, | ||||||
|  | 				\group, group, | ||||||
|  | 				\freq, Pseq(freqs, 1), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\sustain, Pseq(fDurs, 1), | ||||||
|  | 				\busIndex, v | ||||||
|  | 			) | ||||||
|  | 		] | ||||||
|  | 	}).flatten; | ||||||
|  | 	if(oneShot.not, { | ||||||
|  | 		msg = inSeq.collect({arg mSeq, m; mSeq[1..]}); | ||||||
|  | 		//ids = inSeq.collect({arg mSeq, m; mSeq[2]}); | ||||||
|  | 		sectionDurs = seq.collect({arg mSeq; mSeq.flatten2(mSeq.maxDepth - 5).flop[1].sum}); | ||||||
|  | 		pbinds = pbinds ++ | ||||||
|  | 		[ | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \osc, | ||||||
|  | 				\addr, addr, | ||||||
|  | 				\path, "/playing", | ||||||
|  | 				\msg, Pseq(msg, 1), | ||||||
|  | 				\dur, Pseq(sectionDurs, 1) | ||||||
|  | 			); | ||||||
|  | 		] | ||||||
|  | 	}); | ||||||
|  | 	res = Ppar(pbinds); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | genMidiPatterns = {arg seq; | ||||||
|  | 	var voices, durs, patterns, res, mOut, pbRange; | ||||||
|  | 	pbRange = 1; //semitones - change this as needed for your situation | ||||||
|  | 	mOut =  MIDIOut.newByName("TiMidity", "TiMidity port 0").latency_(Server.default.latency); | ||||||
|  | 	# voices, durs = seq.flatten2(seq.maxDepth - 5).flop; | ||||||
|  | 	res = Ppar( | ||||||
|  | 		voices.flop.collect({arg voice, v; | ||||||
|  | 			var clumps, hdScores, freqs, fDurs; | ||||||
|  | 
 | ||||||
|  | 			mOut.program(v, 70); | ||||||
|  | 
 | ||||||
|  | 			clumps = voice.separate({arg a, b; a != b }); | ||||||
|  | 			freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))}, {Rest(0)})}); | ||||||
|  | 			fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); | ||||||
|  | 
 | ||||||
|  | 			Pbind( | ||||||
|  | 				\type, \midi, | ||||||
|  | 				\chan, v, | ||||||
|  | 				\noteval, Pseq(freqs.cpsmidi - 24, 1), | ||||||
|  | 				\note, Pfunc({ | event | event[\noteval].floor }), | ||||||
|  | 				\dur, Pseq(fDurs, 1), | ||||||
|  | 				\midiout, mOut, | ||||||
|  | 				\amp, 1, | ||||||
|  | 				\bend, Pfunc({ | ||||||
|  | 					| event | | ||||||
|  | 					if (event[\note].isRest.not) { | ||||||
|  | 						var pitchbendvalue = event[\noteval].frac.linlin(0, pbRange, 8192, 8192*2).asInteger; | ||||||
|  | 						m.bend(v, pitchbendvalue); | ||||||
|  | 					}; | ||||||
|  | 					0; // return something other than nil to avoid stopping the pattern | ||||||
|  | 				}), | ||||||
|  | 			); | ||||||
|  | 		}); | ||||||
|  | 	); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------resource management funcs | ||||||
|  | 
 | ||||||
|  | genUID = {Date.seed.asHexString.toLower}; | ||||||
|  | 
 | ||||||
|  | seedFunc = {arg func, seed; | ||||||
|  | 	var funcArgs, next; | ||||||
|  | 	next = Routine({loop{func.valueArray(funcArgs).yield }}); | ||||||
|  | 	next.randSeed_(seed); | ||||||
|  | 	{arg ...args; funcArgs = args; next.value} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | stringifyToDepth = {arg data, maxDepth = 1; | ||||||
|  | 	var prettyString = "", rCount = 0, writeArray, indent; | ||||||
|  | 
 | ||||||
|  | 	if(maxDepth == 0, { | ||||||
|  | 		data.asCompileString | ||||||
|  | 	}, { | ||||||
|  | 		indent = {arg size; size.collect({" "}).join("")}; | ||||||
|  | 		writeArray = {arg array; | ||||||
|  | 			prettyString = prettyString ++ indent.value(rCount) ++ "[\n"; | ||||||
|  | 			rCount = rCount + 1; | ||||||
|  | 			if(rCount < maxDepth, { | ||||||
|  | 				array.do({arg subArray; writeArray.value(subArray)}); | ||||||
|  | 			}, { | ||||||
|  | 				prettyString = prettyString ++ array.collect({arg subArray; | ||||||
|  | 					indent.value(rCount + 1) ++ subArray.asCompileString | ||||||
|  | 				}).join(",\n"); | ||||||
|  | 			}); | ||||||
|  | 			rCount = rCount - 1; | ||||||
|  | 			prettyString = prettyString ++ "\n" ++ indent.value(rCount) ++ "],\n"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		writeArray.value(data); | ||||||
|  | 		prettyString.replace(",\n\n", "\n").drop(-2); | ||||||
|  | 	}) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | sanityCheck = {arg motif, index; | ||||||
|  | 	//print functions = very helpful | ||||||
|  | 	("----------" + index + "------------").postln; | ||||||
|  | 
 | ||||||
|  | 	motif.flatten.do({arg val, v; | ||||||
|  | 		if(v > 0, { | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) > 1, {"problem 1".postln}); | ||||||
|  | 			if(motif.flatten[v-1][0].hammingDistance(val[0]) == 0, {"problem 2".postln}); | ||||||
|  | 		}); | ||||||
|  | 		val.postln | ||||||
|  | 	}); | ||||||
|  | 	"***********".postln; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; | ||||||
|  | 	var res; | ||||||
|  | 
 | ||||||
|  | 	res = in; | ||||||
|  | 	if(res.isNil.not, { | ||||||
|  | 		if((res.isArray && res.isString.not), { | ||||||
|  | 			res = res.asCompileString; | ||||||
|  | 			res = res.replace(" ", "").replace("\n", "").replace("\t", ""); | ||||||
|  | 			if(escapeSingleQuotes, {res = res.replace("\'", "")}); | ||||||
|  | 			if(escapeDoubleQuotes, {res = res.replace("\"", "")}); | ||||||
|  | 			res = res.replace("Rest", "\"Rest\""); | ||||||
|  | 			res = res.interpret; | ||||||
|  | 		}, { | ||||||
|  | 			//res.postln; | ||||||
|  | 			if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | 	res | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | writeResources = {arg path, dict; | ||||||
|  | 	var file, modelItems, resString; | ||||||
|  | 	file = File(path,"w"); | ||||||
|  | 
 | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	resString = nameSpaces.collect({arg nameSpace; | ||||||
|  | 		var depth = 0, insert = " "; | ||||||
|  | 		if(nameSpace == "music_data", {depth = 3; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "last_changes", {depth = 1; insert = "\n"}); | ||||||
|  | 		if(nameSpace == "order", {depth = 1; insert = "\n"}); | ||||||
|  | 		if((nameSpace == "ref_uid") && (dict[nameSpace] == nil), {dict[nameSpace] = "nil"}); | ||||||
|  | 		"\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(dict[nameSpace], depth) | ||||||
|  | 	}).join(",\n"); | ||||||
|  | 
 | ||||||
|  | 	resString = "{\n" ++ resString ++ "\n}"; | ||||||
|  | 
 | ||||||
|  | 	file.write(resString); | ||||||
|  | 	file.close; | ||||||
|  | 	resString | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadModelFile = {arg path; loadModelJSON.value(File(path, "r").readAllString.parseJSON)}; | ||||||
|  | 
 | ||||||
|  | loadModelJSON = {arg jsonObject; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS; nS->msgInterpret.value(jsonObject[nS])})); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | setGlobalVars = {arg dict, skipLastXChanges = false; | ||||||
|  | 	var tmpLastXChanges; | ||||||
|  | 	tmpLastXChanges = lastXChanges.deepCopy; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	# seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 	entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 	ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 	motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); | ||||||
|  | 	if(skipLastXChanges, {lastXChanges = tmpLastXChanges}); | ||||||
|  | 	dict | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | globalVarsToDict = { | ||||||
|  | 	var modelItems, dict; | ||||||
|  | 	// order really matters!!!! | ||||||
|  | 	modelItems = [ | ||||||
|  | 		seq, lastXChanges, | ||||||
|  | 		curUID, refUID, orderSeed, durSeed, motifSeed, | ||||||
|  | 		entrancesProbVals, passagesProbVals, exitsProbVals, | ||||||
|  | 		ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, | ||||||
|  | 		motifEdited, orderEdited | ||||||
|  | 	]; | ||||||
|  | 	dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerFile = {arg path; | ||||||
|  | 	ledgerPath = path; | ||||||
|  | 	loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; | ||||||
|  | 
 | ||||||
|  | saveLedger = {arg ledger, path; | ||||||
|  | 	var file; | ||||||
|  | 	file = File(path, "w"); | ||||||
|  | 	file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); | ||||||
|  | 	file.close; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //------global vars | ||||||
|  | 
 | ||||||
|  | primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; | ||||||
|  | //ranges = [[-2400, 0], [-1200, 1200], [0, 2400], [0, 2400]]; | ||||||
|  | exPath = thisProcess.nowExecutingPath; | ||||||
|  | dir = exPath.dirname; | ||||||
|  | //popSize = 4; | ||||||
|  | dims = primes.size; | ||||||
|  | tuples = genTuples.value(); | ||||||
|  | //refUID = nil; | ||||||
|  | group = Group.new; | ||||||
|  | ~group = group; | ||||||
|  | loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); | ||||||
|  | //passagesWeights = [1, 1, 1, 1, 1]; | ||||||
|  | //susWeights = [1, 1, 1]; | ||||||
|  | // order really matters!!!! | ||||||
|  | nameSpaces = [ | ||||||
|  | 	"music_data", "last_changes", "cur_uid", "ref_uid", "order_seed", "dur_seed", "motifs_seed", | ||||||
|  | 	"entrances_probs_vals","passages_probs_vals", "exits_probs_vals", | ||||||
|  | 	"ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", | ||||||
|  | 	"motif_edited", "order_edited" | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //------OSC funcs | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_ledger, {arg msg, time, addr, port; | ||||||
|  | 	loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \load_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\load_model, {arg msg, time, addr, port; | ||||||
|  | 	var dict; | ||||||
|  | 	dict = loadModelFile.value(msg[1].asString); | ||||||
|  | 	setGlobalVars.value(dict); | ||||||
|  | }, \load_model); | ||||||
|  | 
 | ||||||
|  | OSCdef(\save_ledger, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	ledger = msgInterpret.value(msg[1].asString.parseJSON["ledger"], false).postln; | ||||||
|  | 	//loadLedgerJSON.value(msg[0]) | ||||||
|  | 	saveLedger.value(ledger, msg[2].asString); | ||||||
|  | 	//loadLedgerFile.value(msg[1].asString); | ||||||
|  | }, \save_ledger); | ||||||
|  | 
 | ||||||
|  | OSCdef(\generate, {arg msg, time, addr, port; | ||||||
|  | 	var path, dict, durSeeds, musPath, modelString; | ||||||
|  | 	msg.postln; | ||||||
|  | 
 | ||||||
|  | 	path = msg[1].asString; | ||||||
|  | 
 | ||||||
|  | 	dict = loadModelFile.value(path); | ||||||
|  | 	setGlobalVars.value(dict, true); | ||||||
|  | 
 | ||||||
|  | 	popSize = ranges.size; | ||||||
|  | 
 | ||||||
|  | 	//refUID.postln; | ||||||
|  | 
 | ||||||
|  | 	loadLedgerFile.value(ledgerPath); | ||||||
|  | 	if(ledger == nil, {ledger = ["tmp"]}); | ||||||
|  | 	if(ledger.last != "tmp", {ledger = ledger.add("tmp")}); | ||||||
|  | 
 | ||||||
|  | 	if(refUID == nil, {lastXChanges = [initVoices.value().deepCopy]}); | ||||||
|  | 	if((refUID != nil) && (refUID != "tmp"), { | ||||||
|  | 		var file; | ||||||
|  | 		file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); | ||||||
|  | 		lastXChanges = msgInterpret.value(file.readAllString.parseJSON["last_changes"]); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	refUID.postln; | ||||||
|  | 	lastXChanges.collect({arg item; item.postln}); | ||||||
|  | 
 | ||||||
|  | 	durSeeds = seedFunc.value({3.collect({rrand(100000, 999999)})}, durSeed).value.postln; | ||||||
|  | 	entrancesDurFunc = genDurFunc.valueArray(entrancesProbVals[..4] ++ [entrancesProbVals[5..]] ++ [durSeeds[0]]); | ||||||
|  | 	passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..4] ++ [passagesProbVals[5..]] ++ [durSeeds[1]]); | ||||||
|  | 	exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..4] ++ [exitsProbVals[5..]] ++ [durSeeds[2]]); | ||||||
|  | 
 | ||||||
|  | 	if(orders == nil, { | ||||||
|  | 		orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); | ||||||
|  | 		//addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); | ||||||
|  | 	}); | ||||||
|  | 	seq = seedFunc.value(genMotif, motifSeed).value; | ||||||
|  | 
 | ||||||
|  | 	lastXChanges.collect({arg item; item.postln}); | ||||||
|  | 
 | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	modelString = writeResources.value(path, dict); | ||||||
|  | 
 | ||||||
|  | 	//addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); | ||||||
|  | 	addr.sendMsg("/generated", path, modelString, ledgerPath); | ||||||
|  | }, \generate); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | OSCdef(\commit, {arg msg, time, addr, port; | ||||||
|  | 	var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; | ||||||
|  | 	//msg.postln; | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	test1 = msg[1].asString.parseJSON; | ||||||
|  | 	test2 = (dir +/+ ".." +/+ "resources/tmp/tmp_music" ++ ".json").standardizePath.parseJSONFile; | ||||||
|  | 	msgInterpret.value(test1["music"])[0][0][0][1].class.postln; | ||||||
|  | 	msgInterpret.value(test2["music_data"])[0][0][0][1].class.postln; | ||||||
|  | 	(test1["music"] == test2["music_data"]).postln; | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; | ||||||
|  | 	musicChanged = (musicData != seq).postln; | ||||||
|  | 
 | ||||||
|  | 	curUID = genUID.value; | ||||||
|  | 
 | ||||||
|  | 	File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); | ||||||
|  | 	File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); | ||||||
|  | 
 | ||||||
|  | 	modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 	dict = globalVarsToDict.value; | ||||||
|  | 	if(musicChanged, { | ||||||
|  | 		seq = musicData; | ||||||
|  | 		dict["music_data"] = seq; | ||||||
|  | 		dict["motif_edited"] = "true" | ||||||
|  | 	}); | ||||||
|  | 	dict["cur_uid"] = curUID; | ||||||
|  | 
 | ||||||
|  | 	writeResources.value(modelPath, dict); | ||||||
|  | 
 | ||||||
|  | 	File.delete(ledgerPath ++ "_bak"); | ||||||
|  | 	File.copy(ledgerPath, ledgerPath ++ "_bak"); | ||||||
|  | 	File.delete(ledgerPath); | ||||||
|  | 	ledger = ledger.drop(-1).add(curUID); | ||||||
|  | 
 | ||||||
|  | 	saveLedger.value(ledger, ledgerPath); | ||||||
|  | 
 | ||||||
|  | 	addr.sendMsg("/committed", curUID, ledgerPath); | ||||||
|  | 	//refUID = curUID; | ||||||
|  | 
 | ||||||
|  | }, \commit); | ||||||
|  | 
 | ||||||
|  | OSCdef(\transport, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	if(msg[1] == 0, { | ||||||
|  | 		group.set(\release, 2); | ||||||
|  | 		group.set(\gate, 0); | ||||||
|  | 		player.stop; | ||||||
|  | 	}, { | ||||||
|  | 		// the cued sequence can now be read from file, so this can be cleaned up | ||||||
|  | 		var cSize, patterns, pSeq, cuedSeek, indexStart, indexEnd, tmpLedger; | ||||||
|  | 		if(msg[1] == 1, { | ||||||
|  | 			pSeq = []; | ||||||
|  | 			cuedSeek = (seq != nil); | ||||||
|  | 			indexStart = msg[2].asInteger; | ||||||
|  | 			indexEnd = ledger.size - if(cuedSeek, {2}, {1}); | ||||||
|  | 			//ledger.postln; | ||||||
|  | 			if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { | ||||||
|  | 				ledger[indexStart..indexEnd].do({arg uid, index; | ||||||
|  | 					var path, file; | ||||||
|  | 					path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; | ||||||
|  | 					file = File(path, "r"); | ||||||
|  | 					pSeq = pSeq.add([msgInterpret.value(file.readAllString.postln.parseJSON["music_data"]), path, indexStart + index, uid]); | ||||||
|  | 					file.close; | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 			if(cuedSeek, { | ||||||
|  | 				var path, file; | ||||||
|  | 				path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; | ||||||
|  | 				file = File(path, "r"); | ||||||
|  | 				pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, ledger.size - 1, "tmp"]); | ||||||
|  | 				file.close; | ||||||
|  | 			}); | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr); | ||||||
|  | 		}, { | ||||||
|  | 			pSeq = [loadModelJSON.value(msg[2].asString.parseJSON)["music_data"].postln]; | ||||||
|  | 			patterns = genPatterns.value(pSeq, addr, true); | ||||||
|  | 		}); | ||||||
|  | 		player = Pfset(pattern: patterns, cleanupFunc: { | ||||||
|  | 			addr.sendMsg("/transport", 0); | ||||||
|  | 			addr.sendMsg("/one_shot", 0); | ||||||
|  | 		}); | ||||||
|  | 		player = player.play | ||||||
|  | 	}); | ||||||
|  | }, \transport); | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | //synthdefs | ||||||
|  | ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sineBusArray = 4.collect({Bus.audio(s, 1)}); | ||||||
|  | ~bassBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~hdustBusArray = 1.collect({Bus.audio(s, 1)}); | ||||||
|  | ~samplerBusArray = 2.collect({Bus.audio(s, 1)}); | ||||||
|  | ~sBuf = Buffer.alloc(s, 10, 2); | ||||||
|  | SynthDef(\string_model, {arg freq, gate = 1, sustain, amp, dur, attack, release = 1, busIndex = 0; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms; | ||||||
|  | 	noHarms = rrand(20, 40); | ||||||
|  | 	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip; | ||||||
|  | 	//sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~stringModelBusArray), sig1 * amp * EnvGen.kr(Env.adsr(attack, 0.3, 0.9, release, 0.9, -3), gate, doneAction: 2)); | ||||||
|  | 	//Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; | ||||||
|  | 	var sig; | ||||||
|  | 	sig = SinOsc.ar(freq); | ||||||
|  | 	Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.asr(0.3, 0.4, 0.3), gate, timeScale: dur, doneAction: 2)); | ||||||
|  | 	//Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.sine(dur), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; | ||||||
|  | 	var nameSpaces, sigs, hierarchicalDust; | ||||||
|  | 
 | ||||||
|  | 	hierarchicalDust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	sigs = [~stringModelBusArray, ~sineBusArray, ~bassBusArray, ~hdustBusArray, ~samplerBusArray].collect({arg busArray, i; | ||||||
|  | 		var nameSpace, sig; | ||||||
|  | 		nameSpace = ['string', 'sine', 'bass', 'hdust', 'sampler'][i]; | ||||||
|  | 		sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)}); | ||||||
|  | 		sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)}); | ||||||
|  | 		sig = Mix.ar(sig) * pow(NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.1), 2); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	sigs = Mix.ar(sigs / 4); | ||||||
|  | 	Out.ar(0, sigs) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\bass, { | ||||||
|  | 	var switches, drone; | ||||||
|  | 	switches = {|i| Dust.kr(0.1)} ! 9; | ||||||
|  | 	drone = {|i| var harm = pow(2, 2 - (i / 3).trunc), amp = (1 / pow(harm, 2)); | ||||||
|  | 		SinOsc.ar(60 * harm + TRand.kr(-3, 3, switches[i]), 0, amp)} ! 9; | ||||||
|  | 	Out.ar(~bassBusArray[0], Mix.new(drone) * 0.2); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | SynthDef(\sampler, { | ||||||
|  | 	Out.ar(~samplerBusArray, PlayBuf.ar(2, ~sBuf, BufRateScale.kr(~sBuf), doneAction: 2)) | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | // main routine | ||||||
|  | SynthDef(\hdust, { | ||||||
|  | 	arg gate = 0; | ||||||
|  | 	var hierarchical_dust, low_sine, high_sine, brown_noise, white_noise; | ||||||
|  | 	// this triggers the combinations of sources | ||||||
|  | 	// it is similar to the Supercollider UGen called dust but with a hierarchical structure | ||||||
|  | 	hierarchical_dust = ( | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(100)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(10)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(1)) * | ||||||
|  | 		TIRand.kr(0, 1, Impulse.kr(0.1)) | ||||||
|  | 	); | ||||||
|  | 	// adjust the multiplier at the end of each line for adjusting levels | ||||||
|  | 	// note with each trigger, each source has a 1 in 3 chance of sounding | ||||||
|  | 	low_sine = SinOsc.ar(76.midicps / 16) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.1; | ||||||
|  | 	high_sine = SinOsc.ar(76.midicps * 8) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.01; | ||||||
|  | 	brown_noise = BrownNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.025; | ||||||
|  | 	white_noise = WhiteNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.02; | ||||||
|  | 	Out.ar(~hdustBusArray[0], | ||||||
|  | 		((low_sine + high_sine + brown_noise + white_noise) ) | ||||||
|  | 	); | ||||||
|  | }).add; | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | ( | ||||||
|  | var bass, hdust, sampler, mixer; | ||||||
|  | bass = Synth.tail(~group, \bass); | ||||||
|  | hdust = Synth.tail(~group, \hdust); | ||||||
|  | sampler = Synth.head(~group, \sampler); | ||||||
|  | mixer = Synth.tail(~group, \mixer); | ||||||
|  | OSCdef(\mixer, {arg msg, time, addr, port; | ||||||
|  | 	mixer.set((msg[1] ++ '_' ++ msg[2] ++ '_' ++ msg[3]), msg[4]) | ||||||
|  | }, \mixer); | ||||||
|  | 
 | ||||||
|  | OSCdef(\sampler, {arg msg, time, addr, port; | ||||||
|  | 	msg.postln; | ||||||
|  | 	sampler.free; | ||||||
|  | 	~sBuf.free; | ||||||
|  | 	~sBuf = Buffer.read(s, msg[1].asString.postln, action: {sampler = Synth.head(~group, \sampler)}); | ||||||
|  | }, \sampler); | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | /* old something | ||||||
|  | ( | ||||||
|  | SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur; | ||||||
|  | 	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end; | ||||||
|  | 	noHarms = 30; | ||||||
|  | 	freq = WhiteNoise.ar * 3 + freq; | ||||||
|  | 	freqFinal = Duty.ar((1/freq), 0, freq); | ||||||
|  | 	trig = Changed.ar(freqFinal); | ||||||
|  | 	start = Demand.ar(trig, 0, Dwhite(-1, -0.75)); | ||||||
|  | 	end = Demand.ar(trig, 0, Dwhite(0.75, 1)); | ||||||
|  | 	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01); | ||||||
|  | 
 | ||||||
|  | 	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq), | ||||||
|  | 		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}), | ||||||
|  | 		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip; | ||||||
|  | 	sig1 = HPF.ar(sig1, 300); | ||||||
|  | 	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2)); | ||||||
|  | }).add; | ||||||
|  | ) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| @ -0,0 +1,83 @@ | |||||||
|  | { | ||||||
|  | "music_data": | ||||||
|  | [ | ||||||
|  |  [ | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 2, 0, 1, -2, 0 ], [ "Rest" ] ], 1.625 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 2, 0, 1, -2, 0 ], [ 0, 2, 0, 2, -2, -1 ] ], 1.625 ], | ||||||
|  |     [ [ [ -3, 2, 0, 2, -2, -2 ], [ "Rest" ], [ 0, 2, 0, 1, -2, 0 ], [ 0, 2, 0, 2, -2, -1 ] ], 2.75 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ -3, 2, 0, 2, -2, -2 ], [ "Rest" ], [ 0, 2, 0, 1, -2, 0 ], [ "Rest" ] ], 0.75 ], | ||||||
|  |     [ [ [ -3, 2, 0, 2, -2, -2 ], [ -2, 3, 0, 1, -2, -1 ], [ 0, 2, 0, 1, -2, 0 ], [ "Rest" ] ], 2.75 ], | ||||||
|  |     [ [ [ -3, 3, 0, 1, -3, -1 ], [ -2, 3, 0, 1, -2, -1 ], [ 0, 2, 0, 1, -2, 0 ], [ "Rest" ] ], 1.25 ], | ||||||
|  |     [ [ [ -3, 3, 0, 1, -3, -1 ], [ -2, 3, 0, 1, -2, -1 ], [ 1, 3, 0, 0, -2, -1 ], [ "Rest" ] ], 2.5 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ -3, 3, 0, 1, -3, -1 ], [ -2, 3, 0, 1, -2, -1 ], [ "Rest" ], [ "Rest" ] ], 0.75 ], | ||||||
|  |     [ [ [ -3, 3, 0, 1, -3, -1 ], [ -2, 3, 0, 1, -2, -1 ], [ "Rest" ], [ 0, 2, 0, 2, -2, -1 ] ], 3.25 ], | ||||||
|  |     [ [ [ -3, 3, 0, 1, -3, -1 ], [ -2, 2, -1, 2, -2, -1 ], [ "Rest" ], [ 0, 2, 0, 2, -2, -1 ] ], 0.75 ], | ||||||
|  |     [ [ [ -3, 1, 0, 2, -2, -1 ], [ -2, 2, -1, 2, -2, -1 ], [ "Rest" ], [ 0, 2, 0, 2, -2, -1 ] ], 1.625 ], | ||||||
|  |     [ [ [ -3, 1, 0, 2, -2, -1 ], [ -3, 3, 0, 2, -2, -1 ], [ "Rest" ], [ 0, 2, 0, 2, -2, -1 ] ], 1 ], | ||||||
|  |     [ [ [ -3, 1, 0, 2, -2, -1 ], [ -2, 1, 0, 2, -2, -1 ], [ "Rest" ], [ 0, 2, 0, 2, -2, -1 ] ], 1.25 ], | ||||||
|  |     [ [ [ -3, 2, 0, 1, -2, -1 ], [ -2, 1, 0, 2, -2, -1 ], [ "Rest" ], [ 0, 2, 0, 2, -2, -1 ] ], 0.875 ], | ||||||
|  |     [ [ [ -3, 2, 0, 2, -2, -2 ], [ -2, 1, 0, 2, -2, -1 ], [ "Rest" ], [ 0, 2, 0, 2, -2, -1 ] ], 1.625 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ -2, 1, 0, 2, -2, -1 ], [ "Rest" ], [ 0, 2, 0, 2, -2, -1 ] ], 0.75 ], | ||||||
|  |     [ [ [ "Rest" ], [ -2, 1, 0, 2, -2, -1 ], [ 1, 3, 0, 0, -2, -1 ], [ 0, 2, 0, 2, -2, -1 ] ], 2.625 ], | ||||||
|  |     [ [ [ "Rest" ], [ -2, 4, 0, 0, -2, -1 ], [ 1, 3, 0, 0, -2, -1 ], [ 0, 2, 0, 2, -2, -1 ] ], 0.75 ], | ||||||
|  |     [ [ [ "Rest" ], [ -2, 4, 0, 0, -2, -1 ], [ 1, 3, 0, 0, -2, -1 ], [ 0, 3, 0, 1, -2, -1 ] ], 0.875 ], | ||||||
|  |     [ [ [ "Rest" ], [ -2, 4, 0, 0, -2, -1 ], [ 1, 3, 0, 0, -2, -1 ], [ 0, 3, 0, 0, -2, 0 ] ], 2.375 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 1, 3, 0, 0, -2, -1 ], [ 0, 3, 0, 0, -2, 0 ] ], 1.625 ], | ||||||
|  |     [ [ [ -3, 2, 0, 2, -2, -2 ], [ "Rest" ], [ 1, 3, 0, 0, -2, -1 ], [ 0, 3, 0, 0, -2, 0 ] ], 2.5 ], | ||||||
|  |     [ [ [ -3, 2, 0, 2, -2, -2 ], [ "Rest" ], [ 0, 3, 0, 2, -2, -2 ], [ 0, 3, 0, 0, -2, 0 ] ], 1.25 ], | ||||||
|  |     [ [ [ -3, 2, 0, 2, -2, -2 ], [ "Rest" ], [ 0, 3, 0, 2, -2, -2 ], [ 0, 2, 0, 2, -1, -2 ] ], 2.75 ] | ||||||
|  |   ], | ||||||
|  |   [ | ||||||
|  |     [ [ [ -3, 2, 0, 2, -2, -2 ], [ -2, 4, 0, 0, -2, -1 ], [ 0, 3, 0, 2, -2, -2 ], [ 0, 2, 0, 2, -1, -2 ] ], 1.75 ], | ||||||
|  |     [ [ [ -3, 2, 0, 2, -2, -2 ], [ -2, 4, 0, 0, -2, -1 ], [ 0, 4, 1, 0, -2, -1 ], [ 0, 2, 0, 2, -1, -2 ] ], 1.25 ], | ||||||
|  |     [ [ [ -3, 2, 0, 2, -2, -2 ], [ -2, 4, 0, 0, -2, -1 ], [ 0, 4, 1, 0, -2, -1 ], [ 1, 4, 0, 0, -2, -2 ] ], 1.625 ], | ||||||
|  |     [ [ [ -4, 4, 0, 1, -2, -1 ], [ -2, 4, 0, 0, -2, -1 ], [ 0, 4, 1, 0, -2, -1 ], [ 1, 4, 0, 0, -2, -2 ] ], 2.125 ], | ||||||
|  |     [ [ [ "Rest" ], [ -2, 4, 0, 0, -2, -1 ], [ 0, 4, 1, 0, -2, -1 ], [ 1, 4, 0, 0, -2, -2 ] ], 1.375 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ 0, 4, 1, 0, -2, -1 ], [ 1, 4, 0, 0, -2, -2 ] ], 1 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 1, 4, 0, 0, -2, -2 ] ], 0.875 ], | ||||||
|  |     [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3 ] | ||||||
|  |   ] | ||||||
|  |  ] | ||||||
|  | ], | ||||||
|  | "last_changes": | ||||||
|  | [ | ||||||
|  |   [ [ -3, 2, 0, 2, -2, -2 ], [ -2, 4, 0, 0, -2, -1 ], [ 0, 3, 0, 2, -2, -2 ], [ 0, 3, 0, 0, -2, 0 ] ], | ||||||
|  |   [ [ -3, 2, 0, 2, -2, -2 ], [ -2, 4, 0, 0, -2, -1 ], [ 0, 3, 0, 2, -2, -2 ], [ 0, 2, 0, 2, -1, -2 ] ], | ||||||
|  |   [ [ -3, 2, 0, 2, -2, -2 ], [ -2, 4, 0, 0, -2, -1 ], [ 0, 4, 1, 0, -2, -1 ], [ 0, 2, 0, 2, -1, -2 ] ], | ||||||
|  |   [ [ -3, 2, 0, 2, -2, -2 ], [ -2, 4, 0, 0, -2, -1 ], [ 0, 4, 1, 0, -2, -1 ], [ 1, 4, 0, 0, -2, -2 ] ], | ||||||
|  |   [ [ -4, 4, 0, 1, -2, -1 ], [ -2, 4, 0, 0, -2, -1 ], [ 0, 4, 1, 0, -2, -1 ], [ 1, 4, 0, 0, -2, -2 ] ] | ||||||
|  | ], | ||||||
|  | "cur_uid": "74faf83f", | ||||||
|  | "ref_uid": "tmp", | ||||||
|  | "order_seed": 329828, | ||||||
|  | "dur_seed": 441173, | ||||||
|  | "motifs_seed": 330575, | ||||||
|  | "entrances_probs_vals": [ 0, 0.48, 1.7460317460317, 0.58, 1.68, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "passages_probs_vals": [ 0, 0.48, 1.7460317460317, 0.58, 1.68, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "exits_probs_vals": [ 0, 0.48, 1.7460317460317, 0.58, 1.68, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], | ||||||
|  | "ranges": [ [ -3600, -1408.0495356037 ], [ -3600, -609.2879256966 ], [ 858.20433436532, 2066 ], [ 951.08359133127, 2053 ] ], | ||||||
|  | "passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], | ||||||
|  | "order": | ||||||
|  | [ | ||||||
|  |   [ [ 2, 3 ], [ 0 ], [ 1 ] ], | ||||||
|  |   [ [ 1 ], [ 0, 2 ], [ 3 ] ], | ||||||
|  |   [ [ 3 ], [ 1, 0, 1, 1, 0, 0 ], [ 2 ] ], | ||||||
|  |   [ [ 2 ], [ 1, 3, 3 ], [ 0 ] ], | ||||||
|  |   [ [ 0 ], [ 2, 3 ], [ 1 ] ], | ||||||
|  |   [ [ 1 ], [ 2, 3, 0 ], [  ] ] | ||||||
|  | ], | ||||||
|  | "sus_weights": [ 0.73, 0.49, 0 ], | ||||||
|  | "order_size": [ 1, 7 ], | ||||||
|  | "passages_size": [ 0, 5 ], | ||||||
|  | "motif_edited": "false", | ||||||
|  | "order_edited": "false" | ||||||
|  | } | ||||||
Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in New Issue